package threshold.mr04; import static threshold.mr04.Util.compressPoint; import static threshold.mr04.Util.randomFromZn; import static threshold.mr04.Util.randomFromZnStar; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.asn1.sec.SECNamedCurves; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.math.ec.ECPoint; import threshold.mr04.Alice; import threshold.mr04.Bob; import threshold.mr04.Paillier; import threshold.mr04.PaillierPublicKey; import threshold.mr04.Util; import threshold.mr04.benchmarking.Proofs; import threshold.mr04.data.*; public class SignatureTest { // curve initialization from bitcoinj public static final ECDomainParameters CURVE; public static final BigInteger q; public static final ECPoint G; public BigInteger privateKey; public BigInteger aliceShare; public BigInteger bobShare; public SecureRandom rand = new SecureRandom(); public PaillierPublicKey alicesPallierPubKey; public PaillierPublicKey otherPallierPubKey; public int kPrime = 2500; // from paiilier BigInteger N; BigInteger Nsquared; BigInteger g; //from other paillier BigInteger NPrime; BigInteger nPrimeSquared; BigInteger gPrime; //known by alice only--the random values used for the ciphertexts BigInteger r1; BigInteger r2; //known only by bob BigInteger rPrime1; BigInteger rPrime2; BigInteger uPrime; //for zkp1 public BigInteger nHat; public BigInteger h1; public BigInteger h2; public byte[] publicKey; public Paillier paillier; static { X9ECParameters params = SECNamedCurves.getByName("secp256k1"); CURVE = new ECDomainParameters(params.getCurve(), params.getG(), params.getN(), params.getH()); q = params.getN(); G = CURVE.getG(); } public SignatureTest(int t) { /* paillier = new Paillier(256 * (3 * t + 3) + 1, 100); N = paillier.n; g = paillier.g; */ paillier = new Paillier(256 * (3 * t + 3) + 1, 100); do { privateKey = new BigInteger(256, rand); } while (privateKey.compareTo(q) != -1); do { aliceShare = new BigInteger(256, rand); } while (aliceShare.compareTo(q) != -1); bobShare = privateKey.multiply(aliceShare.modInverse(q)).mod(q); publicKey = compressPoint(G.multiply(privateKey), CURVE).getEncoded(); N = paillier.n; Nsquared = paillier.nSquared; g = paillier.g; NPrime = N; nPrimeSquared = Nsquared; gPrime = g; alicesPallierPubKey = new PaillierPublicKey(N, g); otherPallierPubKey = new PaillierPublicKey(NPrime, gPrime); BigInteger p; BigInteger q; BigInteger pPrime; BigInteger qPrime; BigInteger pPrimeqPrime; // test values generated once p = new BigInteger( "17271679500853259237907722112751090572344800097015650067978430270487273362948741147217221813745737065180756833730757525261462768665613913991131866427719227116416050757312058537669863033032226737303616055612946759317498902390429962641420385908878962752920616873839178969530873172616563238953946312567371782591332025913655844884298189560341459584575856552380036842708310909041007"); q = new BigInteger( "13679349955941400890712354406298795275148106390181318180078538082105703681760410189143971341297852299262662291675627451676813043044062128463388674582632527760707881341179231681719822452194383803410464575649942094118927642199654813323117910392205153242518651987825467217332192201895032548164952095659406396661838348254559489136525332853888735013679714339724169847186090393923859"); nHat = p.multiply(q); pPrime = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); qPrime = q.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); pPrimeqPrime = pPrime.multiply(qPrime); nHat = new BigInteger( "236265348219031028683877903779794583288133448965189876633172199463965937811734525033886348183516464403767263317068502789995146148476597858603529345098222167037074791697475407133100492052420936164017066989044809778683277508981350909365181664384969506055989949161038910237490286231913220898888898550119944346304287939272439092448425173582810085209210330872274174796291879141154264344024567264311257082458994017914690811934028317106440081424569441620446616120508191186105218521858324295862764641813408141323916415583638438889085203928556051826507935182374079848700614782735015373342034690531915817024516827597964967251650856472951391789020213816437502823052104436682903113920471066679858792706111846416415108340535853752521173567367174813214653861466686013"); h2 = randomFromZnStar(nHat, rand); BigInteger x = randomFromZn(pPrimeqPrime, rand); h1 = h2.modPow(x, nHat); } public static PublicParameters generateParamsforBitcoin(int k, int kPrime, SecureRandom rand, PaillierPublicKey alicesPaillierPubKey) { X9ECParameters params = SECNamedCurves.getByName("secp256k1"); ECDomainParameters CURVE = new ECDomainParameters(params.getCurve(), params.getG(), params.getN(), params.getH()); Paillier otherPaillier = new Paillier(kPrime, k); PaillierPublicKey otherPaillierPubKey = new PaillierPublicKey(otherPaillier.n, otherPaillier.g); int primeCertainty = k; BigInteger p; BigInteger q; BigInteger pPrime; BigInteger qPrime; BigInteger pPrimeqPrime; BigInteger nHat; do { p = new BigInteger(kPrime / 2, primeCertainty, rand); } while (!p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)) .isProbablePrime(primeCertainty)); pPrime = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); do { q = new BigInteger(kPrime / 2, primeCertainty, rand); } while (!q.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)) .isProbablePrime(primeCertainty)); qPrime = q.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2)); // generate nhat. the product of two safe primes, each of length kPrime/2 nHat = p.multiply(q); BigInteger h2 = randomFromZnStar(nHat, rand); pPrimeqPrime = pPrime.multiply(qPrime); BigInteger x = randomFromZn(pPrimeqPrime, rand); BigInteger h1 = h2.modPow(x, nHat); return new PublicParameters(CURVE, nHat, kPrime, h1, h2, alicesPaillierPubKey, otherPaillierPubKey); }; public static void main(String[] args) { int times = 7; BigInteger m3 = null; BigInteger alpha = null; for (int i = 2; i <= 20; i++) { if (i == 2) { SignatureTest t = new SignatureTest(i); SecureRandom rand = new SecureRandom(); alpha = randomFromZn(q.pow(3), rand); PaillierPublicKey alicesPaillierPubKey = t.alicesPallierPubKey; BigInteger N = alicesPaillierPubKey.N; BigInteger alphaIminus1 = randomFromZn(q.pow(i), rand); BigInteger r3 = randomFromZn(N, rand); m3 = Paillier.encrypt(alphaIminus1, alicesPaillierPubKey,r3); } Paillier paillier = new Paillier(256 * (3 * i + 3) + 1, 100); BigInteger nSquared = paillier.n.pow(2); long startTime = System.nanoTime(); BigInteger v3 = m3.modPow(alpha, nSquared); System.out.println((System.nanoTime() - startTime)); // Alice alice = new Alice(t.aliceShare, t.publicKey, new SecureRandom(), t.paillier, params); // Bob bob = new Bob(t.bobShare, t.publicKey, t.rand, params); // byte[] message = new byte[] { 1, 2, 4, 3 }; // Proofs p = new Proofs(t.publicKey, new SecureRandom(), params); // p.zkpI(1); } // Round1Message r1m = alice.aliceToBobRound1(message); // Round2Message r2m = bob.bobToAliceRound2(r1m); // Round3Message r3m = alice.aliceToBobRound3(r2m); // Round4Message r4m = bob.bobToAliceRound4(r3m); // BigInteger[] sig = alice.aliceOutput(r4m); // // System.out.println(Util.verifySignature(message, sig[0], sig[1], t.publicKey, CURVE)); // // for (int i = 2; i <= times - 1; i++) { // long startTime = System.nanoTime(); // p.zkpI(i - 1); // System.out.println("Proof " + i + ": " + (System.nanoTime() - startTime)); // } } }