From 8ba55bacd20b389af365edadc2d5572fe2d24991 Mon Sep 17 00:00:00 2001 From: "tzlil.gon" Date: Thu, 28 Jan 2016 13:57:47 +0200 Subject: [PATCH] feldmanVSS documention --- .../VerifiableSecretSharing.java | 41 ++++++-- .../LagrangePolynomial.java | 26 ++++- .../java/ShamirSecretSharing/Polynomial.java | 96 +++++++++++++++---- .../ShamirSecretSharing/SecretSharing.java | 48 ++++++++-- .../java/Polynomial/InterpolationTest.java | 4 +- 5 files changed, 180 insertions(+), 35 deletions(-) diff --git a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java index 1b44693..1554bf6 100644 --- a/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java +++ b/destributed-key-generation/src/main/java/FeldmanVerifiableSecretSharing/VerifiableSecretSharing.java @@ -13,43 +13,64 @@ import java.util.Random; */ public class VerifiableSecretSharing extends SecretSharing { + private final CyclicGroup group; + private final BigInteger g; // public generator of group private final BigInteger[] commitments; - private final BigInteger g; + + /** + * @param group a cyclic group of prime order p. + * 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, t, n, s, random); + super(group.orderUpperBound(), t, n, s, random); + this.group = group; this.g = group.getGenerator(); this.commitments = generateCommitments(); } + /** + * @return commitments[i] = g ^ polynomial.coefficients[i] + */ private BigInteger[] generateCommitments() { 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]); //(g ^ coeff[i]) % p + commitments[i] = group.multiply(g,coefficients[i]); } return commitments; } - public BigInteger verify(int i) throws Exception { - if(i < 1 || i > n){ - throw new Exception(); - } + /** + * @param i share holder id + * @param commitments + * @param group + * + * @return product of commitments[j] ^ (i ^ j) == g ^ polynomial(i) + */ + public static BigInteger verify(int i,BigInteger[] commitments,CyclicGroup group) { BigInteger v = group.zero(); int power = 1; for (int j = 0 ; j < commitments.length ; j ++){ v = group.add(v,commitments[i].pow(power)); power *=i; } - - return group.add(group.zero(),v); + return v; } - public BigInteger getG() { + /** + * getter + * @return generator of group + */ + public BigInteger getGenerator() { return g; } + /** + * getter + * @return copy of commitments + */ public BigInteger[] getCommitments() { return Arrays.clone(commitments); } diff --git a/destributed-key-generation/src/main/java/ShamirSecretSharing/LagrangePolynomial.java b/destributed-key-generation/src/main/java/ShamirSecretSharing/LagrangePolynomial.java index fbaa893..d3815ff 100644 --- a/destributed-key-generation/src/main/java/ShamirSecretSharing/LagrangePolynomial.java +++ b/destributed-key-generation/src/main/java/ShamirSecretSharing/LagrangePolynomial.java @@ -4,19 +4,41 @@ import java.math.BigInteger; /** * Created by Tzlil on 1/28/2016. + * + * container of lagrange polynomial + * + * can't be constructed, constructor is private + * + * l = (image/divisor)* polynomial + * + * Note : image and divisor stored separately for avoiding lose of information by division */ class LagrangePolynomial{ public final Polynomial polynomial; public final BigInteger image; public final BigInteger divisor; + /** + * inner constructor, stores all given parameters + * @param polynomial + * @param image + * @param divisor + */ private LagrangePolynomial(Polynomial polynomial, BigInteger image, BigInteger divisor) { this.polynomial = polynomial; this.image = image; this.divisor = divisor; } - public static LagrangePolynomial[] lagrangePolynomials(Polynomial.Point[] points){ + /** + * static method + * @param points array points s.t there are no couple of points that shares the same x value + * + * @return the lagrange polynomials that mach to given points + * + * @throws Exception there exists i != j s.t points[i].x == points[j].x + */ + public static LagrangePolynomial[] lagrangePolynomials(Polynomial.Point[] points) throws Exception { LagrangePolynomial[] lagrangePolynomials = new LagrangePolynomial[points.length]; Polynomial[] factors = new Polynomial[points.length]; for (int i = 0 ; i < factors.length ; i++){ @@ -33,6 +55,8 @@ class LagrangePolynomial{ product = product.mul(factors[j]); } } + if(divisor.equals(BigInteger.ZERO)) + throw new Exception(); lagrangePolynomials[i] = new LagrangePolynomial(product,points[i].y,divisor); } return lagrangePolynomials; diff --git a/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java b/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java index b1dddcc..620e1e7 100644 --- a/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java +++ b/destributed-key-generation/src/main/java/ShamirSecretSharing/Polynomial.java @@ -9,27 +9,39 @@ import java.math.BigInteger; /** * Created by Tzlil on 1/27/2016. */ -public class Polynomial { - - protected static final Polynomial ZERO = new Polynomial(new BigInteger[]{BigInteger.ZERO}); - protected static final Polynomial ONE = new Polynomial(new BigInteger[]{BigInteger.ONE}); +public class Polynomial implements Comparable { + protected static final Polynomial ZERO = new Polynomial(new BigInteger[]{BigInteger.ZERO}); // neutral for add + protected static final Polynomial ONE = new Polynomial(new BigInteger[]{BigInteger.ONE}); // neutral for mul private final int degree; private final BigInteger[] coefficients; + /** + * constructor + * @param coefficients + * degree set as max index such that coefficients[degree] not equals zero + */ public Polynomial(BigInteger[] coefficients) { - this.degree = coefficients.length - 1; + int d = coefficients.length - 1; + while (d > 0 && coefficients[d].equals(BigInteger.ZERO)){ + d--; + } + this.degree = d; this.coefficients = coefficients; } - public Polynomial(Polynomial polynomial) { - this.degree = polynomial.getDegree(); - this.coefficients = polynomial.getCoefficients(); - } - public boolean isEquals(Polynomial other) { + @Override + public int compareTo(Polynomial other) { if (this.degree != other.degree) - return false; - return Arrays.areEqual(this.coefficients,other.coefficients); + return this.degree - other.degree; + int compare; + for (int i = degree; i >= degree ; i--){ + compare = this.coefficients[i].compareTo(other.coefficients[i]); + if (compare != 0){ + return compare; + } + } + return 0; } @Override @@ -40,6 +52,11 @@ public class Polynomial { '}'; } + + /** + * @param x + * @return sum of coefficients[i] * (x ^ i) + */ public BigInteger image(BigInteger x){ BigInteger result = BigInteger.ZERO; BigInteger power = BigInteger.ONE; @@ -50,20 +67,28 @@ public class Polynomial { return result; } + /** + * @param points + * @return polynomial of minimal degree which goes through all points + */ public static Polynomial interpolation(Point[] points){ LagrangePolynomial[] l = LagrangePolynomial.lagrangePolynomials(points); + // product = product of l[i].divisor BigInteger product = BigInteger.ONE; for (int i = 0; i < l.length;i++){ product = product.multiply(l[i].divisor); } + // factor[i] = product divided by l[i].divisor = product of l[j].divisor s.t j!=i BigInteger[] factors = new BigInteger[l.length]; for (int i = 0; i < l.length;i++){ factors[i] = product.divide(l[i].divisor); } - int degree = l[0].polynomial.degree; + + // coefficients[j] = (sum of l[i].image * factor[i] * l[i].coefficients[j] s.t i!=j) divide by product = + // = sum of l[i].image * l[i].coefficients[j] / l[i].divisor s.t i!=j BigInteger[] coefficients = new BigInteger[degree + 1]; for (int j = 0; j < coefficients.length;j++){ coefficients[j] = BigInteger.ZERO; @@ -75,6 +100,11 @@ public class Polynomial { return new Polynomial(coefficients); } + /** + * @param other + * @return new Polynomial of degree max(this degree,other degree) s.t for all x in Z + * new.image(x) = this.image(x) + other.image(x) + */ public Polynomial add(Polynomial other){ Polynomial bigger,smaller; if(this.degree < other.degree){ @@ -92,6 +122,11 @@ public class Polynomial { return new Polynomial(coefficients); } + /** + * @param constant + * @return new Polynomial of degree this.degree s.t for all x in Z + * new.image(x) = constant * this.image(x) + */ public Polynomial mul(BigInteger constant){ BigInteger[] coefficients = this.getCoefficients(); @@ -102,6 +137,11 @@ public class Polynomial { return new Polynomial(coefficients); } + /** + * @param other + * @return new Polynomial of degree this degree + other degree + 1 s.t for all x in Z + * new.image(x) = this.image(x) * other.image(x) + */ public Polynomial mul(Polynomial other){ BigInteger[] coefficients = new BigInteger[this.degree + other.degree + 1]; @@ -116,21 +156,45 @@ public class Polynomial { } + /** getter + * @return copy of coefficients + */ public BigInteger[] getCoefficients() { return Arrays.clone(coefficients); } + + /** getter + * @return degree + */ public int getDegree() { return degree; } - + /** + * inner class + * container for (x,y) x from range and y from image of polynomial + */ public static class Point{ public final BigInteger x; public final BigInteger y; - public Point(BigInteger x, BigInteger y) { + /** + * constructor + * @param x + * @param polynomial y = polynomial.image(x) + */ + public Point(BigInteger x, Polynomial polynomial) { this.x = x; - this.y = y; + this.y = polynomial.image(x); + } + + /** + * copy constructor + * @param point + */ + public Point(Point point) { + this.x = point.x; + this.y = point.y; } } diff --git a/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java b/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java index 0fe9d6a..d3c48c9 100644 --- a/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java +++ b/destributed-key-generation/src/main/java/ShamirSecretSharing/SecretSharing.java @@ -9,48 +9,84 @@ import java.util.Random; /** * Created by Tzlil on 1/27/2016. + * an implementation of Shamire's secret sharing scheme */ public class SecretSharing { - protected final CyclicGroup group; protected final int t; protected final int n; + protected final BigInteger p; protected final Polynomial polynomial; - public SecretSharing(CyclicGroup group, int t, int n, BigInteger s, Random random) { - this.group = group; + /** + * constructor + * @param p 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 random use for generate random polynomial + */ + public SecretSharing(BigInteger p, int t, int n, BigInteger s, Random random) { + this.p = p; this.t = t; this.n = n; this.polynomial = generateRandomPolynomial(s,random); } + /** + * @param s + * @param random + * @return new Polynomial polynomial of degree t ,such that + * 1. polynomial(0) = s + * 2. polynomial coefficients randomly chosen from Zp (except of coefficients[0] = s) + */ private Polynomial generateRandomPolynomial(BigInteger s, Random random) { BigInteger[] coefficients = new BigInteger[t + 1]; coefficients[0] = s; - BigInteger p = group.orderUpperBound(); int bits = p.bitLength(); for (int i = 1 ; i <= t; i++ ){ - coefficients[i] = new BigInteger(bits,random).mod(p); // sample from Zp [0,... p-1] + coefficients[i] = new BigInteger(bits,random).mod(p); } 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 + */ public Polynomial.Point getShare(int i) throws Exception { if(i < 1 || i > n){ throw new Exception(); } - return new Polynomial.Point(BigInteger.valueOf(i), polynomial.image(BigInteger.valueOf(i))); + return new Polynomial.Point(BigInteger.valueOf(i), polynomial); } + /** + * @param shares - subset of the original shares + * + * @return image of interpolation(shares) at x = 0 + */ public static BigInteger getSecrete(Polynomial.Point[] shares){ Polynomial polynomial = Polynomial.interpolation(shares); return polynomial.image(BigInteger.ZERO); } + /** + * getter + * @return threshold + */ public int getThreshold() { return t; } + /** + * getter + * @return number of share holders + */ public int getN() { return n; } diff --git a/destributed-key-generation/src/test/java/Polynomial/InterpolationTest.java b/destributed-key-generation/src/test/java/Polynomial/InterpolationTest.java index 25595c7..d08b0f2 100644 --- a/destributed-key-generation/src/test/java/Polynomial/InterpolationTest.java +++ b/destributed-key-generation/src/test/java/Polynomial/InterpolationTest.java @@ -42,14 +42,14 @@ public class InterpolationTest { continue; } set.add(x); - points[i] = new Polynomial.Point(x,p.image(x)); + points[i] = new Polynomial.Point(x,p); } return points; } public void oneTest(Polynomial p, Polynomial.Point[] points){ Polynomial interpolation = Polynomial.interpolation(points); - assert (p.isEquals(interpolation)); + assert (p.compareTo(interpolation) == 0); } @Test