sketch of JointFeldmanProtocol

DKG
tzlil.gon 2016-02-05 13:30:16 +02:00
parent f8d31d16a3
commit 635165ef8e
7 changed files with 242 additions and 58 deletions

View File

@ -186,6 +186,18 @@ public class Polynomial implements Comparable<Polynomial> {
this.y = polynomial.image(x); this.y = polynomial.image(x);
} }
/**
* constructor
* @param x
* @param p
* @param polynomial y = polynomial.image(x) % q
*
*/
public Point(BigInteger x, Polynomial polynomial,BigInteger p) {
this.x = x;
this.y = polynomial.image(x);
}
/** /**
* copy constructor * copy constructor
* @param point * @param point

View File

@ -9,59 +9,53 @@ import java.util.Random;
* an implementation of Shamire's secret sharing scheme * an implementation of Shamire's secret sharing scheme
*/ */
public class SecretSharing { public class SecretSharing {
protected final int t; private final int t;
protected final int n; private final int n;
private final BigInteger q;
private final Polynomial polynomial;
protected final BigInteger p;
protected final Polynomial polynomial;
/** /**
* constructor * constructor
* @param p prime * @param q a large prime.
* @param t threshold. Any t+1 share holders can recover the secret, * @param t threshold. Any t+1 share holders can recover the secret,
* but any set of at most t share holders cannot * but any set of at most t share holders cannot
* @param n number of share holders * @param n number of share holders
* @param s secret, chosen from Zp * @param x secret, chosen from Zq
* @param random use for generate random polynomial * @param random use for generate random polynomial
*/ */
public SecretSharing(BigInteger p, int t, int n, BigInteger s, Random random) { public SecretSharing(int t, int n, BigInteger x, Random random,BigInteger q) {
this.p = p; this.q = q;
this.t = t; this.t = t;
this.n = n; this.n = n;
this.polynomial = generateRandomPolynomial(s,random); this.polynomial = generateRandomPolynomial(x,random);
} }
/** /**
* @param s * @param x
* @param random * @param random
* @return new FeldmanVerifiableSecretSharing.ShamirSecretSharing.PolynomialTests polynomial of degree t ,such that * @return new Polynomial polynomial of degree t ,such that
* 1. polynomial(0) = s * 1. polynomial(0) = x
* 2. polynomial coefficients randomly chosen from Zp (except of coefficients[0] = s) * 2. polynomial coefficients randomly chosen from Zq (except of coefficients[0] = x)
*/ */
private Polynomial generateRandomPolynomial(BigInteger s, Random random) { private Polynomial generateRandomPolynomial(BigInteger x, Random random) {
BigInteger[] coefficients = new BigInteger[t + 1]; BigInteger[] coefficients = new BigInteger[t + 1];
coefficients[0] = s; coefficients[0] = x.mod(q);
int bits = p.bitLength(); int bits = q.bitLength();
for (int i = 1 ; i <= t; i++ ){ for (int i = 1 ; i <= t; i++ ){
coefficients[i] = new BigInteger(bits,random).mod(p); coefficients[i] = new BigInteger(bits,random).mod(q);
} }
return new Polynomial(coefficients); return new Polynomial(coefficients);
} }
//ToDo make it safe : permission to call this func
/** /**
* @param i in range of [1,...n] * @param i in range of [1,...n]
* *
* @return polynomial.image(i) * @return polynomial.image(i)%q
*
* @throws Exception i out of range
*/ */
public Polynomial.Point getShare(int i) throws Exception { protected Polynomial.Point getShare(int i){
if(i < 1 || i > n){ assert (i > 0 && i <= n);
throw new Exception(); return new Polynomial.Point(BigInteger.valueOf(i), polynomial, q);
}
return new Polynomial.Point(BigInteger.valueOf(i), polynomial);
} }
/** /**
@ -78,7 +72,7 @@ public class SecretSharing {
* getter * getter
* @return threshold * @return threshold
*/ */
public int getThreshold() { public int getT() {
return t; return t;
} }
@ -94,7 +88,12 @@ public class SecretSharing {
* getter * getter
* @return the prime was given in the constructor * @return the prime was given in the constructor
*/ */
public BigInteger getP() { public BigInteger getQ() {
return p; return q;
}
protected Polynomial getPolynomial() {
return polynomial;
} }
} }

View File

@ -1,41 +1,55 @@
package FeldmanVerifiableSecretSharing; package FeldmanVerifiableSecretSharing;
import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial;
import FeldmanVerifiableSecretSharing.ShamirSecretSharing.SecretSharing; import FeldmanVerifiableSecretSharing.ShamirSecretSharing.SecretSharing;
import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Arrays;
import org.factcenter.qilin.primitives.CyclicGroup; import org.factcenter.qilin.primitives.CyclicGroup;
import org.factcenter.qilin.primitives.concrete.Zpstar;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Random; import java.util.Random;
/** /**
* Created by Tzlil on 1/27/2016. * Created by Tzlil on 1/27/2016.
*
* an implementation of Feldman's verifiable secret sharing scheme.
*
* allows trusted dealer to share a key x among n parties.
*
*/ */
public class VerifiableSecretSharing extends SecretSharing { public class VerifiableSecretSharing extends SecretSharing {
private final Zpstar zpstar;
private final CyclicGroup<BigInteger> group;
private final BigInteger g; // public generator of group private final BigInteger g; // public generator of group
private final BigInteger[] commitments; private final BigInteger[] commitments;
private final BigInteger y; // y = g ^ x
/** /**
* @param group a cyclic group of prime order p. * @param p a large prime
* it must be chosen such that computing discrete logarithms is hard in this group. * @param q a large prime dividing p - 1.
* @param g a generator of cyclic group of order q.
* the generated group is a subgroup of Zp*.
* it must be chosen such that computing discrete logarithms is hard in this group.
*/ */
public VerifiableSecretSharing(CyclicGroup<BigInteger> group, int t, int n, BigInteger s, Random random) { public VerifiableSecretSharing(int t, int n, BigInteger x, Random random,BigInteger p,BigInteger q,BigInteger g) {
super(group.orderUpperBound(), t, n, s, random); super(t, n, x, random,q);
this.group = group; this.g = g;
this.g = group.getGenerator(); this.zpstar = new Zpstar(p);
assert (zpstar.contains(g));
assert (p.subtract(BigInteger.ONE).mod(q).equals(BigInteger.ZERO)); // assert p - 1 % q == 0
this.commitments = generateCommitments(); this.commitments = generateCommitments();
this.y = zpstar.multiply(g,x);
} }
/** /**
* @return commitments[i] = g ^ polynomial.coefficients[i] * @return commitments[i] = g ^ polynomial.coefficients[i]
*/ */
private BigInteger[] generateCommitments() { private BigInteger[] generateCommitments() {
Polynomial polynomial = getPolynomial();
BigInteger[] coefficients = polynomial.getCoefficients(); BigInteger[] coefficients = polynomial.getCoefficients();
BigInteger[] commitments = new BigInteger[coefficients.length]; BigInteger[] commitments = new BigInteger[coefficients.length];
for (int i = 0 ; i < commitments.length;i++){ for (int i = 0 ; i < commitments.length;i++){
commitments[i] = group.multiply(g,coefficients[i]); commitments[i] = zpstar.multiply(g,coefficients[i]);
} }
return commitments; return commitments;
} }
@ -43,16 +57,16 @@ public class VerifiableSecretSharing extends SecretSharing {
/** /**
* @param i share holder id * @param i share holder id
* @param commitments * @param commitments
* @param group * @param zpstar
* *
* @return product of commitments[j] ^ (i ^ j) == g ^ polynomial(i) * @return product of commitments[j] ^ (i ^ j) == g ^ polynomial(i)
*/ */
public static BigInteger verify(int i,BigInteger[] commitments,CyclicGroup<BigInteger> group) { public static BigInteger verify(int i,BigInteger[] commitments,Zpstar zpstar) {
BigInteger v = group.zero(); BigInteger v = zpstar.zero();
BigInteger power = BigInteger.ONE; BigInteger power = BigInteger.ONE;
BigInteger I = BigInteger.valueOf(i); BigInteger I = BigInteger.valueOf(i);
for (int j = 0 ; j < commitments.length ; j ++){ for (int j = 0 ; j < commitments.length ; j ++){
v = group.add(v,group.multiply(commitments[j],power)); v = zpstar.add(v,zpstar.multiply(commitments[j],power));
power = power.multiply(I); power = power.multiply(I);
} }
return v; return v;
@ -75,12 +89,19 @@ public class VerifiableSecretSharing extends SecretSharing {
return Arrays.clone(commitments); return Arrays.clone(commitments);
} }
/**
* getter
* @return zpstar
*/
public Zpstar getZpstar(){
return zpstar;
}
/** /**
* getter * getter
* @return the cyclic group was given in the constructor * @return public value of this
*/ */
public CyclicGroup<BigInteger> getGroup() { public BigInteger getY(){
return group; return y;
} }
} }

View File

@ -0,0 +1,123 @@
package JointFeldmanProtocol;
import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial;
import FeldmanVerifiableSecretSharing.VerifiableSecretSharing;
import org.bouncycastle.util.Arrays;
import org.factcenter.qilin.primitives.concrete.Zpstar;
import java.math.BigInteger;
import java.util.Random;
import java.util.Set;
/**
* Created by Tzlil on 2/5/2016.
*
* an implementation of a version of Pedersen's distributed key generation protocol
*/
public class DKG extends VerifiableSecretSharing{
private Network.User user;
private Polynomial.Point[][] shares;
private BigInteger[][] commitmentsArray;
private Set<Integer> QUAL;
private BigInteger x;
private BigInteger y;
private BigInteger[] commitments;
public DKG(int t, int n, BigInteger x, Random random, BigInteger p, BigInteger q, BigInteger g) {
super(t, n, x, random, p, q, g);
}
private void stage1(){
int n = getN();
int i = user.getID();
BigInteger[] commitments = super.getCommitments();
System.arraycopy(commitments, 0, commitmentsArray[i - 1], 0, commitmentsArray[i - 1].length);
Network.Message message = null;
for (int j = 1; j <= commitmentsArray[i - 1].length; j ++){
//message = new Message(Type.Commitment, Shares[i - 1][j - 1])
user.sendBroadcast(message);
}
for (int j = 1; j <= shares[i - 1].length; j ++){
shares[i - 1][j - 1] = getShare(j);
}
for (int j = 1; j <= n ; j++ ){
if(j != i){
//message = new Message(Type.Share, Shares[i - 1][j - 1])
user.send(j,message);
}
}
//Todo receive messages
}
private void stage2(){
int n = getN();
BigInteger g = getGenerator();
Zpstar zpstar = getZpstar();
int i = user.getID();
Network.Message message = null;
for (int j = 1; j <= n ; j++ ){
if(zpstar.multiply(g,shares[i - 1][j - 1].y).equals(verify(j,commitmentsArray[j],zpstar))){
QUAL.add(j);
}else{
//message = new Message(Type.Complaint, j)
user.sendBroadcast(message);
}
}
}
private void stage3(){
//Todo receive something private from each complaint + send what necessary
}
private void stage4(){
Network.Message message = null;
// message = new Message(Type.Y, super.getY())
user.sendBroadcast(message);
Zpstar zpstar = getZpstar();
BigInteger y = zpstar.zero();
for (Network.User user:this.user.getNetwork()) {
//Todo receive yi from all i in QUAL and calc y total
}
int t = getT();
this.commitments = new BigInteger[t];
BigInteger commitment;
for (int k = 1; k <= t ; k++){
commitment = zpstar.zero();
for (int i : QUAL) {
commitment = zpstar.add(commitment,commitmentsArray[i - 1][k - 1]);
}
commitments[k - 1] = commitment;
}
int j = user.getID();
BigInteger x = BigInteger.ZERO;
for (int i : QUAL) {
x = x.add(shares[i][j].y);
}
this.x = x.mod(getQ());
}
@Override
public BigInteger getY() {
return y;
}
@Override
public BigInteger[] getCommitments() {
return Arrays.clone(commitments);
}
@Override
protected Polynomial.Point getShare(int i) {
return null;
}
}

View File

@ -0,0 +1,27 @@
package JointFeldmanProtocol;
/**
* Created by Tzlil on 2/5/2016.
*/
public interface Network extends Iterable<Network.User>{
User connect();
interface User{
int getID();
void send(int userID,Message message);
void sendBroadcast(Message message);
void receive(int userID,Message message);
void receiveBroadcast(Message message);
Network getNetwork();
}
interface Message{
enum Type {
Commitment, Share, Complaint, Y
}
Type getType();
}
}

View File

@ -14,7 +14,7 @@ public class Utils {
BigInteger[] coefficients = new BigInteger[degree + 1]; BigInteger[] coefficients = new BigInteger[degree + 1];
for (int i = 0 ; i <= degree; i++ ){ for (int i = 0 ; i <= degree; i++ ){
coefficients[i] = new BigInteger(bits,random); // sample from Zp [0,... p-1] coefficients[i] = new BigInteger(bits,random); // sample from Zp [0,... q-1]
} }
return new Polynomial(coefficients); return new Polynomial(coefficients);
} }

View File

@ -1,15 +1,13 @@
package FeldmanVerifiableSecretSharing; package FeldmanVerifiableSecretSharing;
import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial; import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial;
import FeldmanVerifiableSecretSharing.ShamirSecretSharing.SecretSharing;
import org.factcenter.qilin.primitives.CyclicGroup; import org.factcenter.qilin.primitives.CyclicGroup;
import org.factcenter.qilin.primitives.concrete.Zn; import org.factcenter.qilin.primitives.concrete.Zn;
import org.factcenter.qilin.primitives.concrete.Zpstar;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Random; import java.util.Random;
/** /**
@ -25,31 +23,34 @@ public class VerifiableSecretSharingTest {
@Before @Before
public void settings(){ public void settings(){
BigInteger p = BigInteger.valueOf(2903); BigInteger p = BigInteger.valueOf(2903);
CyclicGroup<BigInteger> group = new Zn(p); BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2));
int t = 10;
int t = 8;
int n = 20; int n = 20;
random = new Random(); random = new Random();
BigInteger g = null; //Todo
verifiableSecretSharingArray = new VerifiableSecretSharing[tests]; verifiableSecretSharingArray = new VerifiableSecretSharing[tests];
for (int i = 0; i < verifiableSecretSharingArray.length; i++){ for (int i = 0; i < verifiableSecretSharingArray.length; i++){
verifiableSecretSharingArray[i] = new VerifiableSecretSharing(group,t,n,group.sample(random),random); verifiableSecretSharingArray[i] = new VerifiableSecretSharing(t,n
,new BigInteger(q.bitLength(),random).mod(q),random,p,q,g);
} }
} }
public void oneTest(VerifiableSecretSharing verifiableSecretSharing) throws Exception { public void oneTest(VerifiableSecretSharing verifiableSecretSharing) throws Exception {
int n = verifiableSecretSharing.getN(); int n = verifiableSecretSharing.getN();
BigInteger p = verifiableSecretSharing.getP(); BigInteger p = verifiableSecretSharing.getQ();
CyclicGroup<BigInteger> group = verifiableSecretSharing.getGroup(); Zpstar zpstar = new Zpstar(p);
BigInteger g = verifiableSecretSharing.getGenerator(); BigInteger g = verifiableSecretSharing.getGenerator();
Polynomial.Point[] shares = new Polynomial.Point[n]; Polynomial.Point[] shares = new Polynomial.Point[n];
BigInteger[] commitments = verifiableSecretSharing.getCommitments(); BigInteger[] commitments = verifiableSecretSharing.getCommitments();
BigInteger[] verifications = new BigInteger[n]; BigInteger[] verifications = new BigInteger[n];
for (int i = 1 ; i <= shares.length; i ++){ for (int i = 1 ; i <= shares.length; i ++){
shares[i - 1] = verifiableSecretSharing.getShare(i); shares[i - 1] = verifiableSecretSharing.getShare(i);
verifications[i - 1] = VerifiableSecretSharing.verify(i,commitments,group); verifications[i - 1] = VerifiableSecretSharing.verify(i,commitments,zpstar);
} }
BigInteger expected; BigInteger expected;
for (int i = 0 ; i < shares.length ; i++){ for (int i = 0 ; i < shares.length ; i++){
expected = group.multiply(g,shares[i].y).mod(p); // problem with Zn, multiplication doesn't mod n as required expected = zpstar.multiply(g,shares[i].y);
assert (expected.equals(verifications[i])); assert (expected.equals(verifications[i]));
} }
@ -59,6 +60,7 @@ public class VerifiableSecretSharingTest {
public void secretSharingTest() throws Exception { public void secretSharingTest() throws Exception {
for (int i = 0 ; i < verifiableSecretSharingArray.length; i ++){ for (int i = 0 ; i < verifiableSecretSharingArray.length; i ++){
oneTest(verifiableSecretSharingArray[i]); oneTest(verifiableSecretSharingArray[i]);
} }
} }
} }