diff --git a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/Polynomial.java b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/Polynomial.java index ac340b7..e285e01 100644 --- a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/Polynomial.java +++ b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/Polynomial.java @@ -186,6 +186,18 @@ public class Polynomial implements Comparable { 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 * @param point diff --git a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharing.java b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharing.java index f5629d4..4a90ac7 100644 --- a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharing.java +++ b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/SecretSharing.java @@ -9,59 +9,53 @@ import java.util.Random; * an implementation of Shamire's secret sharing scheme */ public class SecretSharing { - protected final int t; - protected final int n; + private final int t; + private final int n; + private final BigInteger q; - - protected final BigInteger p; - protected final Polynomial polynomial; + private final Polynomial polynomial; /** * constructor - * @param p prime + * @param q a large prime. * @param t threshold. Any t+1 share holders can recover the secret, * but any set of at most t share holders cannot * @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 */ - public SecretSharing(BigInteger p, int t, int n, BigInteger s, Random random) { - this.p = p; + public SecretSharing(int t, int n, BigInteger x, Random random,BigInteger q) { + this.q = q; this.t = t; this.n = n; - this.polynomial = generateRandomPolynomial(s,random); + this.polynomial = generateRandomPolynomial(x,random); } /** - * @param s + * @param x * @param random - * @return new FeldmanVerifiableSecretSharing.ShamirSecretSharing.PolynomialTests polynomial of degree t ,such that - * 1. polynomial(0) = s - * 2. polynomial coefficients randomly chosen from Zp (except of coefficients[0] = s) + * @return new Polynomial polynomial of degree t ,such that + * 1. polynomial(0) = x + * 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]; - coefficients[0] = s; - int bits = p.bitLength(); + coefficients[0] = x.mod(q); + int bits = q.bitLength(); 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); } - //ToDo make it safe : permission to call this func /** * @param i in range of [1,...n] * - * @return polynomial.image(i) - * - * @throws Exception i out of range + * @return polynomial.image(i)%q */ - public Polynomial.Point getShare(int i) throws Exception { - if(i < 1 || i > n){ - throw new Exception(); - } - return new Polynomial.Point(BigInteger.valueOf(i), polynomial); + protected Polynomial.Point getShare(int i){ + assert (i > 0 && i <= n); + return new Polynomial.Point(BigInteger.valueOf(i), polynomial, q); } /** @@ -78,7 +72,7 @@ public class SecretSharing { * getter * @return threshold */ - public int getThreshold() { + public int getT() { return t; } @@ -94,7 +88,12 @@ public class SecretSharing { * getter * @return the prime was given in the constructor */ - public BigInteger getP() { - return p; + public BigInteger getQ() { + return q; + } + + protected Polynomial getPolynomial() { + + return polynomial; } } diff --git a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java index 082177f..e8d5c98 100644 --- a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java +++ b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java @@ -1,41 +1,55 @@ package FeldmanVerifiableSecretSharing; +import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial; import FeldmanVerifiableSecretSharing.ShamirSecretSharing.SecretSharing; import org.bouncycastle.util.Arrays; import org.factcenter.qilin.primitives.CyclicGroup; +import org.factcenter.qilin.primitives.concrete.Zpstar; import java.math.BigInteger; import java.util.Random; /** * 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 { - - private final CyclicGroup group; + private final Zpstar zpstar; private final BigInteger g; // public generator of group private final BigInteger[] commitments; - + private final BigInteger y; // y = g ^ x /** - * @param group a cyclic group of prime order p. - * it must be chosen such that computing discrete logarithms is hard in this group. + * @param p a large prime + * @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 group, int t, int n, BigInteger s, Random random) { - super(group.orderUpperBound(), t, n, s, random); - this.group = group; - this.g = group.getGenerator(); + public VerifiableSecretSharing(int t, int n, BigInteger x, Random random,BigInteger p,BigInteger q,BigInteger g) { + super(t, n, x, random,q); + this.g = g; + 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.y = zpstar.multiply(g,x); } /** * @return commitments[i] = g ^ polynomial.coefficients[i] */ private BigInteger[] generateCommitments() { + + Polynomial polynomial = getPolynomial(); BigInteger[] coefficients = polynomial.getCoefficients(); BigInteger[] commitments = new BigInteger[coefficients.length]; for (int i = 0 ; i < commitments.length;i++){ - commitments[i] = group.multiply(g,coefficients[i]); + commitments[i] = zpstar.multiply(g,coefficients[i]); } return commitments; } @@ -43,16 +57,16 @@ public class VerifiableSecretSharing extends SecretSharing { /** * @param i share holder id * @param commitments - * @param group + * @param zpstar * * @return product of commitments[j] ^ (i ^ j) == g ^ polynomial(i) */ - public static BigInteger verify(int i,BigInteger[] commitments,CyclicGroup group) { - BigInteger v = group.zero(); + public static BigInteger verify(int i,BigInteger[] commitments,Zpstar zpstar) { + BigInteger v = zpstar.zero(); BigInteger power = BigInteger.ONE; BigInteger I = BigInteger.valueOf(i); 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); } return v; @@ -75,12 +89,19 @@ public class VerifiableSecretSharing extends SecretSharing { return Arrays.clone(commitments); } + /** + * getter + * @return zpstar + */ + public Zpstar getZpstar(){ + return zpstar; + } /** * getter - * @return the cyclic group was given in the constructor + * @return public value of this */ - public CyclicGroup getGroup() { - return group; + public BigInteger getY(){ + return y; } } diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/DKG.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DKG.java new file mode 100644 index 0000000..6962d29 --- /dev/null +++ b/destributed-key-generation/src/main/java/JointFeldmanProtocol/DKG.java @@ -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 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; + } +} diff --git a/destributed-key-generation/src/main/java/JointFeldmanProtocol/Network.java b/destributed-key-generation/src/main/java/JointFeldmanProtocol/Network.java new file mode 100644 index 0000000..46c1d44 --- /dev/null +++ b/destributed-key-generation/src/main/java/JointFeldmanProtocol/Network.java @@ -0,0 +1,27 @@ +package JointFeldmanProtocol; + +/** + * Created by Tzlil on 2/5/2016. + */ +public interface Network extends Iterable{ + + 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(); + + } +} diff --git a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/Utils.java b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/Utils.java index b43869d..67bd51c 100644 --- a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/Utils.java +++ b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/ShamirSecretSharing/PolynomialTests/Utils.java @@ -14,7 +14,7 @@ public class Utils { BigInteger[] coefficients = new BigInteger[degree + 1]; 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); } diff --git a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java index 8846cd9..ec58262 100644 --- a/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java +++ b/destributed-key-generation/src/test/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharingTest.java @@ -1,15 +1,13 @@ package FeldmanVerifiableSecretSharing; import FeldmanVerifiableSecretSharing.ShamirSecretSharing.Polynomial; -import FeldmanVerifiableSecretSharing.ShamirSecretSharing.SecretSharing; import org.factcenter.qilin.primitives.CyclicGroup; import org.factcenter.qilin.primitives.concrete.Zn; +import org.factcenter.qilin.primitives.concrete.Zpstar; import org.junit.Before; import org.junit.Test; import java.math.BigInteger; -import java.util.ArrayList; -import java.util.List; import java.util.Random; /** @@ -25,31 +23,34 @@ public class VerifiableSecretSharingTest { @Before public void settings(){ BigInteger p = BigInteger.valueOf(2903); - CyclicGroup group = new Zn(p); - int t = 10; + BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); + + int t = 8; int n = 20; random = new Random(); + BigInteger g = null; //Todo verifiableSecretSharingArray = new VerifiableSecretSharing[tests]; 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 { int n = verifiableSecretSharing.getN(); - BigInteger p = verifiableSecretSharing.getP(); - CyclicGroup group = verifiableSecretSharing.getGroup(); + BigInteger p = verifiableSecretSharing.getQ(); + Zpstar zpstar = new Zpstar(p); BigInteger g = verifiableSecretSharing.getGenerator(); Polynomial.Point[] shares = new Polynomial.Point[n]; BigInteger[] commitments = verifiableSecretSharing.getCommitments(); BigInteger[] verifications = new BigInteger[n]; for (int i = 1 ; i <= shares.length; 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; 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])); } @@ -59,6 +60,7 @@ public class VerifiableSecretSharingTest { public void secretSharingTest() throws Exception { for (int i = 0 ; i < verifiableSecretSharingArray.length; i ++){ oneTest(verifiableSecretSharingArray[i]); + } } }