feldmanVSS documention

DKG
tzlil.gon 2016-01-28 13:57:47 +02:00
parent 93240c10f4
commit 8ba55bacd2
5 changed files with 180 additions and 35 deletions

View File

@ -13,43 +13,64 @@ import java.util.Random;
*/
public class VerifiableSecretSharing extends SecretSharing {
private final CyclicGroup<BigInteger> 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<BigInteger> 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<BigInteger> 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);
}

View File

@ -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;

View File

@ -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<Polynomial> {
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;
}
}

View File

@ -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<BigInteger> group;
protected final int t;
protected final int n;
protected final BigInteger p;
protected final Polynomial polynomial;
public SecretSharing(CyclicGroup<BigInteger> 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;
}

View File

@ -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