tested interpolation

DKG
tzlil.gon 2016-01-28 01:47:07 +02:00
parent 6100497e8e
commit 93240c10f4
9 changed files with 313 additions and 32 deletions

View File

@ -2,6 +2,7 @@ package FeldmanVerifiableSecretSharing;
import ShamirSecretSharing.SecretSharing; import ShamirSecretSharing.SecretSharing;
import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Arrays;
import org.factcenter.qilin.primitives.CyclicGroup;
import org.factcenter.qilin.primitives.concrete.Zpstar; import org.factcenter.qilin.primitives.concrete.Zpstar;
import java.math.BigInteger; import java.math.BigInteger;
@ -15,9 +16,9 @@ public class VerifiableSecretSharing extends SecretSharing {
private final BigInteger[] commitments; private final BigInteger[] commitments;
private final BigInteger g; private final BigInteger g;
public VerifiableSecretSharing(Zpstar zpstar, int t, int n, BigInteger s, Random random) { public VerifiableSecretSharing(CyclicGroup<BigInteger> group, int t, int n, BigInteger s, Random random) {
super(zpstar, t, n, s, random); super(group, t, n, s, random);
this.g = BigInteger.ONE; //ToDO zpstar.getGenerator() this.g = group.getGenerator();
this.commitments = generateCommitments(); this.commitments = generateCommitments();
} }
@ -25,7 +26,7 @@ public class VerifiableSecretSharing extends SecretSharing {
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] = zpstar.multiply(g,coefficients[i]); commitments[i] = group.multiply(g,coefficients[i]); //(g ^ coeff[i]) % p
} }
return commitments; return commitments;
} }
@ -34,13 +35,14 @@ public class VerifiableSecretSharing extends SecretSharing {
if(i < 1 || i > n){ if(i < 1 || i > n){
throw new Exception(); throw new Exception();
} }
BigInteger v = BigInteger.ONE; BigInteger v = group.zero();
int power = 1; int power = 1;
for (int j = 0 ; j < commitments.length ; j ++){ for (int j = 0 ; j < commitments.length ; j ++){
v.multiply(commitments[i].pow(power)); v = group.add(v,commitments[i].pow(power));
power *=i; power *=i;
} }
return zpstar.add(BigInteger.ONE,v);
return group.add(group.zero(),v);
} }

View File

@ -0,0 +1,40 @@
package ShamirSecretSharing;
import java.math.BigInteger;
/**
* Created by Tzlil on 1/28/2016.
*/
class LagrangePolynomial{
public final Polynomial polynomial;
public final BigInteger image;
public final BigInteger 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){
LagrangePolynomial[] lagrangePolynomials = new LagrangePolynomial[points.length];
Polynomial[] factors = new Polynomial[points.length];
for (int i = 0 ; i < factors.length ; i++){
factors[i] = new Polynomial(new BigInteger[]{BigInteger.ZERO.subtract(points[i].x),BigInteger.ONE}); // X - Xi
}
Polynomial product;
BigInteger divisor;
for(int i = 0; i < points.length; i ++) {
product = Polynomial.ONE;
divisor = BigInteger.ONE;
for (int j = 0; j < points.length; j++) {
if (i != j) {
divisor = divisor.multiply(points[i].x.subtract(points[j].x));
product = product.mul(factors[j]);
}
}
lagrangePolynomials[i] = new LagrangePolynomial(product,points[i].y,divisor);
}
return lagrangePolynomials;
}
}

View File

@ -2,6 +2,7 @@ package ShamirSecretSharing;
import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Arrays;
import org.factcenter.qilin.primitives.concrete.ECGroup; import org.factcenter.qilin.primitives.concrete.ECGroup;
import org.factcenter.qilin.util.Pair;
import java.math.BigInteger; import java.math.BigInteger;
@ -10,8 +11,8 @@ import java.math.BigInteger;
*/ */
public class Polynomial { public class Polynomial {
private static final Polynomial ZERO = new Polynomial(new BigInteger[]{BigInteger.ZERO}); protected static final Polynomial ZERO = new Polynomial(new BigInteger[]{BigInteger.ZERO});
private static final Polynomial ONE = new Polynomial(new BigInteger[]{BigInteger.ONE}); protected static final Polynomial ONE = new Polynomial(new BigInteger[]{BigInteger.ONE});
private final int degree; private final int degree;
private final BigInteger[] coefficients; private final BigInteger[] coefficients;
@ -25,36 +26,53 @@ public class Polynomial {
this.coefficients = polynomial.getCoefficients(); this.coefficients = polynomial.getCoefficients();
} }
public boolean isEquals(Polynomial other) {
if (this.degree != other.degree)
return false;
return Arrays.areEqual(this.coefficients,other.coefficients);
}
@Override
public String toString() {
return "Polynomial{" +
"degree=" + degree +
", coefficients=" + java.util.Arrays.toString(coefficients) +
'}';
}
public BigInteger image(BigInteger x){ public BigInteger image(BigInteger x){
BigInteger result = BigInteger.ZERO; BigInteger result = BigInteger.ZERO;
BigInteger power = BigInteger.ONE; BigInteger power = BigInteger.ONE;
for(int i = 0 ; i <= degree ; i++){ for(int i = 0 ; i <= degree ; i++){
result.add(coefficients[i].multiply(power)); result = result.add(coefficients[i].multiply(power));
power.multiply(x); power = power.multiply(x);
} }
return result; return result;
} }
public static Polynomial interpolation(Point[] points){ public static Polynomial interpolation(Point[] points){
Polynomial[] factors = new Polynomial[points.length]; LagrangePolynomial[] l = LagrangePolynomial.lagrangePolynomials(points);
for (int i = 0 ; i < factors.length ; i++){
factors[i] = new Polynomial(new BigInteger[]{BigInteger.ONE,points[i].x}); // X - Xi BigInteger product = BigInteger.ONE;
for (int i = 0; i < l.length;i++){
product = product.multiply(l[i].divisor);
} }
Polynomial result = ZERO;
BigInteger constant; BigInteger[] factors = new BigInteger[l.length];
Polynomial product; for (int i = 0; i < l.length;i++){
for (int i = 0 ; i < points.length; i++){ factors[i] = product.divide(l[i].divisor);
constant = points[i].y; }
product = ONE;
for (int j = 0 ; j < points.length; j ++){ int degree = l[0].polynomial.degree;
if(i != j ) { BigInteger[] coefficients = new BigInteger[degree + 1];
constant = constant.divide(points[i].x.subtract(points[j].x)); for (int j = 0; j < coefficients.length;j++){
product = product.mul(factors[j]); coefficients[j] = BigInteger.ZERO;
} for (int i = 0; i < l.length; i++){
coefficients[j] = coefficients[j].add(l[i].image.multiply(factors[i]).multiply(l[i].polynomial.coefficients[j]));
} }
result.add(product.mul(constant)); coefficients[j] = coefficients[j].divide(product);
} }
return result; return new Polynomial(coefficients);
} }
public Polynomial add(Polynomial other){ public Polynomial add(Polynomial other){

View File

@ -1,6 +1,7 @@
package ShamirSecretSharing; package ShamirSecretSharing;
import org.factcenter.qilin.primitives.CyclicGroup;
import org.factcenter.qilin.primitives.concrete.Zpstar; import org.factcenter.qilin.primitives.concrete.Zpstar;
import java.math.BigInteger; import java.math.BigInteger;
@ -10,13 +11,13 @@ import java.util.Random;
* Created by Tzlil on 1/27/2016. * Created by Tzlil on 1/27/2016.
*/ */
public class SecretSharing { public class SecretSharing {
protected final Zpstar zpstar; protected final CyclicGroup<BigInteger> group;
protected final int t; protected final int t;
protected final int n; protected final int n;
protected final Polynomial polynomial; protected final Polynomial polynomial;
public SecretSharing(Zpstar zpstar, int t, int n, BigInteger s, Random random) { public SecretSharing(CyclicGroup<BigInteger> group, int t, int n, BigInteger s, Random random) {
this.zpstar = zpstar; this.group = group;
this.t = t; this.t = t;
this.n = n; this.n = n;
this.polynomial = generateRandomPolynomial(s,random); this.polynomial = generateRandomPolynomial(s,random);
@ -25,13 +26,15 @@ public class SecretSharing {
private Polynomial generateRandomPolynomial(BigInteger s, Random random) { private Polynomial generateRandomPolynomial(BigInteger s, Random random) {
BigInteger[] coefficients = new BigInteger[t + 1]; BigInteger[] coefficients = new BigInteger[t + 1];
coefficients[0] = s; coefficients[0] = s;
BigInteger p = group.orderUpperBound();
int bits = p.bitLength();
for (int i = 1 ; i <= t; i++ ){ for (int i = 1 ; i <= t; i++ ){
coefficients[i] = zpstar.sample(random); coefficients[i] = new BigInteger(bits,random).mod(p); // sample from Zp [0,... p-1]
} }
return new Polynomial(coefficients); return new Polynomial(coefficients);
} }
//ToDo make it safe : permission to call this func + modulo calc //ToDo make it safe : permission to call this func
public Polynomial.Point getShare(int i) throws Exception { public Polynomial.Point getShare(int i) throws Exception {
if(i < 1 || i > n){ if(i < 1 || i > n){
throw new Exception(); throw new Exception();

View File

@ -0,0 +1,44 @@
package Polynomial;
import ShamirSecretSharing.Polynomial;
import org.junit.Before;
import org.junit.Test;
import java.math.BigInteger;
import java.util.Random;
/**
* Created by Tzlil on 1/27/2016.
*/
public class AddTest {
Polynomial[] arr1;
Polynomial[] arr2;
int tests = 1 << 12;
int maxDegree = 15;
int bits = 128;
Random random;
@Before
public void settings(){
random = new Random();
arr1 = new Polynomial[tests];
arr2 = new Polynomial[tests];
for (int i = 0; i < arr1.length; i++){
arr1[i] = Utils.generateRandomPolynomial(random.nextInt(maxDegree),bits,random);
arr2[i] = Utils.generateRandomPolynomial(random.nextInt(maxDegree),bits,random);
}
}
public void oneTest(Polynomial p1, Polynomial p2){
Polynomial sum = p1.add(p2);
BigInteger x = new BigInteger(bits,random);
assert(sum.image(x).equals(p1.image(x).add(p2.image(x))));
}
@Test
public void addTest(){
for (int i = 0 ; i < arr1.length; i ++){
oneTest(arr1[i],arr2[i]);
}
}
}

View File

@ -0,0 +1,61 @@
package Polynomial;
import ShamirSecretSharing.Polynomial;
import org.junit.Before;
import org.junit.Test;
import java.math.BigInteger;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
/**
* Created by Tzlil on 1/27/2016.
*/
public class InterpolationTest {
Polynomial[] polynomials;
int tests = 1 << 10;
int maxDegree = 15;
int bits = 128;
Random random;
Polynomial.Point[][] pointsArrays;
@Before
public void settings(){
random = new Random();
polynomials = new Polynomial[tests];
pointsArrays = new Polynomial.Point[tests][];
for (int i = 0; i < polynomials.length; i++){
polynomials[i] = Utils.generateRandomPolynomial(random.nextInt(maxDegree),bits,random);
pointsArrays[i] = randomPoints(polynomials[i]);
}
}
public Polynomial.Point[] randomPoints(Polynomial p){
Polynomial.Point[] points = new Polynomial.Point[p.getDegree() + 1];
BigInteger x;
Boolean b;
Set<BigInteger> set = new HashSet();
for (int i = 0; i < points.length; i++){
x = new BigInteger(bits,random);
if(set.contains(x)){
i--;
continue;
}
set.add(x);
points[i] = new Polynomial.Point(x,p.image(x));
}
return points;
}
public void oneTest(Polynomial p, Polynomial.Point[] points){
Polynomial interpolation = Polynomial.interpolation(points);
assert (p.isEquals(interpolation));
}
@Test
public void interpolationTest(){
for (int i = 0; i < polynomials.length; i ++){
oneTest(polynomials[i],pointsArrays[i]);
}
}
}

View File

@ -0,0 +1,46 @@
package Polynomial;
import ShamirSecretSharing.Polynomial;
import org.junit.Before;
import org.junit.Test;
import java.math.BigInteger;
import java.util.Random;
/**
* Created by Tzlil on 1/27/2016.
*/
public class MulByConstTest {
Polynomial[] arr1;
BigInteger[] arr2;
int tests = 1 << 12;
int maxDegree = 15;
int bits = 128;
Random random;
@Before
public void settings(){
random = new Random();
arr1 = new Polynomial[tests];
arr2 = new BigInteger[tests];
for (int i = 0; i < arr1.length; i++){
arr1[i] = Utils.generateRandomPolynomial(random.nextInt(maxDegree),bits,random);
arr2[i] = new BigInteger(bits,random);
}
}
public void oneTest(Polynomial p, BigInteger c){
Polynomial product = p.mul(c);
BigInteger x = new BigInteger(bits,random);
assert(product.image(x).equals(p.image(x).multiply(c)));
}
@Test
public void mulByConstTest(){
for (int i = 0 ; i < arr1.length; i ++){
oneTest(arr1[i],arr2[i]);
}
}
}

View File

@ -0,0 +1,46 @@
package Polynomial;
import ShamirSecretSharing.Polynomial;
import org.junit.Before;
import org.junit.Test;
import java.math.BigInteger;
import java.util.Random;
/**
* Created by Tzlil on 1/27/2016.
*/
public class MulTest {
Polynomial[] arr1;
Polynomial[] arr2;
int tests = 1 << 12;
int maxDegree = 15;
int bits = 128;
Random random;
@Before
public void settings(){
random = new Random();
arr1 = new Polynomial[tests];
arr2 = new Polynomial[tests];
for (int i = 0; i < arr1.length; i++){
arr1[i] = Utils.generateRandomPolynomial(random.nextInt(maxDegree),bits,random);
arr2[i] = Utils.generateRandomPolynomial(random.nextInt(maxDegree),bits,random);
}
}
public void oneTest(Polynomial p1, Polynomial p2){
Polynomial product = p1.mul(p2);
BigInteger x = new BigInteger(bits,random);
assert(product.image(x).equals(p1.image(x).multiply(p2.image(x))));
}
@Test
public void mulTest(){
for (int i = 0 ; i < arr1.length; i ++){
oneTest(arr1[i],arr2[i]);
}
}
}

View File

@ -0,0 +1,21 @@
package Polynomial;
import ShamirSecretSharing.Polynomial;
import java.math.BigInteger;
import java.util.Random;
/**
* Created by Tzlil on 1/27/2016.
*/
public class Utils {
public static Polynomial generateRandomPolynomial(int degree,int bits,Random random) {
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]
}
return new Polynomial(coefficients);
}
}