feldmanVSS documention
parent
93240c10f4
commit
8ba55bacd2
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue