false if the user is not found in the record.
- */
- public boolean disqualifyUser(int user) {
- return usersMap.remove(user) == null;
-
- }
-
- public int getNQulaifiedUsers() {
- return usersMap.size();
- }
-
- /**
- * Set the l2 norm proof for the given user.
- * @param user The user index.
- * @param proof The proof to set.
- * @return true if the user is sucessfuly updated.
- * false if the user is not found in the record.
- */
- public boolean setProof(int user, UserVector2.L2NormBoundProof2 proof) {
- UserInfo userInfo = usersMap.get(user);
- if(userInfo == null)
- return false;
- userInfo.setProof(proof);
- return true;
- }
-
- /**
- * Sets Y for the given user.
- * @param user The user index.
- * @param Y_commitments_to_peer_share_of_checksum The commitments to the peer's share of the checksums
- * @return true if the user is sucessfuly updated.
- * false if the user is not found in the record.
- */
- public boolean setY(int user, BigInteger[] Y_commitments_to_peer_share_of_checksum) {
- UserInfo userInfo = usersMap.get(user);
- if(userInfo == null)
- return false;
-
- userInfo.setY(Y_commitments_to_peer_share_of_checksum);
- return true;
- }
-
- /**
- * Generates challenge vectors.
- */
- public void generateChallengeVectors() {
- // byte[] randBytes = new byte[(int)Math.ceil(2*N*m/8)];
- byte[] randBytes = new byte[2*((int)Math.ceil(Num_cs_to_server_ZKP_iteration*dimension_Ser/8)+1)];
- int[] idjRShift3s = new int[dimension_Ser];
- // We need twice the random bits in challenge_vectors_Ser. We need half of them to flip the 1's
- Util.rand.nextBytes(randBytes);
- int mid = randBytes.length/2;
- //// //// //// //// //// //// ///// challenger //// //// //// //// //// //// //// //// //// ////
- final_CVs = new int[Num_cs_to_server_ZKP_iteration][];
- //// //// //// //// ////\\\
-
-
- int bIndex_R3 = 0;
- // challenge vector in P4PServer.java
- // idj=i*dimension_Ser + j
- int idj = 0;
- int[] idj_arr = new int[dimension_Ser];
-
- // (i*dimension_Ser + j)%8
- int idjM8 = 0;
- int[] offset_idjM8_arr = new int[dimension_Ser];
-
- // 1<+ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: - *
+ * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - *
+ * notice, this list of conditions and the following disclaimer. + * * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - *
+ * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * 3. The name of the University may not be used to endorse or promote products - * derived from this software without specific prior written permission. - *
+ * derived from this software without specific prior written permission. + * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -29,24 +29,23 @@ * SUCH DAMAGE. */ -package p4p.bench; +package io.grpc.examples.p4p.p4p.bench; import java.math.BigInteger; import java.security.SecureRandom; -import java.util.Vector; -import net.i2p.util.NativeBigInteger; +import io.grpc.examples.p4p.net.i2p.util.NativeBigInteger; -import p4p.util.Util; -import p4p.util.StopWatch; -import p4p.util.P4PParameters; -import p4p.crypto.SquareCommitment; -import p4p.crypto.Proof; -import p4p.crypto.BitCommitment; -import p4p.crypto.Commitment; +import io.grpc.examples.p4p.p4p.util.Util; +import io.grpc.examples.p4p.p4p.util.StopWatch; +import io.grpc.examples.p4p.p4p.util.P4PParameters; +import io.grpc.examples.p4p.p4p.crypto.SquareCommitment; +import io.grpc.examples.p4p.p4p.crypto.Proof; +import io.grpc.examples.p4p.p4p.crypto.BitCommitment; +import io.grpc.examples.p4p.p4p.crypto.Commitment; -import p4p.user.UserVector; +import io.grpc.examples.p4p.p4p.user.UserVector; /** * Changes: @@ -58,8 +57,8 @@ /** * * This is essentailly the same class as user.UserVector2 as of reversion r15 (until 12/08/2005). - * As an initial implementation, it only implemented the basic crypographic tools, no real - * computation. It is good as a benchmarking tool since it contains all the expensive crypto + * As an initial implementation, it only implemented the basic crypographic tools, no real + * computation. It is good as a benchmarking tool since it contains all the expensive crypto * steps. It is moved to this package to preserve the banchmarking capability. Real development * will go on in the user package. * @@ -86,7 +85,7 @@ public class UserVector2Bench extends UserVector { public UserVector2Bench(long[] data, long F, int l, NativeBigInteger g, NativeBigInteger h) { super(data, F, l); - this.g = g; + this. g = g; this.h = h; sc = new SquareCommitment(g, h); } @@ -95,8 +94,8 @@ public UserVector2Bench(long[] data, long F, int l, NativeBigInteger g, NativeBi /** * A zero-knowledge proof that the vector L2 norm is bounded by L. *
- * This proof uses another method. Namely instead of checking each checksum individually
- * it checks the sum of their squares. This still gives the bound but uses fewer bit
+ * This proof uses another method. Namely instead of checking each checksum individually
+ * it checks the sum of their squares. This still gives the bound but uses fewer bit
* commitment proofs. Note that the challenge vectors are chosen from {-1, 0, 1}.
*/
public class L2NormBoundProof2 extends Proof {
@@ -108,11 +107,11 @@ public class L2NormBoundProof2 extends Proof {
// Construct the ZKP that the commitment contains a bit
public void construct() {
- if (checkCoVector == null)
+ if(c == null)
throw new RuntimeException("Checksum vector not set yet.");
- checksums = new long[checkCoVector.length];
- scProofs = new SquareCommitment.SquareCommitmentProof[checkCoVector.length];
+ checksums = new long[c.length];
+ scProofs = new SquareCommitment.SquareCommitmentProof[c.length];
SquareCommitment sc = new SquareCommitment(g, h);
// Compute the checksums:
@@ -120,7 +119,7 @@ public void construct() {
BigInteger squareSumCommitment = BigInteger.ONE; // Commitment to the sum of the squares
BigInteger sRandomness = BigInteger.ZERO;
- for (int i = 0; i < checkCoVector.length; i++) {
+ for(int i = 0; i < c.length; i++) {
// checksums[i] = 0;
// for(int j = 0; j < m; j++) {
// //s += c[i][j]*data[j];
@@ -129,7 +128,7 @@ public void construct() {
// else if(c[i][j] == -1)
// checksums[i] -= data[j];
// }
- checksums[i] = Math.abs(Util.innerProduct(checkCoVector[i], data_UV));
+ checksums[i] = Math.abs(Util.innerProduct(c[i], data));
/**
* Note that although all the normal compuations are done in
* a small finite field, we don't restrict the size of the
@@ -143,11 +142,11 @@ public void construct() {
//System.out.println("cs = " + cs);
sc.commit(cs);
- scProofs[i] = (SquareCommitment.SquareCommitmentProof) sc.getProof();
+ scProofs[i] = (SquareCommitment.SquareCommitmentProof)sc.getProof();
- if (debug) {
+ if(debug) {
// lets check here:
- if (!sc.verify(scProofs[i])) {
+ if(!sc.verify(scProofs[i])) {
throw new RuntimeException("Square commitment proof or verification is not working properly. i = " + 1);
}
}
@@ -158,12 +157,12 @@ public void construct() {
sRandomness = sRandomness.add(sc.getSb()).mod(q);
}
- if (debug) {
+ if(debug) {
// Lets verify if we compute the commitment to the sum of squares correcly:
System.out.print("Checking commitment to sum of squares ...");
Commitment cm = new Commitment(g, h);
BigInteger ssc = cm.commit(squareSum, sRandomness);
- if (!ssc.equals(squareSumCommitment)) {
+ if(!ssc.equals(squareSumCommitment)) {
throw new RuntimeException("Commitment to sum of squares wasn't computed correctly!");
}
System.out.println(" done.");
@@ -178,10 +177,10 @@ public void construct() {
squareSumCommitment = squareSumCommitment.multiply(squareSumCommitment).mod(p); // 2x
// Lets check if the commitment was computed correctly:
- if (debug) {
+ if(debug) {
System.out.print("Checking commitment to 2*(sum of squares) ...");
Commitment cm = new Commitment(g, h);
- if (!cm.verify(squareSumCommitment, squareSum, sRandomness))
+ if(!cm.verify(squareSumCommitment, squareSum, sRandomness))
throw new RuntimeException("Commitment to 2*(sum of squares) wasn't computed correctly!");
System.out.println(" done.");
}
@@ -190,19 +189,19 @@ public void construct() {
commitment = new BigInteger[1];
commitment[0] = squareSumCommitment;
-
- int numBits = Math.max(squareSum.bitLength(), Integer.toBinaryString(checkCoVector.length).length() + 2 * l_UV);
+ // 🌟 crux of the test 🌟 //
+ int numBits = Math.max(squareSum.bitLength(), Integer.toBinaryString(c.length).length()+2*l);
// Even for small squares we must do all the commitments otherwise leak info.
DEBUG("squareSum has " + numBits + " bits");
bcProofs = new BitCommitment.BitCommitmentProof[numBits];
BitCommitment bc = new BitCommitment(g, h);
- for (int i = 0; i < numBits - 1; i++) {
+ for(int i = 0; i < numBits - 1; i++) {
BigInteger cc = bc.commit(squareSum.testBit(i));
- bcProofs[i] = (BitCommitment.BitCommitmentProof) bc.getProof();
+ bcProofs[i] = (BitCommitment.BitCommitmentProof)bc.getProof();
- if (debug) {
- if (!cc.equals(bcProofs[i].getCommitment()[0]))
+ if(debug) {
+ if(!cc.equals(bcProofs[i].getCommitment()[0]))
throw new RuntimeException("Bit commitment wasn't computed correctly!");
}
@@ -216,39 +215,39 @@ public void construct() {
// Now the last bit:
// First need to compute the randomness correctly:
// BigInteger e = new BigInteger(new Long(((long)1)<<(numBits-1)).toString()); // 2^l
- BigInteger e = BigInteger.ZERO.setBit(numBits - 1); // 2^l
+ BigInteger e = BigInteger.ZERO.setBit(numBits-1); // 2^l
e = e.modInverse(q);
sRandomness = sRandomness.multiply(e).mod(q); // divide by 2^l
- bc.commit(squareSum.testBit(numBits - 1), sRandomness);
- bcProofs[numBits - 1] = (BitCommitment.BitCommitmentProof) bc.getProof();
+ bc.commit(squareSum.testBit(numBits-1), sRandomness);
+ bcProofs[numBits-1] = (BitCommitment.BitCommitmentProof)bc.getProof();
// Lets check it here:
- if (debug) {
+ if(debug) {
System.out.print("Checking homomorphism ...");
BigInteger ZZ = BigInteger.ONE;
BigInteger z = BigInteger.ZERO;
- for (int i = 0; i < numBits; i++) {
+ for(int i = 0; i < numBits; i++) {
//BigInteger e = new BigInteger(new Long(((long)1)< Integer.toBinaryString(checkCoVector.length).length() + 2 * l_UV) {
+ if(bcProofs.length > Integer.toBinaryString(c.length).length()+2*l) {
System.out.println("Sum of squares has too many bits: " + bcProofs.length
- + ", the limit is " + (Integer.toBinaryString(checkCoVector.length).length() + 2 * l_UV));
+ + ", the limit is " + (Integer.toBinaryString(c.length).length()+2*l));
return false;
}
@@ -310,8 +309,8 @@ public boolean verify2(Proof proof) {
// Check the square proofs:
SquareCommitment sc = new SquareCommitment(g, h);
- for (int i = 0; i < scProofs.length; i++) {
- if (!sc.verify(scProofs[i])) {
+ for(int i = 0; i < scProofs.length; i++) {
+ if(!sc.verify(scProofs[i])) {
System.out.println("Square verification " + i + " failed.");
return false;
}
@@ -320,12 +319,12 @@ public boolean verify2(Proof proof) {
// Now the bit commitment for the sum. First check if the commitment is
// computed correctly:
BigInteger z = BigInteger.ONE;
- for (int i = 0; i < scProofs.length; i++) {
+ for(int i = 0; i < scProofs.length; i++) {
z = z.multiply(scProofs[i].getCommitment()[1]).mod(p); // *= B
}
z = z.multiply(z).mod(p); // commitment[0] actually stores 2X
- if (!l2Proof.getCommitment()[0].equals(z)) {
+ if(!l2Proof.getCommitment()[0].equals(z)) {
System.out.println("Commitment to square sum wasn't computed correctly.");
return false;
}
@@ -337,8 +336,8 @@ public boolean verify2(Proof proof) {
DEBUG("Checking " + bcProofs.length + " bit commitments");
BigInteger ZZ = BigInteger.ONE;
- for (int i = 0; i < bcProofs.length; i++) {
- if (!bc.verify(bcProofs[i])) {
+ for(int i = 0; i < bcProofs.length; i++) {
+ if(!bc.verify(bcProofs[i])) {
System.out.println("Bit commitment verification " + i + " failed.");
return false;
}
@@ -347,11 +346,11 @@ public boolean verify2(Proof proof) {
BigInteger e = BigInteger.ZERO.setBit(i);
// Note that we can't use ((long)1)< 0 && arg.charAt(0) == '-') {
+ if(arg.length() > 0 && arg.charAt(0) == '-') {
if (arg.equals("-k")) {
try {
k = Integer.parseInt(args[i++]);
- } catch (NumberFormatException e) {
+ }
+ catch (NumberFormatException e) {
k = 512;
}
- } else if (arg.equals("-m")) {
+ }
+ else if(arg.equals("-m")) {
try {
m = Integer.parseInt(args[i++]);
- } catch (NumberFormatException e) {
+ }
+ catch (NumberFormatException e) {
m = 10;
}
- } else if (arg.equals("-N")) {
+ }
+ else if(arg.equals("-N")) {
try {
zkpIterations = Integer.parseInt(args[i++]);
- } catch (NumberFormatException e) {
+ }
+ catch (NumberFormatException e) {
zkpIterations = 50;
}
- } else if (arg.equals("-o")) {
+ }
+
+ else if(arg.equals("-o")) {
try {
nLoops = Integer.parseInt(args[i++]);
- } catch (NumberFormatException e) {
+ }
+ catch (NumberFormatException e) {
nLoops = 10;
}
- } else if (arg.equals("-l")) {
+ }
+
+ else if(arg.equals("-l")) {
try {
l = Integer.parseInt(args[i++]);
- } catch (NumberFormatException e) {
+ }
+ catch (NumberFormatException e) {
l = 40;
}
- } else if (arg.equals("-d")) {
+ }
+
+ else if(arg.equals("-d")) {
debug = true;
- } else if (arg.equals("-w")) {
+ }
+ else if(arg.equals("-w")) {
worstcase = true; // test the worst case cost. i.e. every vector should pass. this is when the verifier spends longest time.
- } else if (arg.equals("-bench")) {
+ }
+ else if(arg.equals("-bench")) {
doBench = true;
}
}
@@ -434,7 +448,8 @@ public static void main(String[] args) {
SecureRandom rand = null;
try {
rand = SecureRandom.getInstance("SHA1PRNG");
- } catch (java.security.NoSuchAlgorithmException e) {
+ }
+ catch(java.security.NoSuchAlgorithmException e) {
System.err.println("NoSuchAlgorithmException!");
e.printStackTrace();
rand = new SecureRandom();
@@ -444,8 +459,8 @@ public static void main(String[] args) {
// Lets make l = log_2 (m)
//int l = Math.max(10, (int)Math.ceil(Math.log(m)/Math.log(2.))); // We restrict L to be 32 bits
- long L = ((long) 2) << l - 1;
- long F = BigInteger.probablePrime(l + 10, rand).longValue();
+ long L = ((long)2)<
* NOTE: This class is not used in the new version of the L2-norm ZKP
- * (implemented in {@link p4p.user.UserVector2}) and is not being maintained.
+ * (implemented in {@link UserVector2}) and is not being maintained.
*
*
* @author ET 08/30/2005
@@ -25,11 +25,11 @@
public class BitVectorCommitment extends VectorCommitment {
// The bit vector
boolean[] bitVec = null;
-
+
public BitVectorCommitment(NativeBigInteger g[], NativeBigInteger h) {
super(g, h);
}
-
+
/**
* Override this method to prevent users from using a BitVectorCommitment
* object to commit to non-bit vectors. Since all commit calls in
@@ -37,9 +37,9 @@ public BitVectorCommitment(NativeBigInteger g[], NativeBigInteger h) {
* them all here.
*/
protected BigInteger vectorCommit(BigInteger[] vals, BigInteger r) {
- if(vals.length != N)
+ if(vals.length != N)
throw new RuntimeException("Incorrect dimension!");
-
+
BigInteger c = h.modPow(r, p);
for(int i = 0; i < N; i++) {
if(vals[i].equals(BigInteger.ZERO))
@@ -49,33 +49,33 @@ else if(vals[i].equals(BigInteger.ONE))
else
throw new RuntimeException("Can only commit to bits!");
}
-
+
return c;
}
-
+
/**
* Given a matrix of bits, commit to a column specified by the
* 2nd argument. The columns are numbered 0, 1, 2, ..., starting
* from the LSB. Note that col specifies the position of ``bit'',
* not ``byte''.
*/
-
+
public BigInteger commit(byte[][] bits, int col) {
r = Util.randomBigInteger(q);
return commit(bits, col, r);
}
-
+
public BigInteger commit(byte[][] bits, int col, BigInteger r) {
- if(bits.length != N)
+ if(bits.length != N)
throw new RuntimeException("Incorrect dimension!");
-
+
int byteIndex = col/8; // Which byte this bit belongs to
int offset = col%8; // The offset within this byte. Starting from right
-
+
if(col < 0 || byteIndex > bits[0].length) return null;
-
+
bitVec = new boolean[N]; // Number of rows is the size of the bit vector
-
+
BigInteger c = h.modPow(r, p);
for(int i = 0; i < N; i++) {
if((bits[i][byteIndex] & (1<
@@ -55,46 +53,47 @@
public class Commitment extends P4PParameters {
protected NativeBigInteger g = null;
protected NativeBigInteger h = null;
-
+
/**
* verify that the parameters are correct.
*/
-
+
public void sanityCheck() {
if(!g.modPow(q, p).equals(BigInteger.ONE))
throw new IllegalArgumentException("g does not have the correct order!");
-
+
if(!h.modPow(q, p).equals(BigInteger.ONE))
throw new IllegalArgumentException("h does not have the correct order!");
}
-
+
// The committer:
-
- /**
+
+ /**
* The value to be committed to.
*/
- protected BigInteger val = null;
+ protected BigInteger val = null;
- /**
+ /**
* The randomness used in the commitment.
*/
- protected BigInteger r = null;
-
+ protected BigInteger r = null;
+
/**
*/
public Commitment(NativeBigInteger g, NativeBigInteger h) {
this.g = g;
this.h = h;
- sanityCheck();
+ sanityCheck();
}
/**
* Compute the commitment using the given value and randomness.
* Make this method final to prevent subclass from overiding it.
*/
- protected final BigInteger computeCommitment(BigInteger val,
+ protected final BigInteger computeCommitment(BigInteger val,
BigInteger r) {
//BigInteger rr = r.mod(q);
+
if(val.equals(BigInteger.ONE))
return g.multiply(h.modPow(r, p)).mod(p);
else if (val.equals(BigInteger.ZERO))
@@ -108,12 +107,12 @@ else if (val.equals(BigInteger.ZERO))
//return g.modPow(val, p).multiply(h.modPow(r, p)).mod(p);
return g.modPow(val.mod(q), p).multiply(h.modPow(r, p)).mod(p);
}
-
+
/**
* Commit to a long
*/
-
+
public BigInteger commit(long val) {
return commit(new BigInteger(new Long(val).toString()));
}
@@ -121,7 +120,7 @@ public BigInteger commit(long val) {
/**
* Commit to a number in Z_q
*/
-
+
public BigInteger commit(BigInteger val) {
r = Util.randomBigInteger(q);
this.val = val;
@@ -135,11 +134,11 @@ public BigInteger commit(BigInteger val) {
/**
* Commit to a number in Z_q using the given randomness
*/
-
+
public BigInteger commit(BigInteger val, BigInteger r) {
this.r = r.mod(q);
this.val = val;
-
+
return computeCommitment(this.val, this.r);
}
@@ -150,7 +149,7 @@ public BigInteger commit(BigInteger val, BigInteger r) {
public BigInteger getRandomness() {
return r;
}
-
+
/**
* Return the vector contained in this commitment
*/
@@ -158,7 +157,7 @@ public BigInteger getValue() {
return val;
}
-
+
// The verifier:
/**
* Verify if the given triple consist a valid commitment using the
diff --git a/src/java/p4p/crypto/Proof.java b/src/main/java/io/grpc/examples/p4p/p4p/crypto/Proof.java
similarity index 95%
rename from src/java/p4p/crypto/Proof.java
rename to src/main/java/io/grpc/examples/p4p/p4p/crypto/Proof.java
index 41d1871..4e3ce3b 100644
--- a/src/java/p4p/crypto/Proof.java
+++ b/src/main/java/io/grpc/examples/p4p/p4p/crypto/Proof.java
@@ -1,7 +1,7 @@
/**
* Copyright (c) 2007 Regents of the University of California.
* All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -29,15 +29,14 @@
* SUCH DAMAGE.
*/
-package p4p.crypto;
+package io.grpc.examples.p4p.p4p.crypto;
import java.math.BigInteger;
-import java.security.SecureRandom;
-import p4p.util.P4PParameters;
+import io.grpc.examples.p4p.p4p.util.P4PParameters;
/**
- *
+ *
* This is an abstract 3-round (a.k.a $\Sigma$) proof consisting of 3 rounds:
*
* Prover -> Verifier: commitment
@@ -51,7 +50,7 @@
public abstract class Proof extends P4PParameters {
- protected BigInteger[] commitment = null;
+ protected BigInteger[] commitment = null;
/**
* This is the first message in a 3-round proof. The prover ``commits''
* to her data using some kind of commitment scheme. This is essentially
@@ -71,7 +70,7 @@ public abstract class Proof extends P4PParameters {
public Proof() {}
- public Proof(BigInteger[] commitment, BigInteger[] challenge,
+ public Proof(BigInteger[] commitment, BigInteger[] challenge,
BigInteger[] response) {
this.commitment = commitment;
this.challenge = challenge;
@@ -81,12 +80,12 @@ public Proof(BigInteger[] commitment, BigInteger[] challenge,
public BigInteger[] getCommitment() { return commitment; }
public BigInteger[] getChallenge() { return challenge; }
public BigInteger[] getResponse() { return response; }
-
+
/**
* Construct the proof. This should be overriden by subclasses.
*/
public abstract void construct();
-
+
/**
* Verify the proof. To be overriden by subclasses.
*/
diff --git a/src/java/p4p/crypto/SquareCommitment.java b/src/main/java/io/grpc/examples/p4p/p4p/crypto/SquareCommitment.java
similarity index 78%
rename from src/java/p4p/crypto/SquareCommitment.java
rename to src/main/java/io/grpc/examples/p4p/p4p/crypto/SquareCommitment.java
index 8ee9087..36663e4 100644
--- a/src/java/p4p/crypto/SquareCommitment.java
+++ b/src/main/java/io/grpc/examples/p4p/p4p/crypto/SquareCommitment.java
@@ -1,7 +1,7 @@
/**
* Copyright (c) 2007 Regents of the University of California.
* All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -29,21 +29,18 @@
* SUCH DAMAGE.
*/
-package p4p.crypto;
+package io.grpc.examples.p4p.p4p.crypto;
import java.math.BigInteger;
-import java.security.SecureRandom;
-import java.security.MessageDigest;
import java.security.GeneralSecurityException;
-import net.i2p.util.NativeBigInteger;
-
-import p4p.util.Util;
-import p4p.util.StopWatch;
-import p4p.util.P4PParameters;
+import io.grpc.examples.p4p.p4p.util.P4PParameters;
+import io.grpc.examples.p4p.p4p.util.StopWatch;
+import io.grpc.examples.p4p.p4p.util.Util;
+import io.grpc.examples.p4p.net.i2p.util.NativeBigInteger;
/**
- *
+ *
* Given two numbers, a and b with b = a^2 mod q, produces two commitments s.t.
* A = C(a), B = C(b) and a ZKP that proves, in zero-knowledge, that the
* the number contained in B is the square of the number contained in A.
@@ -93,10 +90,10 @@ public class SquareCommitment extends Commitment {
private BigInteger a = null;
private BigInteger b = null;
private NativeBigInteger A = null;
- private NativeBigInteger B = null;
+ private NativeBigInteger B = null;
private BigInteger sa = null;
private BigInteger sb = null;
-
+
public SquareCommitment(NativeBigInteger g, NativeBigInteger h) {
super(g, h);
}
@@ -112,13 +109,13 @@ public BigInteger commit(BigInteger val) {
a = val; // Must take mod q
A = new NativeBigInteger(super.commit(a));
sa = getRandomness();
- b = a.multiply(a).mod(q);
+ b = a.multiply(a).mod(P4PParameters.q);
B = new NativeBigInteger(super.commit(b));
sb = getRandomness();
-
+
return A;
}
-
+
/**
* Commits to
@@ -247,15 +244,15 @@ public boolean verify(Proof proof) {
BigInteger[] c = proof.getCommitment();
BigInteger[] s = proof.getChallenge();
BigInteger[] r = proof.getResponse();
-
+
if(c.length != 4 || s.length != 1 || r.length != 3)
return false;
-
+
return verify(c[0], c[1], c[2], c[3], s[0], r[0], r[1], r[2]);
}
-
- private boolean verify(BigInteger A, BigInteger B, BigInteger Ca,
- BigInteger Cb, BigInteger c, BigInteger v,
+
+ private boolean verify(BigInteger A, BigInteger B, BigInteger Ca,
+ BigInteger Cb, BigInteger c, BigInteger v,
BigInteger za, BigInteger zb) {
// Also need to verify the hash
BigInteger[] msg = new BigInteger[4];
@@ -263,9 +260,9 @@ private boolean verify(BigInteger A, BigInteger B, BigInteger Ca,
msg[1] = B;
msg[2] = Ca;
msg[3] = Cb;
-
+
try {
- if(!c.equals(Util.secureHash(msg, q))) {
+ if(!c.equals(Util.secureHash(msg, P4PParameters.q))) {
System.out.println("Challenge is not equal to the hash!");
return false;
}
@@ -275,26 +272,26 @@ private boolean verify(BigInteger A, BigInteger B, BigInteger Ca,
e.printStackTrace();
return false;
}
-
-
+
+
// Pass 1: g^v*h^za = A^c*Ca mod p?
- if(!g.modPow(v, p).multiply(h.modPow(za, p)).mod(p)
- .equals(A.modPow(c, p).multiply(Ca).mod(p))) {
+ if(!g.modPow(v, P4PParameters.p).multiply(h.modPow(za, P4PParameters.p)).mod(P4PParameters.p)
+ .equals(A.modPow(c, P4PParameters.p).multiply(Ca).mod(P4PParameters.p))) {
System.out.println("Pass 1: g^v*h^za = A^c*Ca mod p failed.");
return false;
}
-
+
// Pass 2: A^v*h^zb = B^c*Cb mod p?
- BigInteger vv = Cb.multiply(B.modPow(c, p)).mod(p);
- if(!vv.equals(A.modPow(v, p).multiply(h.modPow(zb, p)).mod(p))) {
+ BigInteger vv = Cb.multiply(B.modPow(c, P4PParameters.p)).mod(P4PParameters.p);
+ if(!vv.equals(A.modPow(v, P4PParameters.p).multiply(h.modPow(zb, P4PParameters.p)).mod(P4PParameters.p))) {
System.out.println("Pass 2: A^v*h^zb = B^c*Cb mod p failed.");
return false;
}
-
+
return true;
}
-
+
/**
* Test the SquareCommitment and the ZKP
@@ -302,14 +299,14 @@ private boolean verify(BigInteger A, BigInteger B, BigInteger Ca,
public static void main(String[] args) {
int k = 512;
int nLoops = 10;
-
+
for (int i = 0; i < args.length; ) {
String arg = args[i++];
if(arg.length() > 0 && arg.charAt(0) == '-') {
if (arg.equals("-k")) {
try {
k = Integer.parseInt(args[i++]);
- }
+ }
catch (NumberFormatException e) {
k = 512;
}
@@ -317,17 +314,17 @@ public static void main(String[] args) {
else if(arg.equals("-l")) {
try {
nLoops = Integer.parseInt(args[i++]);
- }
+ }
catch (NumberFormatException e) {
nLoops = 10;
}
}
else if(arg.equals("-d")) {
- debug = true;
+ P4PParameters.debug = true;
}
}
}
-
+
// Setup the parameters:
P4PParameters.initialize(k, false);
NativeBigInteger g = P4PParameters.getGenerator();
@@ -337,28 +334,28 @@ else if(arg.equals("-d")) {
SquareCommitment sc = new SquareCommitment(g, h);
SquareCommitment verifier = new SquareCommitment(g, h);
// Construct a new SquareCommitment to verify.
-
- System.out.println("Testing SquareCommitment for " + nLoops + " loops .");
+
+ System.out.println("Testing SquareCommitment for " + nLoops + " loops .");
StopWatch proverWatch = new StopWatch();
StopWatch verifierWatch = new StopWatch();
long start = System.currentTimeMillis();
for(int j = 0; j < nLoops; j++) {
- BigInteger a = Util.randomBigInteger(q);
- BigInteger r = Util.randomBigInteger(q);
+ BigInteger a = Util.randomBigInteger(P4PParameters.q);
+ BigInteger r = Util.randomBigInteger(P4PParameters.q);
sc.commit(a.negate(), r);
//sc.commit(a, r);
-
+
// Test the ZKP:
System.out.print("Testing square commitment ZKP ...");
proverWatch.start();
SquareCommitmentProof proof = (SquareCommitmentProof)sc.getProof();
proverWatch.pause();
-
+
verifierWatch.start();
if(!sc.verify(proof))
- System.out.println("ZKP failed for test " + j
- + ". Should have passed.");
- // how do we test failed zkp?
+ System.out.println("ZKP failed for test " + j
+ + ". Should have passed.");
+ // how do we test failed zkp?
else
System.out.println(" passed");
verifierWatch.pause();
@@ -366,19 +363,19 @@ else if(arg.equals("-d")) {
verifierWatch.stop();
proverWatch.stop();
long end = System.currentTimeMillis();
- System.out.println("Square commitment ZKP: " + nLoops
- + " loops. ms per loop:");
+ System.out.println("Square commitment ZKP: " + nLoops
+ + " loops. ms per loop:");
System.out.println("\n Prover time Verifier time Total");
System.out.println("===================================================");
- System.out.println(" "
- + (double)proverWatch.getElapsedTime()/(double)nLoops
- + " "
- + (double)verifierWatch.getElapsedTime()/(double)nLoops
- + " "
- + (double)(proverWatch.getElapsedTime()+verifierWatch
- .getElapsedTime())/(double)nLoops);
-
-
-
+ System.out.println(" "
+ + (double)proverWatch.getElapsedTime()/(double)nLoops
+ + " "
+ + (double)verifierWatch.getElapsedTime()/(double)nLoops
+ + " "
+ + (double)(proverWatch.getElapsedTime()+verifierWatch
+ .getElapsedTime())/(double)nLoops);
+
+
+
}
}
diff --git a/src/java/p4p/crypto/ThreeWayCommitment.java b/src/main/java/io/grpc/examples/p4p/p4p/crypto/ThreeWayCommitment.java
similarity index 84%
rename from src/java/p4p/crypto/ThreeWayCommitment.java
rename to src/main/java/io/grpc/examples/p4p/p4p/crypto/ThreeWayCommitment.java
index 0cdc59c..f048ff3 100644
--- a/src/java/p4p/crypto/ThreeWayCommitment.java
+++ b/src/main/java/io/grpc/examples/p4p/p4p/crypto/ThreeWayCommitment.java
@@ -1,7 +1,7 @@
/**
* Copyright (c) 2007 Regents of the University of California.
* All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -29,19 +29,16 @@
* SUCH DAMAGE.
*/
-package p4p.crypto;
+package io.grpc.examples.p4p.p4p.crypto;
import java.math.BigInteger;
import java.security.SecureRandom;
-import java.security.MessageDigest;
-import java.security.GeneralSecurityException;
-
-import net.i2p.util.NativeBigInteger;
-import p4p.util.Util;
-import p4p.util.StopWatch;
-import p4p.util.P4PParameters;
+import io.grpc.examples.p4p.p4p.util.P4PParameters;
+import io.grpc.examples.p4p.p4p.util.StopWatch;
+import io.grpc.examples.p4p.p4p.util.Util;
+import io.grpc.examples.p4p.net.i2p.util.NativeBigInteger;
/**
* A 3-Way commitment is a commitment that contains one of three values
@@ -64,7 +61,7 @@
public class ThreeWayCommitment extends Commitment {
public final NativeBigInteger CONST; // The public constant
-
+
public ThreeWayCommitment(NativeBigInteger g, NativeBigInteger h,
BigInteger c) {
super(g, h);
@@ -76,44 +73,44 @@ public ThreeWayCommitment(NativeBigInteger g, NativeBigInteger h,
super(g, h);
this.CONST = new NativeBigInteger(new BigInteger(String.valueOf(c)).abs());
}
-
+
/**
*/
public BigInteger commit(BigInteger val) {
if(!val.equals(BigInteger.ZERO) && !val.equals(CONST)
- && !val.equals(CONST.negate()))
- throw new RuntimeException("ThreeWayCommitment.commit can only"
- + "be invoked with 0 or +/-" + CONST);
+ && !val.equals(CONST.negate()))
+ throw new RuntimeException("ThreeWayCommitment.commit can only"
+ + "be invoked with 0 or +/-" + CONST);
return super.commit(val);
// Commitment is smart enough to avoid doing
// exponetiation if val is either 0 or 1.
}
-
+
/**
- */
+ */
public BigInteger commit(long val) {
long c = CONST.longValue();
if(val != 0 && val != c && val != -c)
- throw new RuntimeException("ThreeWayCommitment.commit can only"
- + "be invoked with 0 or +/-" + c);
-
+ throw new RuntimeException("ThreeWayCommitment.commit can only"
+ + "be invoked with 0 or +/-" + c);
+
return super.commit(new BigInteger(String.valueOf(val)));
// Commitment is smart enough to avoid doing exponetiation
// if val is either 0 or 1.
}
-
+
public BigInteger commit(long val, BigInteger r) {
long c = CONST.longValue();
if(val != 0 && val != c && val != -c)
- throw new RuntimeException("ThreeWayCommitment.commit can only"
- + "be invoked with 0 or +/-" + c);
-
+ throw new RuntimeException("ThreeWayCommitment.commit can only"
+ + "be invoked with 0 or +/-" + c);
+
return super.commit(new BigInteger(String.valueOf(val)), r);
// Commitment is smart enough to avoid doing exponetiation
// if val is either 0 or 1.
}
-
-
+
+
// The verifier:
/**
* Verify if the given bit val is contained in the commitment
@@ -115,7 +113,7 @@ public BigInteger commit(boolean val, BigInteger r) {
public boolean verify(BigInteger c, BigInteger val, BigInteger r) {
if(!val.equals(BigInteger.ZERO) && !val.equals(BigInteger.ONE))
return false;
-
+
return super.verify(c, val, r);
}
@@ -127,10 +125,10 @@ public Proof getProof() {
// f(r) = h^r. The onw way group homomorphism
public BigInteger f(BigInteger i){
- return h.modPow(i, p);
+ return h.modPow(i, P4PParameters.p);
}
-
-
+
+
/**
* A zero-knowledge proof that the commitment contains a bit. The protocol
* is based on the f-preimage proof of
@@ -141,15 +139,15 @@ public BigInteger f(BigInteger i){
*/
public class BitCommitmentProof extends Proof {
public BitCommitmentProof() { super(); }
-
+
// Construct the ZKP that the commitment contains a bit
public void construct() {
if(val == null)
- throw new RuntimeException("Must commit to a bit first"
- + "before constructing the proof!");
-
+ throw new RuntimeException("Must commit to a bit first"
+ + "before constructing the proof!");
+
commitment = new BigInteger[3];
- commitment[0] = new NativeBigInteger(commit(val, r));
+ commitment[0] = new NativeBigInteger(commit(val, r));
/**
* The first element is the commitment itself. Note we must use our
* own randomness here since we already committed to a bit.
@@ -158,37 +156,37 @@ public void construct() {
*/
challenge = new BigInteger[1];
response = new BigInteger[4];
-
- BigInteger v = Util.randomBigInteger(q);;
+
+ BigInteger v = Util.randomBigInteger(P4PParameters.q);;
BigInteger e1 = null;
BigInteger z1 = null;
BigInteger e0 = null;
BigInteger z0 = null;
BigInteger m0 = null;
BigInteger m1 = null;
-
+
if(val.equals(BigInteger.ZERO)) {
- e1 = Util.randomBigInteger(q);;
- z1 = Util.randomBigInteger(q);;
+ e1 = Util.randomBigInteger(P4PParameters.q);;
+ z1 = Util.randomBigInteger(P4PParameters.q);;
// calculate m0, m1:
m0 = f(v);
-
+
/**
* Note: NativeBigInteger seems to be unable to handle negative
* exponents properly. We should avoid using
* modPow(e1.negate(), p) before we fix the implementation.
*/
- BigInteger t = (commitment[0].modInverse(p)).modPow(e1, p);
+ BigInteger t = (commitment[0].modInverse(P4PParameters.p)).modPow(e1, P4PParameters.p);
// c^ -e1
- t = t.multiply(g.modPow(e1, p));
- m1 = (t.multiply(f(z1))).mod(p); // f(z1) * c ^ (-e1) * g ^ e1
-
+ t = t.multiply(g.modPow(e1, P4PParameters.p));
+ m1 = (t.multiply(f(z1))).mod(P4PParameters.p); // f(z1) * c ^ (-e1) * g ^ e1
+
commitment[1] = m0;
commitment[2] = m1;
// Get challenge which should be a hash of the commitment:
BigInteger s = null;
try {
- s = Util.secureHash(commitment, q);
+ s = Util.secureHash(commitment, P4PParameters.q);
challenge[0] = s;
}
catch(GeneralSecurityException e) {
@@ -196,43 +194,43 @@ public void construct() {
e.printStackTrace();
}
// Compute response:
- e0 = (s.subtract(e1)).mod(q); //e0 = s - e1;
- z0 = v.add(e0.multiply(r)).mod(q); // v + e0 * r;
+ e0 = (s.subtract(e1)).mod(P4PParameters.q); //e0 = s - e1;
+ z0 = v.add(e0.multiply(r)).mod(P4PParameters.q); // v + e0 * r;
}
else if(val.equals(BigInteger.ONE)) {
- e0 = Util.randomBigInteger(q);;
- z0 = Util.randomBigInteger(q);;
-
+ e0 = Util.randomBigInteger(P4PParameters.q);;
+ z0 = Util.randomBigInteger(P4PParameters.q);;
+
// calculate m0, m1:
m1 = f(v);
- m0 = f(z0).multiply((commitment[0].modInverse(p)).modPow(e0, p));
+ m0 = f(z0).multiply((commitment[0].modInverse(P4PParameters.p)).modPow(e0, P4PParameters.p));
// f(z0) * c ^ (-e0)
-
+
commitment[1] = m0;
commitment[2] = m1;
// Get challenge which should be a hash of the commitment:
BigInteger s = null;
try {
- s = Util.secureHash(commitment, q);
+ s = Util.secureHash(commitment, P4PParameters.q);
challenge[0] = s;
}
catch(GeneralSecurityException e) {
System.err.println("Can't compute hash!");
e.printStackTrace();
}
- e1 = s.subtract(e0).mod(q); //e1 = s - e0;
- z1 = v.add(e1.multiply(r)).mod(q); // v + e1 * r;
+ e1 = s.subtract(e0).mod(P4PParameters.q); //e1 = s - e0;
+ z1 = v.add(e1.multiply(r)).mod(P4PParameters.q); // v + e1 * r;
}
else
- throw new RuntimeException("Not a bit commitment!");
-
+ throw new RuntimeException("Not a bit commitment!");
+
response[0] = e0;
response[1] = e1;
response[2] = z0;
response[3] = z1;
}
}
-
+
/**
* Verifies the given proof using our own parameters.
*
@@ -246,16 +244,16 @@ public boolean verify(Proof proof) {
BigInteger[] c = proof.getCommitment();
BigInteger[] s = proof.getChallenge();
BigInteger[] r = proof.getResponse();
-
+
if(c.length != 3 || s.length != 1 || r.length != 4)
return false;
-
+
return verify(c[0], c[1], c[2], s[0], r[0], r[1], r[2], r[3]);
}
-
- private boolean verify(BigInteger c, BigInteger m0, BigInteger m1,
- BigInteger s, BigInteger e0, BigInteger e1,
+
+ private boolean verify(BigInteger c, BigInteger m0, BigInteger m1,
+ BigInteger s, BigInteger e0, BigInteger e1,
BigInteger z0, BigInteger z1) {
// Also need to verify the hash
@@ -263,9 +261,9 @@ private boolean verify(BigInteger c, BigInteger m0, BigInteger m1,
msg[0] = c;
msg[1] = m0;
msg[2] = m1;
-
+
try {
- if(!s.equals(Util.secureHash(msg, q))) {
+ if(!s.equals(Util.secureHash(msg, P4PParameters.q))) {
System.out.println("Challenge is not equal to the hash!");
return false;
}
@@ -275,36 +273,36 @@ private boolean verify(BigInteger c, BigInteger m0, BigInteger m1,
e.printStackTrace();
return false;
}
-
+
// Pass 1:
- if(!s.equals((e0.add(e1)).mod(q))) {
+ if(!s.equals((e0.add(e1)).mod(P4PParameters.q))) {
System.out.println("Verification failed 1");
return false;
}
-
+
// Pass 2:
- BigInteger vv = (m0.multiply(c.modPow(e0, p))).mod(p); // m0*c ^ e0
+ BigInteger vv = (m0.multiply(c.modPow(e0, P4PParameters.p))).mod(P4PParameters.p); // m0*c ^ e0
if(!f(z0).equals(vv)) {
System.out.println("Verification failed 2");
return false;
}
-
+
// Pass 3;
//NativeBigInteger nvv = new NativeBigInteger(bit_c.multiply(g.modInverse(p)));
- NativeBigInteger nvv =
- new NativeBigInteger(c.multiply(g.modInverse(p)).mod(p));
- vv = nvv.modPow(e1, p); //m1 * (c/y)^e1
- vv = (vv.multiply(m1)).mod(p);
+ NativeBigInteger nvv =
+ new NativeBigInteger(c.multiply(g.modInverse(P4PParameters.p)).mod(P4PParameters.p));
+ vv = nvv.modPow(e1, P4PParameters.p); //m1 * (c/y)^e1
+ vv = (vv.multiply(m1)).mod(P4PParameters.p);
if(!f(z1).equals(vv)) {
- System.out.println("Verification failed 3. f(z1) = " + f(z1)
- + ", vv = " + vv);
+ System.out.println("Verification failed 3. f(z1) = " + f(z1)
+ + ", vv = " + vv);
return false;
-
+
}
-
+
return true;
}
-
+
/**
* Test the BitCommitment and the ZKP
@@ -313,14 +311,14 @@ public static void main(String[] args) {
int k = 512;
int N = 32;
int nLoops = 100;
-
+
for (int i = 0; i < args.length; ) {
String arg = args[i++];
if(arg.length() > 0 && arg.charAt(0) == '-') {
if (arg.equals("-k")) {
try {
k = Integer.parseInt(args[i++]);
- }
+ }
catch (NumberFormatException e) {
k = 512;
}
@@ -328,7 +326,7 @@ public static void main(String[] args) {
else if(arg.equals("-N")) {
try {
N = Integer.parseInt(args[i++]);
- }
+ }
catch (NumberFormatException e) {
N = 32;
}
@@ -336,15 +334,15 @@ else if(arg.equals("-N")) {
else if(arg.equals("-l")) {
try {
nLoops = Integer.parseInt(args[i++]);
- }
+ }
catch (NumberFormatException e) {
nLoops = 10;
}
}
-
+
}
}
-
+
// Setup the parameters:
P4PParameters.initialize(k, false);
NativeBigInteger g = P4PParameters.getGenerator();
@@ -353,7 +351,7 @@ else if(arg.equals("-l")) {
BitCommitment bc = new BitCommitment(g, h);
- SecureRandom rand = null;
+ SecureRandom rand = null;
try {
rand = SecureRandom.getInstance("SHA1PRNG");
}
@@ -362,9 +360,9 @@ else if(arg.equals("-l")) {
e.printStackTrace();
rand = new SecureRandom();
}
-
+
rand.nextBoolean();
-
+
System.out.println("Testing BitCommitment for " + nLoops + " loops .");
StopWatch proverWatch = new StopWatch();
StopWatch verifierWatch = new StopWatch();
@@ -372,27 +370,27 @@ else if(arg.equals("-l")) {
for(int j = 0; j < nLoops; j++) {
int val = rand.nextBoolean() ? 1 : 0;
BigInteger c = bc.commit(val);
-
- System.out.println("BitCommitted to " + val);
-
+
+ System.out.println("Committed to " + val);
+
// Verify
System.out.print("Testing commitment verification ...");
- if(!bc.verify(c, new BigInteger(String.valueOf(val)),
- bc.getRandomness()))
- System.out.println("Verification failed for test " + j
- + ". Should have passed.");
+ if(!bc.verify(c, new BigInteger(String.valueOf(val)),
+ bc.getRandomness()))
+ System.out.println("Verification failed for test " + j
+ + ". Should have passed.");
else
System.out.println(" passed");
-
+
// Wrong randomness. Should fail:
- if(bc.verify(c, new BigInteger(String.valueOf(val)),
- Util.randomBigInteger(q)))
- System.out.println("Verification passed for test " + j
- + ". Should have failed (wrong r).");
+ if(bc.verify(c, new BigInteger(String.valueOf(val)),
+ Util.randomBigInteger(P4PParameters.q)))
+ System.out.println("Verification passed for test " + j
+ + ". Should have failed (wrong r).");
// Wrong value. Should fail:
- if(bc.verify(c, Util.randomBigInteger(q), bc.getRandomness()))
- System.out.println("Verification passed for test " + j
- + ". Should have failed (wrong value).");
+ if(bc.verify(c, Util.randomBigInteger(P4PParameters.q), bc.getRandomness()))
+ System.out.println("Verification passed for test " + j
+ + ". Should have failed (wrong value).");
// Test the ZKP:
System.out.print("Testing bit commitment ZKP ...");
@@ -407,8 +405,8 @@ else if(arg.equals("-l")) {
verifierWatch.start();
if(!verifier.verify(proof))
- System.out.println("ZKP failed for test " + j
- + ". Should have passed.");
+ System.out.println("ZKP failed for test " + j
+ + ". Should have passed.");
else
System.out.println(" passed");
verifierWatch.pause();
@@ -416,18 +414,18 @@ else if(arg.equals("-l")) {
long end = System.currentTimeMillis();
verifierWatch.stop();
proverWatch.stop();
- System.out.println("Bit commitment ZKP: " + nLoops
- + " loops. ms per loop:");
+ System.out.println("Bit commitment ZKP: " + nLoops
+ + " loops. ms per loop:");
System.out.println("\n Prover time Verifier time Total");
System.out.println("===================================================");
- System.out.println(" "
- + (double)proverWatch.getElapsedTime()/(double)nLoops
- + " "
- + (double)verifierWatch.getElapsedTime()/(double)nLoops
- + " "
- + (double)(proverWatch.getElapsedTime()
- +verifierWatch.getElapsedTime())
- /(double)nLoops);
+ System.out.println(" "
+ + (double)proverWatch.getElapsedTime()/(double)nLoops
+ + " "
+ + (double)verifierWatch.getElapsedTime()/(double)nLoops
+ + " "
+ + (double)(proverWatch.getElapsedTime()
+ +verifierWatch.getElapsedTime())
+ /(double)nLoops);
System.out.println("Total testing time: " + (end-start) + " ms.");
}
}
diff --git a/src/java/p4p/crypto/BitVectorCommitment.java b/src/main/java/io/grpc/examples/p4p/p4p/crypto/BitVectorCommitment.java
similarity index 88%
rename from src/java/p4p/crypto/BitVectorCommitment.java
rename to src/main/java/io/grpc/examples/p4p/p4p/crypto/BitVectorCommitment.java
index 8ad6e10..295ca66 100644
--- a/src/java/p4p/crypto/BitVectorCommitment.java
+++ b/src/main/java/io/grpc/examples/p4p/p4p/crypto/BitVectorCommitment.java
@@ -1,22 +1,22 @@
-package p4p.crypto;
+package io.grpc.examples.p4p.p4p.crypto;
import java.math.BigInteger;
import java.security.SecureRandom;
-import net.i2p.util.NativeBigInteger;
-
-import p4p.util.Util;
-import p4p.util.P4PParameters;
+import io.grpc.examples.p4p.p4p.user.UserVector2;
+import io.grpc.examples.p4p.p4p.util.P4PParameters;
+import io.grpc.examples.p4p.p4p.util.Util;
+import io.grpc.examples.p4p.net.i2p.util.NativeBigInteger;
/**
- *
+ *
* A bit vector commitment. It allows the committer to commit to an N-dimensional
* vector of bits (0's or 1's). The commitment is a single element in Z_q. It
* also includes a ZKP that proves that the commmitment contains a vector of bits
* (0's or 1's).
* a using the given randomness. The method actually
* produces two Commitments (A and B). Only A is returned. B
@@ -130,20 +127,20 @@ public BigInteger commit(BigInteger val) {
public BigInteger commit(BigInteger val, BigInteger r) {
a = val;
A = new NativeBigInteger(computeCommitment(a, r));
- if(debug) {
- if(!A.equals(computeCommitment(a.mod(q), r)))
+ if(P4PParameters.debug) {
+ if(!A.equals(computeCommitment(a.mod(P4PParameters.q), r)))
throw new RuntimeException("A is not correct!");
}
sa = r;
- b = a.multiply(a).mod(q);
- if(debug) {
- if(!b.equals(a.mod(q).multiply(a.mod(q)).mod(q)))
+ b = a.multiply(a).mod(P4PParameters.q);
+ if(P4PParameters.debug) {
+ if(!b.equals(a.mod(P4PParameters.q).multiply(a.mod(P4PParameters.q)).mod(P4PParameters.q)))
throw new RuntimeException("b (should be a^2) is not correct!");
}
-
- sb = Util.randomBigInteger(q);
+
+ sb = Util.randomBigInteger(P4PParameters.q);
B = new NativeBigInteger(computeCommitment(b, sb));
-
+
return A;
}
@@ -153,22 +150,22 @@ public BigInteger commit(BigInteger val, BigInteger r) {
public BigInteger getA() {
return A;
}
-
+
public BigInteger getB() {
return B;
}
-
+
/**
* Gets the randomness
- */
+ */
public BigInteger getSa() {
return sa;
}
-
+
public BigInteger getSb() {
return sb;
}
-
+
/**
* Constructs the square commitment proof.
*/
@@ -177,7 +174,7 @@ public Proof getProof() {
proof.construct();
return proof;
}
-
+
/**
* A zero-knowledge proof that two commitments contain a number and its
@@ -189,52 +186,52 @@ public Proof getProof() {
*/
public class SquareCommitmentProof extends Proof {
public SquareCommitmentProof() { super(); }
-
+
// Construct the ZKP that the commitment contains a bit
public void construct() {
if(A == null || B == null)
throw new RuntimeException("Must commit to the numbers before"
- + " constructing the proof!");
+ + " constructing the proof!");
commitment = new BigInteger[4];
- commitment[0] = A;
+ commitment[0] = A;
commitment[1] = B;
- BigInteger x = Util.randomBigInteger(q);
- BigInteger ra = Util.randomBigInteger(q);
- BigInteger rb = Util.randomBigInteger(q);
-
- commitment[2] = g.modPow(x, p).multiply(h.modPow(ra, p)).mod(p); // Ca
- commitment[3] = A.modPow(x, p).multiply(h.modPow(rb, p)).mod(p); // Cb
+ BigInteger x = Util.randomBigInteger(P4PParameters.q);
+ BigInteger ra = Util.randomBigInteger(P4PParameters.q);
+ BigInteger rb = Util.randomBigInteger(P4PParameters.q);
+
+ commitment[2] = g.modPow(x, P4PParameters.p).multiply(h.modPow(ra, P4PParameters.p)).mod(P4PParameters.p); // Ca
+ commitment[3] = A.modPow(x, P4PParameters.p).multiply(h.modPow(rb, P4PParameters.p)).mod(P4PParameters.p); // Cb
// The first two elements are the commitments to a and b.
// The next two elements are Ca and Cb
-
+
challenge = new BigInteger[1];
-
+
// Get the challenge which should be a hash of the commitment:
BigInteger c = null;
try {
- c = Util.secureHash(commitment, q);
+ c = Util.secureHash(commitment, P4PParameters.q);
challenge[0] = c;
}
catch(GeneralSecurityException e) {
System.err.println("Can't compute hash!");
e.printStackTrace();
}
-
+
response = new BigInteger[3];
-
+
// response[0] = a.multiply(c).add(x).mod(q); // v
// response[1] = sa.multiply(c).add(ra).mod(q); // za
// response[2] = sb.subtract(sa.multiply(a)).multiply(c).add(rb).mod(q); // zb
-
- BigInteger a1 = a.mod(q);
- response[0] = a1.multiply(c).add(x).mod(q); // v
- response[1] = sa.multiply(c).add(ra).mod(q); // za
+
+ BigInteger a1 = a.mod(P4PParameters.q);
+ response[0] = a1.multiply(c).add(x).mod(P4PParameters.q); // v
+ response[1] = sa.multiply(c).add(ra).mod(P4PParameters.q); // za
response[2] = sb.subtract(sa.multiply(a1)).multiply(c).add(rb)
- .mod(q); // zb
+ .mod(P4PParameters.q); // zb
}
}
-
+
/**
* Verifies the given proof using our own parameters.
* val is contained in the commitment
@@ -122,9 +119,9 @@ public BigInteger commit(long val, BigInteger r) {
*/
public boolean verify(BigInteger c, BigInteger val, BigInteger r) {
if(!val.equals(BigInteger.ZERO) && !val.equals(CONST)
- && !val.equals(CONST.negate()))
+ && !val.equals(CONST.negate()))
return false;
-
+
return super.verify(c, val, r);
}
@@ -133,7 +130,7 @@ public Proof getProof() {
proof.construct();
return proof;
}
-
+
/**
* A zero-knowledge proof that the commitment contains 0,or +/-c. The protocol
* is based on
@@ -155,20 +152,20 @@ public class ThreeWayCommitmentProof extends Proof {
* itself so we don't need to store the bit commitments.
*/
private BitCommitment.BitCommitmentProof bcp1 = null;
- private BitCommitment.BitCommitmentProof bcp2 = null;
+ private BitCommitment.BitCommitmentProof bcp2 = null;
public ThreeWayCommitmentProof() { super(); }
-
+
// Construct the ZKP that the commitment contains 0,or +/-c
public void construct() {
if(val == null)
- throw new RuntimeException("Must commit to a value first"
- + "before constructing the proof!");
-
+ throw new RuntimeException("Must commit to a value first"
+ + "before constructing the proof!");
+
// We do need to store this commitment:
commitment = new BigInteger[1];
- if(val != null)
+ if(val != null)
commitment[0] = commit(val, r);
else
commitment[0] = commit(val);
@@ -202,7 +199,7 @@ else if(val.equals(CONST.negate())) {
bc2.commit(1);
bc1.commit(0, rc.add(bc2.getRandomness()).mod(q));
}
-
+
/**
* The first element in the BitCommitmentProof is the commitment
* itself so we don't need to store the bit commitment.
@@ -226,9 +223,9 @@ public BitCommitment.BitCommitmentProof getNumeratorProof() {
*/
public BitCommitment.BitCommitmentProof getDenominatorProof() {
return bcp2;
- }
+ }
}
-
+
/**
* Verifies the given proof using our own parameters.
*
@@ -236,19 +233,19 @@ public BitCommitment.BitCommitmentProof getDenominatorProof() {
* who does not have the values, should construct a fresh new commitment
* and pass the proof to it. The verifier and the prover should use the
* same parameters (e.g. g and h).
- */
+ */
public boolean verify(ThreeWayCommitmentProof proof) {
BitCommitment.BitCommitmentProof bcp1 = proof.getNumeratorProof();
BitCommitment.BitCommitmentProof bcp2 = proof.getDenominatorProof();
// Check the bit commitments
- BitCommitment bc = new BitCommitment(g, h);
+ BitCommitment bc = new BitCommitment(g, h);
if(!bc.verify(bcp1) || !bc.verify(bcp2)) {
System.out.println("BitCommitment verification failed!");
return false;
}
-
+
// This commitment
BigInteger C = proof.getCommitment()[0];
BigInteger C1 = bcp1.getCommitment()[0];
@@ -258,10 +255,10 @@ public boolean verify(ThreeWayCommitmentProof proof) {
System.out.println("C1: " + C1 + ", C2: " + C2);
return false;
}
-
+
return true;
}
-
+
/**
* Test the ThreeCommitment and the ZKP
@@ -269,14 +266,14 @@ public boolean verify(ThreeWayCommitmentProof proof) {
public static void main(String[] args) {
int k = 512;
int nLoops = 10;
-
+
for (int i = 0; i < args.length; ) {
String arg = args[i++];
if(arg.length() > 0 && arg.charAt(0) == '-') {
if (arg.equals("-k")) {
try {
k = Integer.parseInt(args[i++]);
- }
+ }
catch (NumberFormatException e) {
k = 512;
}
@@ -284,22 +281,22 @@ public static void main(String[] args) {
else if(arg.equals("-l")) {
try {
nLoops = Integer.parseInt(args[i++]);
- }
+ }
catch (NumberFormatException e) {
nLoops = 10;
}
}
-
+
}
}
-
+
// Setup the parameters:
P4PParameters.initialize(k, false);
- NativeBigInteger g = P4PParameters.getGenerator();
- NativeBigInteger h = P4PParameters.getFreshGenerator();
+ NativeBigInteger g = getGenerator();
+ NativeBigInteger h = getFreshGenerator();
// We should use the same generators for both the prover and the verifier.
- SecureRandom rand = null;
+ SecureRandom rand = null;
try {
rand = SecureRandom.getInstance("SHA1PRNG");
}
@@ -308,9 +305,9 @@ else if(arg.equals("-l")) {
e.printStackTrace();
rand = new SecureRandom();
}
-
+
rand.nextBoolean();
-
+
System.out.println("Testing ThreeWayCommitment for " + nLoops + " loops .");
StopWatch proverWatch = new StopWatch();
StopWatch verifierWatch = new StopWatch();
@@ -319,7 +316,7 @@ else if(arg.equals("-l")) {
for(int j = 0; j < nLoops; j++) {
long c = rand.nextLong();
if(k < 66) c = (long)rand.nextInt()%(1<<(k-2));
-
+
if(c < 0) c = -c;
long val = rand.nextLong();
if(val%3 == 0) val = 0;
@@ -327,29 +324,29 @@ else if(arg.equals("-l")) {
else val = -c;
ThreeWayCommitment tc = new ThreeWayCommitment(g, h, c);
- BigInteger C = tc.commit(val);
-
+ BigInteger C = tc.commit(val);
+
// Verify
System.out.print("Testing commitment verification No. " + j + "....");
System.out.println(" Committed to " + val);
- if(!tc.verify(C, new BigInteger(String.valueOf(val)),
- tc.getRandomness())) {
- System.out.println("Verification failed for test " + j
- + ". Should have passed.");
+ if(!tc.verify(C, new BigInteger(String.valueOf(val)),
+ tc.getRandomness())) {
+ System.out.println("Verification failed for test " + j
+ + ". Should have passed.");
nfails++;
}
-
+
// Wrong randomness. Should fail:
- if(tc.verify(C, new BigInteger(String.valueOf(val)),
- Util.randomBigInteger(q))) {
- System.out.println("Verification passed for test " + j
- + ". Should have failed (wrong r).");
+ if(tc.verify(C, new BigInteger(String.valueOf(val)),
+ Util.randomBigInteger(q))) {
+ System.out.println("Verification passed for test " + j
+ + ". Should have failed (wrong r).");
nfails++;
}
// Wrong value. Should fail:
if(tc.verify(C, Util.randomBigInteger(q), tc.getRandomness())) {
- System.out.println("Verification passed for test " + j
- + ". Should have failed (wrong value).");
+ System.out.println("Verification passed for test " + j
+ + ". Should have failed (wrong value).");
nfails++;
}
@@ -374,18 +371,18 @@ else if(arg.equals("-l")) {
long end = System.currentTimeMillis();
verifierWatch.stop();
proverWatch.stop();
- System.out.println("3-Way commitment ZKP: " + nLoops
- + " loops. Total failed tests: " + nfails + ". ms per loop:");
+ System.out.println("3-Way commitment ZKP: " + nLoops
+ + " loops. Total failed tests: " + nfails + ". ms per loop:");
System.out.println("\n Prover time Verifier time Total");
System.out.println("===================================================");
- System.out.println(" "
- + (double)proverWatch.getElapsedTime()/(double)nLoops
- + " "
- + (double)verifierWatch.getElapsedTime()/(double)nLoops
- + " "
- + (double)(proverWatch.getElapsedTime()
- +verifierWatch.getElapsedTime())
- /(double)nLoops);
+ System.out.println(" "
+ + (double)proverWatch.getElapsedTime()/(double)nLoops
+ + " "
+ + (double)verifierWatch.getElapsedTime()/(double)nLoops
+ + " "
+ + (double)(proverWatch.getElapsedTime()
+ +verifierWatch.getElapsedTime())
+ /(double)nLoops);
System.out.println("Total testing time: " + (end-start) + " ms.");
}
}
diff --git a/src/java/p4p/crypto/VectorCommitment.java b/src/main/java/io/grpc/examples/p4p/p4p/crypto/VectorCommitment.java
similarity index 85%
rename from src/java/p4p/crypto/VectorCommitment.java
rename to src/main/java/io/grpc/examples/p4p/p4p/crypto/VectorCommitment.java
index 1da82c8..043152e 100644
--- a/src/java/p4p/crypto/VectorCommitment.java
+++ b/src/main/java/io/grpc/examples/p4p/p4p/crypto/VectorCommitment.java
@@ -1,7 +1,7 @@
/**
* Copyright (c) 2007 Regents of the University of California.
* All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -29,19 +29,18 @@
* SUCH DAMAGE.
*/
-package p4p.crypto;
+package io.grpc.examples.p4p.p4p.crypto;
import java.math.BigInteger;
-import java.security.SecureRandom;
-
-import net.i2p.util.NativeBigInteger;
-import p4p.util.Util;
-import p4p.util.P4PParameters;
+import io.grpc.examples.p4p.p4p.user.UserVector2;
+import io.grpc.examples.p4p.p4p.util.P4PParameters;
+import io.grpc.examples.p4p.p4p.util.Util;
+import io.grpc.examples.p4p.net.i2p.util.NativeBigInteger;
/**
- *
+ *
* Vector commitment. It allows the committer to commit to an N-dimensional
* vector. The commitment is a single element in Z_q. The scheme is based on
* Pedersen's discrete log based commitment scheme:
@@ -51,7 +50,7 @@
* Volume 576, Jan 1992, Page 129
* NOTE: This class is not used in the new version of the L2-norm ZKP
- * (implemented in {@link p4p.user.UserVector2}) and is not being maintained.
+ * (implemented in {@link UserVector2}) and is not being maintained.
*
* @author ET 08/25/2005
*/
@@ -59,32 +58,32 @@
public class VectorCommitment extends P4PParameters {
protected NativeBigInteger[] g = null;
protected NativeBigInteger h = null;
-
+
/**
* The dimension of the vector
*/
- int N = -1;
-
+ int N = -1;
+
/**
* verify that the parameters are correct.
*/
-
+
public void sanityCheck() {
super.sanityCheck();
-
+
if(!h.modPow(q, p).equals(BigInteger.ONE))
throw new IllegalArgumentException("h does not have the correct order!");
-
+
if(N <= 0)
throw new IllegalArgumentException("Non-positive dimension!");
-
+
for(int i = 0; i < N; i++) {
if(g[i].equals(BigInteger.ONE))
throw new IllegalArgumentException("g[" + i + "] is ONE!");
if(!g[i].modPow(q, p).equals(BigInteger.ONE))
throw new IllegalArgumentException("g[" + i + "] does not have the correct order!");
}
-
+
}
/**
@@ -93,9 +92,9 @@ public void sanityCheck() {
* to bits).
*/
protected BigInteger vectorCommit(BigInteger[] vals, BigInteger r) {
- if(vals.length != N)
+ if(vals.length != N)
throw new IllegalArgumentException("Incorrect dimension!");
-
+
BigInteger c = h.modPow(r, p);
for(int i = 0; i < N; i++) {
if(vals[i].equals(BigInteger.ZERO))
@@ -105,107 +104,107 @@ else if(vals[i].equals(BigInteger.ONE))
else
c = c.multiply(g[i].modPow(vals[i].mod(q), p)).mod(p);
}
-
+
return c;
}
// The committer:
- /**
+ /**
* The values to be committed to.
*/
- protected BigInteger[] vals = null;
-
- /**
+ protected BigInteger[] vals = null;
+
+ /**
* The randomness used in the commitment.
*/
- protected BigInteger r = null;
-
+ protected BigInteger r = null;
+
/**
*/
public VectorCommitment(NativeBigInteger g[], NativeBigInteger h) {
this.g = g;
this.h = h;
N = g.length;
- sanityCheck();
+ sanityCheck();
}
-
+
public int getDemension() { return N; }
-
+
/**
* Commits to a vector of long integers. (Assume q > Long.MAX_VALUE)
- */
+ */
public BigInteger commit(long[] vals) {
this.vals = new BigInteger[vals.length];
- for(int i = 0; i < vals.length; i++)
+ for(int i = 0; i < vals.length; i++)
this.vals[i] = new BigInteger(String.valueOf(vals[i]));
-
+
return commit(this.vals);
}
-
-
+
+
/**
- * Commits to a vector of long integers using the given randomness
+ * Commits to a vector of long integers using the given randomness
* (Assume q > Long.MAX_VALUE)
- */
+ */
public BigInteger commit(long[] vals, BigInteger r) {
this.vals = new BigInteger[vals.length];
- for(int i = 0; i < vals.length; i++)
+ for(int i = 0; i < vals.length; i++)
this.vals[i] = new BigInteger(String.valueOf(vals[i]));
-
+
return commit(this.vals, r);
}
-
-
+
+
/**
* Commits to a vector of integers. (Assume q > Integer.MAX_VALUE)
- */
+ */
public BigInteger commit(int[] vals) {
this.vals = new BigInteger[vals.length];
- for(int i = 0; i < vals.length; i++)
+ for(int i = 0; i < vals.length; i++)
this.vals[i] = new BigInteger(String.valueOf(vals[i]));
-
+
return commit(this.vals);
}
-
+
/**
* Commits to a vector of integers using the given randomness.
* (Assume q > Integer.MAX_VALUE)
- */
+ */
public BigInteger commit(int[] vals, BigInteger r) {
this.vals = new BigInteger[vals.length];
- for(int i = 0; i < vals.length; i++)
+ for(int i = 0; i < vals.length; i++)
this.vals[i] = new BigInteger(String.valueOf(vals[i]));
-
+
return commit(this.vals, r);
}
-
+
/**
* Commits to a vector of BigInteger
*/
-
+
public BigInteger commit(BigInteger[] vals) {
r = Util.randomBigInteger(q);
return commit(vals, r);
}
-
+
/**
* Commits to a vector of BigInteger using the given randomness
*/
-
+
public BigInteger commit(BigInteger[] vals, BigInteger r) {
this.r = r;
this.vals = vals;
-
+
return vectorCommit(vals, r);
}
-
+
/**
* Returns the randomness used in this commitment
*/
public BigInteger getRandomness() {
return r;
}
-
+
/**
* Returns the vector contained in this commitment
*/
@@ -213,7 +212,7 @@ public BigInteger[] getVector() {
return vals;
}
-
+
// The verifier:
/**
* Verify if the given vector is the one contained in the commitment.
@@ -223,7 +222,7 @@ public boolean verify(BigInteger c, BigInteger[] vec, BigInteger r) {
BigInteger cc = vectorCommit(vec, r);
return cc.equals(c);
}
-
+
/**
* Test the VectorCommitment
*/
@@ -231,14 +230,14 @@ public static void main(String[] args) {
int k = 512;
int N = 32;
int nLoops = 10;
-
+
for (int i = 0; i < args.length; ) {
String arg = args[i++];
if(arg.length() > 0 && arg.charAt(0) == '-') {
if (arg.equals("-k")) {
try {
k = Integer.parseInt(args[i++]);
- }
+ }
catch (NumberFormatException e) {
k = 512;
}
@@ -246,7 +245,7 @@ public static void main(String[] args) {
else if(arg.equals("-N")) {
try {
N = Integer.parseInt(args[i++]);
- }
+ }
catch (NumberFormatException e) {
N = 32;
}
@@ -254,31 +253,31 @@ else if(arg.equals("-N")) {
else if(arg.equals("-l")) {
try {
nLoops = Integer.parseInt(args[i++]);
- }
+ }
catch (NumberFormatException e) {
nLoops = 10;
}
}
-
+
}
}
-
+
// Setup the parameters:
P4PParameters.initialize(k, false);
-
- VectorCommitment vc =
- new VectorCommitment(P4PParameters.getGenerators(N),
- P4PParameters.getGenerator()) ;
-
+
+ VectorCommitment vc =
+ new VectorCommitment(P4PParameters.getGenerators(N),
+ P4PParameters.getGenerator()) ;
+
// Generate the vector:
BigInteger[] vec = new BigInteger[N];
BigInteger[] sum = new BigInteger[N];
-
+
// dummy
BigInteger[] dummy = new BigInteger[N];
for(int i = 0; i < N; i++)
dummy[i] = Util.randomBigInteger(q);
-
+
System.out.println("Testing VectorCommitment .");
for(int j = 0; j < nLoops; j++) {
//System.out.print(".");
@@ -286,31 +285,31 @@ else if(arg.equals("-l")) {
vec[i] = Util.randomBigInteger(q);
sum[i] = vec[i].add(dummy[i]);
}
-
+
// Commit
BigInteger c = vc.commit(vec);
BigInteger r = vc.getRandomness();
-
+
// Verify
if(!vc.verify(c, vec, r))
- System.out.println("Verification failed for test "
- + j + ". Should have passed.");
-
+ System.out.println("Verification failed for test "
+ + j + ". Should have passed.");
+
// Wrong randomness. Should fail:
if(vc.verify(c, vec, Util.randomBigInteger(q)))
- System.out.println("Verification passed for test "
- + j + ". Should have failed (wrong r submitted).");
-
+ System.out.println("Verification passed for test "
+ + j + ". Should have failed (wrong r submitted).");
+
// Wrong vector. Should fail:
if(vc.verify(c, dummy, r))
- System.out.println("Verification passed for test "
- + j + ". Should have failed (wrong vector submitted).");
-
+ System.out.println("Verification passed for test "
+ + j + ". Should have failed (wrong vector submitted).");
+
// Now check the homomorphism:
System.out.print("Verifying homomorphism ....");
BigInteger dc = vc.commit(dummy);
BigInteger dr = vc.getRandomness();
-
+
// c*dc = commit(sum, r+dr)
if(!c.multiply(dc).mod(p).equals(vc.commit(sum, r.add(dr)).mod(p)))
System.out.println(" failed. Homomorphism doesn't hold.");
diff --git a/src/main/java/io/grpc/examples/p4p/p4p/peer/P4PPeer.java b/src/main/java/io/grpc/examples/p4p/p4p/peer/P4PPeer.java
new file mode 100644
index 0000000..4ee9879
--- /dev/null
+++ b/src/main/java/io/grpc/examples/p4p/p4p/peer/P4PPeer.java
@@ -0,0 +1,47 @@
+package io.grpc.examples.p4p.p4p.peer;
+
+import io.grpc.examples.p4p.net.i2p.util.NativeBigInteger;
+
+public class P4PPeer {
+ private NativeBigInteger g = null;
+ private NativeBigInteger h = null;
+
+ protected int m = -1; // The dimension of user vector
+ protected long F = -1;
+ /**
+ * The order of the (small) finite field over which all the computations
+ * are carried out. It should be a prime of appropriate bit-length (e.g.
+ * 64 bits).
+ */
+
+ protected long L = -1;
+ protected int l; // The max number of bits of the 2 norm of user vector
+ protected int N = 50; // The number of chechsums to compute. Default 50
+ private int c[][] = null; // The challenge vectors
+ public long[] s = null; // The accumulated vector sum
+ public long[] peerSum = null; // The peer's share of the vector sum
+
+
+ /**
+ * Sets the peer's share of the vector sum
+ * @param vv the sum of the peer's share of the user vector
+ */
+ public void setPeerSum(long[] vv) {
+ peerSum = vv;
+ }
+
+ public P4PPeer(int m, long F, int l, int N, NativeBigInteger g,
+ NativeBigInteger h) {
+ if(F < 0)
+ throw new RuntimeException("Field order must be positive.");
+
+ this.m = m;
+ this.F = F;
+ this.l = l;
+ this.L = ((long)1)<
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the University may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+package io.grpc.examples.p4p.p4p.sim;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.SecureRandom;
+import java.io.File; // Import the File class
+import java.io.FileNotFoundException; // Import this class to handle errors
+import java.util.Scanner; // Import the Scanner class to read text files
+
+import io.grpc.examples.p4p.p4p.user.UserVector2;
+import io.grpc.examples.p4p.p4p.util.P4PParameters;
+import io.grpc.examples.p4p.p4p.util.StopWatch;
+import io.grpc.examples.p4p.p4p.util.Util;
+import io.grpc.examples.p4p.net.i2p.util.NativeBigInteger;
+
+import io.grpc.examples.p4p.p4p.peer.P4PPeer;
+import io.grpc.examples.p4p.p4p.server.P4PServer;
+
+/**
+ * Providing a simulation framework for a P4P system. This allows one to debug
+ * and benchmark the cryptographic primitives without having to provide other
+ * components necessary for a real deployment (e.g. secure communication).
+ *
+ * @author ET 12/10/2005
+ */
+
+public class P4PSim extends P4PParameters {
+ private static NativeBigInteger g = null;
+ private static NativeBigInteger h = null;
+
+ private static int k = 512; // Security parameter
+ private static int m = 10000; // User vector dimension
+ private static int n = 1; // Number of users
+ private static int l = 40; // Bit length of L
+
+ /**
+ * Start a simulation.
+ */
+ public static void main(String[] args) {
+ int nLoops = 1;
+ boolean doBench = false;
+ boolean worstcase = false;
+ int zkpIterations = 50;
+
+ for (int i = 0; i < args.length; ) {
+ String arg = args[i++];
+ /**
+ * Test the worst case cost. i.e. every vector should pass. This is
+ * when the verifier spends longest time.
+ */
+ // Definie the number of iterations that the bound ZKP must have:
+
+ if (arg.length() > 0 && arg.charAt(0) == '-') {
+ if (arg.equals("-k")) {
+ try {
+ k = Integer.parseInt(args[i++]);
+ } catch (NumberFormatException e) {
+ k = 512;
+ }
+ } else if (arg.equals("-m")) {
+ try {
+ m = Integer.parseInt(args[i++]);
+ } catch (NumberFormatException e) {
+ m = 10;
+ }
+ } else if (arg.equals("-n")) {
+ try {
+ n = Integer.parseInt(args[i++]);
+ } catch (NumberFormatException e) {
+ n = 10;
+ }
+ } else if (arg.equals("-N")) {
+ try {
+ zkpIterations = Integer.parseInt(args[i++]);
+ } catch (NumberFormatException e) {
+ zkpIterations = 50;
+ }
+ } else if (arg.equals("-o")) {
+ try {
+ nLoops = Integer.parseInt(args[i++]);
+ } catch (NumberFormatException e) {
+ nLoops = 10;
+ }
+ } else if (arg.equals("-l")) {
+ try {
+ l = Integer.parseInt(args[i++]);
+ } catch (NumberFormatException e) {
+ l = 40;
+ }
+ } else if (arg.equals("-d")) {
+ debug = true;
+ } else if (arg.equals("-w")) {
+ worstcase = true;
+ } else if (arg.equals("-bench")) {
+ doBench = true;
+ }
+ }
+ }
+
+ System.out.println("k = " + k);
+ System.out.println("m = " + m);
+ System.out.println("n = " + n);
+ System.out.println("nLoops = " + nLoops);
+
+ // Setup the parameters:
+ P4PParameters.initialize(k, false);
+ SecureRandom rand = null;
+ try {
+ rand = SecureRandom.getInstance("SHA1PRNG");
+ } catch (java.security.NoSuchAlgorithmException e) {
+ System.err.println("NoSuchAlgorithmException!");
+ e.printStackTrace();
+ rand = new SecureRandom();
+ }
+
+ rand.nextBoolean();
+
+ long L = ((long) 2) << l - 1;
+ long F = BigInteger.probablePrime(Math.min(l + 30, 62), rand).longValue();
+ // Make the field size to be 10 bits larger than l
+
+ // Or just make F 62 bits? Note that we can't use 64 bit since there is no
+ // unsigned long in java.
+ //F = BigInteger.probablePrime(62, rand).longValue();
+
+ int N = zkpIterations;
+ System.out.println("l = " + l + ", L = " + L);
+ System.out.println("F = " + F);
+ System.out.println("zkpIterations = " + zkpIterations);
+
+ // Generate the data and the checksum coefficient vector:
+ try {
+ String fileName = "/Users/mac/Desktop/FedBFT/voting/output.txt";
+ File myObj = new File(fileName);
+ Path path = Paths.get(fileName);
+ long dataLineNum = 0;
+ try{
+ dataLineNum = Files.lines(path).count();
+ }catch(IOException e){
+ System.out.println("error of read line");
+ }
+ System.out.println("dataLineNum: "+dataLineNum);
+ Scanner myReader = new Scanner(myObj);
+ while (myReader.hasNextLine()) {
+ String strdata = myReader.nextLine();
+ m = strdata.length();
+ long[] data = new long[m];
+ char[] charArray = strdata.toCharArray();
+ for (int did = 0; did < m; did++) {
+ long a = charArray[did] - '0';
+ data[did] = a;
+ }
+ System.out.println(data);
+
+
+// int[][] c = new int[zkpIterations][];
+ NativeBigInteger[] bi = P4PParameters.getGenerators(2);
+ g = bi[0];
+ h = bi[1];
+
+ P4PServer server = new P4PServer(m, F, l, zkpIterations, g, h);
+ P4PPeer peer = new P4PPeer(m, F, l, zkpIterations, g, h);
+ long[] s = new long[m];
+ long[] v = new long[m];
+
+ StopWatch proverWatch = new StopWatch();
+ StopWatch verifierWatch = new StopWatch();
+ double delta = 1.5;
+ int nfails = 0;
+
+ for (int kk = 0; kk < nLoops; kk++) {
+ int nQulaifiedUsers = 0;
+ boolean passed = true;
+ server.init(); // Must clear old states and data
+ server.generateChallengeVectors();
+ for (int i = 0; i < m; i++) {
+ s[i] = 0;
+ v[i] = 0;
+ }
+// for each user
+ for (int i = 0; i < n; i++) {
+ long start = System.currentTimeMillis();
+ long innerProductTime = 0;
+ long randChallengeTime = 0;
+ boolean shouldPass;
+ // We should create a vector that passes the zkp
+ if (worstcase) shouldPass = true; // Test the worst case
+ else shouldPass = rand.nextBoolean();
+ //System.out.println("Loop " + kk + ", user " + i + ". shouldPass = " + shouldPass);
+ if (shouldPass) delta = 0.5;
+ else delta = 2.0;
+ double l2 = (double) L * delta;
+
+// 1⃣️. Generate Data & 🌛UserVector2
+
+// data = Util.randVector(m, F, l2);
+ UserVector2 uv = new UserVector2(data, F, l, g, h);
+// UserVector2(data, F, l, g, h)
+
+
+// 2⃣️. Shares: u, v
+ uv.generateShares();
+
+// 2.1 Set checkCoVector through server challenge_vector for each user 🐢
+ uv.setChecksumCoefficientVectors(server.getChallengeVectors());
+
+// 🌟 prover start 🌟
+ proverWatch.start();
+// peerProof, serverProof construct() 🐰 SquareSum.add()
+ UserVector2.L2NormBoundProof2 peerProof =
+ (UserVector2.L2NormBoundProof2) uv.getL2NormBoundProof2(false);
+ UserVector2.L2NormBoundProof2 serverProof =
+ (UserVector2.L2NormBoundProof2) uv.getL2NormBoundProof2(true);
+ proverWatch.pause();
+// 🌟 prover pause 🌟
+
+// 2.2 server.setUV(U),
+ server.setUserVector(i, uv.getU());
+// 2.3 server.setProof
+ server.setProof(i, serverProof);
+
+// 3⃣️. The peer:
+ long[] vv = uv.getV();
+// 3⃣.1 The peer: setV(); // 🌛 UserVector2(m, F, l, g, h)
+ UserVector2 pv = new UserVector2(m, F, l, g, h);
+ pv.setV(vv);
+
+// 3.2 set CheCoVectors through server.ChallVector for Each User 🐢
+ pv.setChecksumCoefficientVectors(server.getChallengeVectors());
+ verifierWatch.start();
+
+// 3.2 setChecksumCoefficientVectors through server Challenge_Vector for Each User
+ boolean peerPassed = pv.verify2(peerProof); // 🌟 verify2 🌟
+ verifierWatch.pause();
+
+
+// 4⃣️ !peerPassed disqualifyUser(i),
+// server.setY(): commitments to the peer's share of the checksums, and forward to server
+// verify the proof, // peerVerification returns true
+ if (!peerPassed)
+ server.disqualifyUser(i);
+ else
+ server.setY(i, pv.getY());
+ /**
+ * Note that peer's verification simply computes some
+ * commitments the peer's shares of the checksums (i.e. the
+ * Y's) which should be forwarded to the server. We simulate
+ * this by the server.setY call. The server then use them to
+ * verify the proof. This is where the real verification
+ * happens. The peer's verification actually always returns
+ * true.
+ */
+
+ // 5⃣️ l2 < L = shouldPass
+ shouldPass = l2 < L; // Correct shouldPass using actual data.
+ shouldPass = true;
+ if (shouldPass) {
+ nQulaifiedUsers++;
+ Util.vectorAdd(s, data, s, F);
+ Util.vectorAdd(v, vv, v, F);
+ }
+ }
+
+// 6⃣️ server prepare to verify
+// server.setPeerSum()
+// server.compute()
+ peer.setPeerSum(v);
+ verifierWatch.start();
+ server.compute(peer); // 🌟 serverVerify 🐢🌟
+ verifierWatch.pause();
+
+// 7⃣️ VectorSum()
+ long[] result = server.getVectorSum();
+
+ for (int ii = 0; ii < m; ii++) {
+// 7.1 res[ii] != Util.mod(s[ii], F)
+ if (result[ii] != Util.mod(s[ii], F)) {
+ System.out.println("\tElement " + ii
+ + " don't agree. Computed: "
+ + result[ii] + ", should be "
+ + Util.mod(s[ii], F));
+ passed = false;
+ nfails++;
+ break;
+ }
+ }
+ if (passed)
+ System.out.println("Test " + kk + " passed. Number of qualified users "
+ + " should be " + nQulaifiedUsers + ". Server reported "
+ + server.getNQulaifiedUsers());
+ else
+ System.out.println("Test " + kk + " failed. Number of qualified users should be "
+ + nQulaifiedUsers + ". Server reported "
+ + server.getNQulaifiedUsers());
+
+ }
+
+ verifierWatch.stop();
+ proverWatch.stop();
+ long end = System.currentTimeMillis();
+
+ System.out.println("Total tests run: " + nLoops + ". Failed: " + nfails);
+ System.out.println("\n Prover time Verifier time Total");
+ System.out.println("============================================================");
+ System.out.println(" " + (double) proverWatch.getElapsedTime() / nLoops
+ + " "
+ + (double) verifierWatch.getElapsedTime() / nLoops
+ + " "
+ + ((double) (proverWatch.getElapsedTime()
+ + verifierWatch.getElapsedTime())) / nLoops);
+ System.out.println("Note that the time is for all " + n + " users in ms.");
+ System.out.println("Also note that the prover needs to compute proofs"
+ + " for both the server and the privacy peer.");
+ }
+ myReader.close();
+
+ } catch (FileNotFoundException e) {
+ System.out.println("An error occurred.");
+ e.printStackTrace();
+ }
+
+ }
+}
+
+
diff --git a/src/main/java/io/grpc/examples/p4p/p4p/sim/ServerTemp.java b/src/main/java/io/grpc/examples/p4p/p4p/sim/ServerTemp.java
new file mode 100644
index 0000000..1fa1899
--- /dev/null
+++ b/src/main/java/io/grpc/examples/p4p/p4p/sim/ServerTemp.java
@@ -0,0 +1,4 @@
+package io.grpc.examples.p4p.p4p.sim;
+
+public class ServerTemp {
+}
diff --git a/src/main/java/io/grpc/examples/p4p/p4p/sim/beforeSecondVAdd.txt b/src/main/java/io/grpc/examples/p4p/p4p/sim/beforeSecondVAdd.txt
new file mode 100644
index 0000000..590f9cb
--- /dev/null
+++ b/src/main/java/io/grpc/examples/p4p/p4p/sim/beforeSecondVAdd.txt
@@ -0,0 +1,7 @@
+ private long[] s = null; // The accumulated vector sum
+ private long[] peerSum = null; // The peer's share of the vector sum
+
+
+ before 2nd VectorAdd(s, peerSum, s, F), after Util.vectorAdd(s, u, s, F)
+ s=[423415934382092800, -63743772828146432, 1437938452422568960, -827156099394474752, 76182506976720640, -1743276040546728704, -1500102254775153920, 66737688933934848, -351584170633951488, -235637947241373696]
+ peerSum=[-423415886871895594, 63743614238569075, -1437938290428259645, 827156229809895151, -76182261736714936, 1743276244504359410, 1500102466478549832, -66737474705362734, 351584355525083225, 235638017818629922]
\ No newline at end of file
diff --git a/src/main/java/io/grpc/examples/p4p/p4p/sim/serverVerify(l2Proof, Y).txt b/src/main/java/io/grpc/examples/p4p/p4p/sim/serverVerify(l2Proof, Y).txt
new file mode 100644
index 0000000..9efd46c
--- /dev/null
+++ b/src/main/java/io/grpc/examples/p4p/p4p/sim/serverVerify(l2Proof, Y).txt
@@ -0,0 +1,78 @@
+public main(){
+ for(int i = 0; i < x.length; i++) {
+ // First make sure the checksums are computed correctly:
+ if(x[i] != Util.mod(Util.innerProduct(c[i], u), F)) {
+ // We are doing server
+ return false;
+ }
+ // Now check if the modular correctors, the Bs, are computed correctly
+ if(!B[i].equals(tcProofs[i].getCommitment()[0])) {
+ return false;
+ }
+ // Check the 3-way proofs
+ if(!tc.verify(tcProofs[i])) {
+ return false;
+ }
+ X[i] =
+ cm.commit(new BigInteger(new Long(x[i]).toString()).mod(q),
+ // The checksum
+ r[i]); // The randomness
+ S[i] = X[i].multiply(B[i]).mod(p).multiply(Y[i]).mod(p);
+ }
+
+ // Next check that the sum of squares does not have excessive bits:
+ if(bcProofs.length > Integer.toBinaryString(c.length).length()+2*l) {
+ System.out.println("Sum of squares has too many bits: "
+ + bcProofs.length
+ + ", the limit is "
+ + (Integer.toBinaryString(c.length).length()+2*l));
+ return false;
+ }
+
+ // Check the square proofs:
+ SquareCommitment sc = new SquareCommitment(g, h);
+ for(int i = 0; i < scProofs.length; i++) {
+ // 1st: check that the square commitment encodes the correct
+ if(!scProofs[i].getCommitment()[0].equals(S[i])) {
+ return false;
+ }
+ // 2nd: Square Verification
+ if(!sc.verify(scProofs[i])) {
+ return false;
+ }
+ }
+
+ BigInteger z = BigInteger.ONE;
+ for(int i = 0; i < scProofs.length; i++) {
+ z = z.multiply(scProofs[i].getCommitment()[1]).mod(p); // *= B
+ }
+ z = z.multiply(z).mod(p); // commitment[0] actually stores 2X
+// Commitment to square sum wasn't computed correctly
+ if(!l2Proof.getCommitment()[0].equals(z)) {
+ return false;
+ }
+
+ // Then check each bits
+ BitCommitment bc = new BitCommitment(g, h);
+ BigInteger zz = BigInteger.ONE;
+
+ DEBUG("Checking " + bcProofs.length + " bit commitments");
+
+ BigInteger ZZ = BigInteger.ONE;
+ for(int i = 0; i < bcProofs.length; i++) {
+ if(!bc.verify(bcProofs[i])) {
+ System.out.println("Bit commitment verification " + i
+ + " failed.");
+ return false;
+ }
+ BigInteger e = BigInteger.ZERO.setBit(i);
+
+ NativeBigInteger Z =
+ (NativeBigInteger)bcProofs[i].getCommitment()[0];
+ ZZ = ZZ.multiply(Z.modPow(e, p)).mod(p);
+ }
+ // Homomorphism does not hold
+ if(!ZZ.equals(z)) {
+ return false;
+ }
+ }
\ No newline at end of file
diff --git a/src/main/java/io/grpc/examples/p4p/p4p/user/SquareSum.bitLength for(c) checker.txt b/src/main/java/io/grpc/examples/p4p/p4p/user/SquareSum.bitLength for(c) checker.txt
new file mode 100644
index 0000000..75a9ee0
--- /dev/null
+++ b/src/main/java/io/grpc/examples/p4p/p4p/user/SquareSum.bitLength for(c) checker.txt
@@ -0,0 +1 @@
+i == 1 || i==2 || i ==3 || i==4 || i==5 || i== 10 || i == 20 || i == 30 || i == 40 || i == 45 || i==46 || i==47 || i==48 || i==49 || i==50
\ No newline at end of file
diff --git a/src/java/p4p/user/UserVector.java b/src/main/java/io/grpc/examples/p4p/p4p/user/UserVector.java
similarity index 59%
rename from src/java/p4p/user/UserVector.java
rename to src/main/java/io/grpc/examples/p4p/p4p/user/UserVector.java
index ee06b12..82f0ea2 100644
--- a/src/java/p4p/user/UserVector.java
+++ b/src/main/java/io/grpc/examples/p4p/p4p/user/UserVector.java
@@ -1,21 +1,21 @@
/**
* Copyright (c) 2007 Regents of the University of California.
* All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- *
+ *
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
+ * notice, this list of conditions and the following disclaimer.
+ *
* 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
* 3. The name of the University may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
+ * derived from this software without specific prior written permission.
+ *
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -29,27 +29,27 @@
* SUCH DAMAGE.
*/
-package p4p.user;
+package io.grpc.examples.p4p.p4p.user;
import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.Vector;
-import net.i2p.util.NativeBigInteger;
+import io.grpc.examples.p4p.p4p.util.P4PParameters;
+import io.grpc.examples.p4p.p4p.util.StopWatch;
+import io.grpc.examples.p4p.p4p.util.Util;
+import io.grpc.examples.p4p.net.i2p.util.NativeBigInteger;
-import p4p.util.Util;
-import p4p.util.StopWatch;
-import p4p.util.P4PParameters;
-import p4p.crypto.Proof;
-import p4p.crypto.BitVectorCommitment;
+import io.grpc.examples.p4p.p4p.crypto.Proof;
+import io.grpc.examples.p4p.p4p.crypto.BitVectorCommitment;
/**
* Changes:
- *
- * 10/12/2007: The method implemented in this class is OUT OF DATE. Do NOT
- * use this class.
- * 12/05/2005: Moved to user package.
+ *
+ * 10/12/2007: The method implemented in this class is OUT OF DATE. Do NOT
+ * use this class.
+ * 12/05/2005: Moved to user package.
*/
/**
@@ -59,77 +59,72 @@
* some operations as well as a ZKP that proves the L2 norm of the user vector
* is bounded by L.
*
- * NOTE: The L2-norm bound ZKP implemented in this class is OUT OF DATE. It
+ * NOTE: The L2-norm bound ZKP implemented in this class is OUT OF DATE. It
* should be replaced by the protocol implemented in
*
- * This provides a mapping between the finite field [-F/2, F/2] where our
- * P4P computations are performed and the field of real numbers where many
+ * This provides a mapping between the finite field [-F/2, F/2] where our
+ * P4P computations are performed and the field of real numbers where many
* applications run.
*
* @param data the array of longs to be converted
* @param offset starting position in the array
* @param len then number of elements to be cpnverted.
- * @param F the size of the finite field where private P4P
+ * @param F the size of the finite field where private P4P
* computation is carried out
- * @param R the maximum value of the floating point number that
+ * @param R the maximum value of the floating point number that
* the system supports.
* @return an array of doubles between [-R, R].
*/
- public static double[] itor(long[] data, int offset, int len, long F,
+ public static double[] itor(long[] data, int offset, int len, long F,
double R) {
double [] v = new double[len];
-
+
double alpha = 2.d*R/F;
for(int i = 0; i < len; i++)
v[i] = (double)data[offset+i]*alpha;
-
+
return v;
}
/**
- * Converts the integers in the given array
- * This provides a mapping between the finite field [-F/2, F/2] where our
- * P4P computations are performed and the field of real numbers where many
+ * This provides a mapping between the finite field [-F/2, F/2] where our
+ * P4P computations are performed and the field of real numbers where many
* applications run.
*
* @param data the array of longs to be converted
- * @param F the size of the finite field where private P4P
+ * @param F the size of the finite field where private P4P
* computation is carried out
- * @param R the maximum value of the floating point number that
+ * @param R the maximum value of the floating point number that
* the system supports.
* @return an array of doubles between [-R, R].
*/
@@ -537,53 +527,53 @@ public static double[] itor(long[] data, long F, double R) {
return itor(data, 0, data.length, F, R);
/*
double [] v = new double[data.length];
-
+
double alpha = 2.d*R/F;
for(int i = 0; i < data.length; i++)
v[i] = (double)data[i]*alpha;
-
+
return v;
*/
}
/**
- * Converts the integers in the given array
- * This provides a mapping between the finite field [-F/2, F/2] where our
- * P4P computations are performed and the field of real numbers where many
+ * This provides a mapping between the finite field [-F/2, F/2] where our
+ * P4P computations are performed and the field of real numbers where many
* applications run.
*
* @param data the array of longs to be converted
- * @param F the size of the finite field where private P4P
+ * @param F the size of the finite field where private P4P
* computation is carried out
- * @param R the maximum value of the floating point number that
+ * @param R the maximum value of the floating point number that
* the system supports.
* @return an array of doubles between [-R, R].
*/
public static double[][] itor(long[][] data, long F, double R) {
double [][] v = new double[data.length][data[0].length];
-
+
for(int i = 0; i < data.length; i++)
v[i] = Util.itor(data[i], F, R);
-
+
return v;
}
/**
- * Converts the double precision floating point numbers in the given array
- *
* This provides a mapping between the finite field [-F/2, F/2] where our
@@ -593,40 +583,40 @@ public static double[][] itor(long[][] data, long F, double R) {
* @param data the array of doubles to be converted
* @param offset starting position in the array
* @param len then number of elements to be cpnverted.
- * @param F the size of the finite field where private P4P
+ * @param F the size of the finite field where private P4P
* computation is carried out
- * @param R the maximum value of the floating point number that
+ * @param R the maximum value of the floating point number that
* the system supports.
* @return an array of integers between [-F/2, F/2).
*/
- public static long[] rtoi(double[] data, int offset, int len, long F,
+ public static long[] rtoi(double[] data, int offset, int len, long F,
double R) {
long [] v = new long[len];
-
+
double alpha = 2.d*R/F;
for(int i = 0; i < len; i++)
v[i] = Math.round(data[i+offset]/alpha);
-
+
return v;
}
/**
- * Converts the double precision floating point numbers in the given array
- *
- * This provides a mapping between the finite field [-F/2, F/2] where our
+ * This provides a mapping between the finite field [-F/2, F/2] where our
* P4P computations are performed and the field of real numbers where many
* applications run.
*
* @param data the array of doubles to be converted
- * @param F the size of the finite field where private P4P
+ * @param F the size of the finite field where private P4P
* computation is carried out
- * @param R the maximum value of the floating point number that
+ * @param R the maximum value of the floating point number that
* the system supports.
* @return an array of integers between [-F/2, F/2).
*/
@@ -634,22 +624,22 @@ public static long[] rtoi(double[] data, long F, double R) {
return rtoi(data, 0, data.length, F, R);
/*
long [] v = new long[data.length];
-
+
double alpha = 2.d*R/F;
for(int i = 0; i < data.length; i++)
v[i] = Math.round(data[i]/alpha);
-
+
return v;
*/
}
/**
- * Converts the double precision floating point numbers in the given array
- *
* This provides a mapping between the finite field [-F/2, F/2] where our
@@ -657,42 +647,42 @@ public static long[] rtoi(double[] data, long F, double R) {
* applications run.
*
* @param data the array of doubles to be converted
- * @param F the size of the finite field where private P4P
+ * @param F the size of the finite field where private P4P
* computation is carried out
- * @param R the maximum value of the floating point number that
+ * @param R the maximum value of the floating point number that
* the system supports.
* @return an array of integers of length false if the user is not found in the record.
+ */
+ public boolean disqualifyUser(int user) {
+ return usersMap.remove(user) == null;
+ }
+
+ public int getNQulaifiedUsers() {
+ return usersMap.size();
+ }
+
+ /**
+ * Set the l2 norm proof for the given user.
+ * @param user The user index.
+ * @param proof The proof to set.
+ * @return true if the user is sucessfuly updated.
+ * false if the user is not found in the record.
+ */
+ public boolean setProof(int user, UserVector2.L2NormBoundProof2 proof) {
+ UserInfo userInfo = usersMap.get(user);
+ if(userInfo == null)
+ return false;
+ userInfo.setProof(proof);
+ return true;
+ }
+
+ /**
+ * Sets Y for the given user.
+ * @param user The user index.
+ * @param Y The commitments to the peer's share of the checksums
+ * @return true if the user is sucessfuly updated.
+ * false if the user is not found in the record.
+ */
+ public boolean setY(int user, BigInteger[] Y) {
+ UserInfo userInfo = usersMap.get(user);
+ if(userInfo == null)
+ return false;
+
+ userInfo.setY(Y);
+ return true;
+ }
+
+ /**
+ * Generates challenge vectors.
+ */
+ public void generateChallengeVectors() {
+ // byte[] randBytes = new byte[(int)Math.ceil(2*N*m/8)];
+ byte[] randBytes = new byte[2*((int)Math.ceil(N*m/8)+1)];
+ // We need twice the random bits in c. We need half of them to flip the 1's
+ Util.rand.nextBytes(randBytes);
+ int mid = randBytes.length/2;
+ c = new int[N][];
+ for(int i = 0; i < N; i++) {
+ c[i] = new int[m];
+ for(int j = 0; j < m; j++) {
+ //int byteIndex = (int)2*(i*m + j)/8;
+ //int offset = 2*(i*m + j)%8;
+ int byteIndex = (i*m + j)>>3;
+ int offset = (i*m + j)%8;
+ c[i][j] = (randBytes[byteIndex] & (1<UserVector2
* which is more efficient and secure. This class is kept here for reference
- * purposes only. It is not being maintained and hasn't been throughoutly
+ * purposes only. It is not being maintained and hasn't been throughoutly
* tested. Use UserVector2 instead.
*
* @author ET 10/11/2005
*/
public class UserVector extends P4PParameters {
- protected long[] data_UV = null; // The user data
- protected int dimension = -1; // The dimension of user vector
+ protected long[] data = null; // The user data
+ protected int m = -1; // The dimension of user vector
- protected long F_UV = -1;
- // The order of the (small) finite field over which all the
- // computations are carried out. It should be a prime of
+ protected long F = -1;
+ // The order of the (small) finite field over which all the
+ // computations are carried out. It should be a prime of
// appropriate length (e.g. the length of a long).
- protected int[][] checkCoVector = null; // The checksum coefficient vectors.
+ protected int[][] c = null; // The checksum coefficient vectors.
- protected long L_UV = -1;
- protected int l_UV;
+ protected long L = -1;
+ protected int l;
/**
*/
- public UserVector(long[] data_UV_P, long F_UV_P, int log_2_m_UV_P) {
- if (F_UV_P < 0 || !new BigInteger(new Long(F_UV_P).toString()).isProbablePrime(200))
+ public UserVector(long[] data, long F, int l) {
+ if(F < 0 || !new BigInteger(new Long(F).toString()).isProbablePrime(200))
throw new RuntimeException("Field order must be positive prime.");
- this.data_UV = data_UV_P;
- this.dimension = data_UV_P.length
- ;
- this.F_UV = F_UV_P;
- this.l_UV = log_2_m_UV_P;
- this.L_UV = ((long) 1) << l_UV - 1;
+ this.data = data;
+ this.m = data.length
+ ; this.F = F;
+ this.l = l;
+ this.L = ((long)1)<UserVector2. The privacy peer only
* sets and accesses the v part of the data (by calling
* {@link #setV(long[])}, {@link #getV()} and {@link #getL2NormBoundProof2(boolean)})
* with argument false.
- *
- *
* The server manipulates the u part via {@link #setV(long[])},
* {@link #getV()} and {@link #getL2NormBoundProof2(boolean)} with argument true. In addition, the
* server should receive Y's from the peer and call {@link #setY}
@@ -82,15 +73,15 @@
*/
public class UserVector2 extends UserVector {
- private NativeBigInteger g_UV2 = null;
- private NativeBigInteger h_UV2 = null;
+ private NativeBigInteger g = null;
+ private NativeBigInteger h = null;
//private SquareCommitment sc = null;
/**
* Constructs a (share of) user vector.
*
* @param data the user vector
- * @param F_UV_p the size of the field where all user computations are
+ * @param F the size of the field where all user computations are
* performed
* @param l the max allowed number of bits of the L2 norm of user
* vector
@@ -98,64 +89,48 @@ public class UserVector2 extends UserVector {
* @param h the sceond generator used in commitment
*
*/
- public UserVector2(long[] data, long F_UV_p, int l, NativeBigInteger g,
+ public UserVector2(long[] data, long F, int l, NativeBigInteger g,
NativeBigInteger h) {
- super(data, F_UV_p, l);
- this.g_UV2 = g;
- this.h_UV2 = h;
+ super(data, F, l);
+ this. g = g;
+ this.h = h;
//sc = new SquareCommitment(g, h);
}
- public UserVector2(int m, long FieldSize_larger_than_bitLength_UV2, int log_2_m_UV2_P, NativeBigInteger g_UV2_P,
- NativeBigInteger h_UV2_P) {
- super(m, FieldSize_larger_than_bitLength_UV2, log_2_m_UV2_P);
- this.g_UV2 = g_UV2_P;
- this.h_UV2 = h_UV2_P;
+ public UserVector2(int m, long F, int l, NativeBigInteger g,
+ NativeBigInteger h) {
+ super(m, F, l);
+ this. g = g;
+ this.h = h;
//sc = new SquareCommitment(g, h);
}
/**
*/
- public void setData(long[] data_UV2_P) {
- this.data_UV = data_UV2_P;
- if(dimension == -1)
- dimension = data_UV2_P.length;
+ public void setData(long[] data) {
+ this.data = data;
+ if(m == -1)
+ m = data.length;
}
- private long [] serverUserVector_UV2 = null; // Server's share of user vector
- private long [] peerVector_UV2 = null; // Privacy peer's share of user vector
+ private long [] u = null; // Server's share of user vector
+ private long [] v = null; // Privacy peer's share of user vector
/**
* Generates the shares of the user vector.
*/
- // iterate through dimensions
- // generate server & peer vectors
public void generateShares() {
- if(serverUserVector_UV2 == null) {
- serverUserVector_UV2 = new long[dimension];
- peerVector_UV2 = new long[dimension];
+ if(u == null) {
+ u = new long[m];
+ v = new long[m];
+ }
+
+ u = Util.randVector(m, F, 0);
+ for(int i = 0; i < m; i++) {
+ v[i] = Util.mod(data[i] - u[i], F);
+ assert (data[i] == Util.mod(u[i] + v[i], F));
}
- // 1. serverUVector
- serverUserVector_UV2 = Util.randVector(dimension, F_UV, 0);
-
- boolean data_equal_mod_uv2;
- boolean [] data_equal_mod_array_uv2 = new boolean[dimension];
- int generate_shares_ui = 0;
- for(generate_shares_ui = 0; generate_shares_ui < dimension; generate_shares_ui++) {
-
- // 2. peerUVector = mod(dataUV[]-serverVector, F
- //
- // if(data_UV[i] == Util.mod(serverV[i] + peerV[i], F))
- peerVector_UV2[generate_shares_ui] = Util.mod(data_UV[generate_shares_ui] - serverUserVector_UV2[generate_shares_ui], F_UV);
-
- if(data_UV[generate_shares_ui] == Util.mod(serverUserVector_UV2[generate_shares_ui] + peerVector_UV2[generate_shares_ui], F_UV)){
- data_equal_mod_uv2 = true;
- data_equal_mod_array_uv2[generate_shares_ui] = data_equal_mod_uv2;
- }
- assert (data_UV[generate_shares_ui] == Util.mod(serverUserVector_UV2[generate_shares_ui] + peerVector_UV2[generate_shares_ui], F_UV));
- System.out.println("after assert in GenerateShares UV2");
- } // for 10 dimension, assert(data==mod)
}
@@ -163,14 +138,14 @@ public void generateShares() {
* Returns the server share.
*/
public long[] getU() {
- return serverUserVector_UV2;
+ return u;
}
/**
* Returns the peer share.
*/
public long[] getV() {
- return peerVector_UV2;
+ return v;
}
@@ -178,11 +153,11 @@ public long[] getV() {
* Sets the server share. This is useful for server-side manipulation,
* e.g. verifying the server-side proof.
*
- * @param u_U2 the vector
+ * @param u the vector
*
*/
- public void setU(long[] u_U2) {
- this.serverUserVector_UV2 = u_U2;
+ public void setU(long[] u) {
+ this.u = u;
}
@@ -194,7 +169,7 @@ public void setU(long[] u_U2) {
*
*/
public void setV(long[] v) {
- this.peerVector_UV2 = v;
+ this.v = v;
}
@@ -243,7 +218,7 @@ public void setV(long[] v) {
*
*
*
*
@@ -255,6 +230,11 @@ public void setV(long[] v) {
* BigInteger array
* mdCorrector and accessed via {@link #getMdCorrector()}.
* They are sent to the server only.Y and pass it to the server.
*/
- private BigInteger[] Y_peer_UV2 = null;
- // The peer share of the checksums. Put it here for tes
+ private BigInteger[] Y = null;
+ // The peer share of the checksums. Put it here for test
public boolean verify2(Proof proof) {
L2NormBoundProof2 l2Proof = (L2NormBoundProof2)proof;
if(l2Proof.isForServer())
- return serverVerify_uv2(l2Proof, Y_peer_UV2);
+ return serverVerify(l2Proof, Y);
else
- return peerVerify_uv2(l2Proof);
+ return peerVerify(l2Proof);
}
/**
* Call this method to set the commitments to the y's, which should be
* verified by the peer and passed to the server.
*/
- public void setY_UV2(BigInteger[] Y_U2) {
- this.Y_peer_UV2 = Y_U2;
+ public void setY(BigInteger[] Y) {
+ this.Y = Y;
}
- public BigInteger[] getY_UV2() {
- return Y_peer_UV2;
+ public BigInteger[] getY() {
+ return Y;
}
- protected boolean peerVerify_uv2(L2NormBoundProof2 l2Proof) {
- long[] y_checksums_l2Proof = l2Proof.getChecksums();
- System.out.println("peerVerify_uv2: [y.length] "+ String.valueOf(y_checksums_l2Proof.length));
+ protected boolean peerVerify(L2NormBoundProof2 l2Proof) {
+ long[] y = l2Proof.getChecksums();
// This is only getting the peer's share of the checksums.
BigInteger[] r = l2Proof.getChecksumRandomness();
- Y_peer_UV2 = new BigInteger[y_checksums_l2Proof.length]; // The commitments to the checksums
+ Y = new BigInteger[y.length]; // The commitments to the checksums
// Peer just computes the commitments to the checksums
- Commitment cm = new Commitment(g_UV2, h_UV2);
- for(int i = 0; i < y_checksums_l2Proof.length; i++) {
- y_checksums_l2Proof[i] = Util.mod(Util.innerProduct(checkCoVector[i], peerVector_UV2), F_UV);
- Y_peer_UV2[i] =
- cm.commit(new BigInteger(new Long(y_checksums_l2Proof[i]).toString()),
- // The checksum
- r[i]); // The randomness
+ Commitment cm = new Commitment(g, h);
+ for(int i = 0; i < y.length; i++) {
+ y[i] = Util.mod(Util.innerProduct(c[i], v), F);
+ Y[i] =
+ cm.commit(new BigInteger(new Long(y[i]).toString()),
+ // The checksum
+ r[i]); // The randomness
}
return true;
}
- public boolean serverVerify_uv2(L2NormBoundProof2 l2Proof, BigInteger[] Y_UV2_serverV_P) {
- System.out.println("serverVerify_uv2: "+ Arrays.toString(Y_UV2_serverV_P));
- if(Y_UV2_serverV_P == null)
+ public boolean serverVerify(L2NormBoundProof2 l2Proof, BigInteger[] Y) {
+ if(Y == null)
throw new RuntimeException("Must perform peer verification first!");
BitCommitment.BitCommitmentProof[] bcProofs =
- l2Proof.getBitCommitmentProofs();
+ l2Proof.getBitCommitmentProofs();
SquareCommitment.SquareCommitmentProof[] scProofs =
- l2Proof.getSquareCommitmentProofs();
+ l2Proof.getSquareCommitmentProofs();
ThreeWayCommitment.ThreeWayCommitmentProof[] tcProofs =
- l2Proof.getThreeWayCommitmentProofs();
+ l2Proof.getThreeWayCommitmentProofs();
long[] x = l2Proof.getChecksums();
// This is only getting the server's share of the checksums.
- BigInteger[] r_checksum_randomness_l2Proof = l2Proof.getChecksumRandomness();
- BigInteger[] X_checksums = new BigInteger[x.length];
+ BigInteger[] r = l2Proof.getChecksumRandomness();
+ BigInteger[] X = new BigInteger[x.length];
// The commitments to the checksums
- BigInteger[] S_checksums = new BigInteger[x.length];
+ BigInteger[] S = new BigInteger[x.length];
// The commitments to s
- BigInteger[] B_MdCorrector_l2Proof = l2Proof.getMdCorrector();
+ BigInteger[] B = l2Proof.getMdCorrector();
// The Bs
// Check the checksums and their commitments:
- Commitment cm = new Commitment(g_UV2, h_UV2);
- ThreeWayCommitment tc = new ThreeWayCommitment(g_UV2, h_UV2, F_UV);
+ Commitment cm = new Commitment(g, h);
+ ThreeWayCommitment tc = new ThreeWayCommitment(g, h, F);
for(int i = 0; i < x.length; i++) {
// First make sure the checksums are computed correctly:
//if(s[i] != Math.abs(Util.innerProduct(c[i], data))) {
- if(x[i] != Util.mod(Util.innerProduct(checkCoVector[i], serverUserVector_UV2), F_UV)) {
+ if(x[i] != Util.mod(Util.innerProduct(c[i], u), F)) {
// We are doing server
System.out.println("Checksum " + i
- + " not computed correctly!");
+ + " not computed correctly!");
return false;
}
// Now check if the modular correctors, the Bs, are computed correctly
- if(!B_MdCorrector_l2Proof[i].equals(tcProofs[i].getCommitment()[0])) {
+ if(!B[i].equals(tcProofs[i].getCommitment()[0])) {
System.out.println("B[" + i + "]"
- + " not computed correctly!");
+ + " not computed correctly!");
return false;
}
// Check the 3-way proofs
if(!tc.verify(tcProofs[i])) {
System.out.println("3-Way proof " + i
- + " not computed correctly!");
+ + " not computed correctly!");
return false;
}
- X_checksums[i] =
- cm.commit(new BigInteger(new Long(x[i]).toString()).mod(q),
- // The checksum
- r_checksum_randomness_l2Proof[i]); // The randomness
- S_checksums[i] = X_checksums[i].multiply(B_MdCorrector_l2Proof[i]).mod(p).multiply(Y_UV2_serverV_P[i]).mod(p);
+ X[i] =
+ cm.commit(new BigInteger(new Long(x[i]).toString()).mod(P4PParameters.q),
+ // The checksum
+ r[i]); // The randomness
+ S[i] = X[i].multiply(B[i]).mod(P4PParameters.p).multiply(Y[i]).mod(P4PParameters.p);
}
// Next check that the sum of squares does not have excessive bits:
- if(bcProofs.length > Integer.toBinaryString(checkCoVector.length).length()+2*l_UV) {
+ int BL = bcProofs.length; // numBits, squareSum =
+ int CLA2l = Integer.toBinaryString(c.length).length()+2*l; //86
+ P4PParameters.DEBUG("BL: " + BL + "CLA2L: "+CLA2l);
+ if(bcProofs.length > Integer.toBinaryString(c.length).length()+2*l){
System.out.println("Sum of squares has too many bits: "
- + bcProofs.length
- + ", the limit is "
- + (Integer.toBinaryString(checkCoVector.length).length()+2*l_UV));
+ + bcProofs.length
+ + ", the limit is "
+ + (Integer.toBinaryString(c.length).length()+2*l));
+
return false;
}
// Check the square proofs:
- SquareCommitment sc = new SquareCommitment(g_UV2, h_UV2);
+ SquareCommitment sc = new SquareCommitment(g, h);
for(int i = 0; i < scProofs.length; i++) {
// First check that the square commitment encodes the correct
// number i.e. the A in scProofs is the commitment to s.
- if(!scProofs[i].getCommitment()[0].equals(S_checksums[i])) {
+ if(!scProofs[i].getCommitment()[0].equals(S[i])) {
System.out.println("S[" + i + "] computed incroorectly.");
return false;
}
@@ -751,27 +749,27 @@ public boolean serverVerify_uv2(L2NormBoundProof2 l2Proof, BigInteger[] Y_UV2_se
// computed correctly:
BigInteger z = BigInteger.ONE;
for(int i = 0; i < scProofs.length; i++) {
- z = z.multiply(scProofs[i].getCommitment()[1]).mod(p); // *= B
+ z = z.multiply(scProofs[i].getCommitment()[1]).mod(P4PParameters.p); // *= B
}
- z = z.multiply(z).mod(p); // commitment[0] actually stores 2X
+ z = z.multiply(z).mod(P4PParameters.p); // commitment[0] actually stores 2X
if(!l2Proof.getCommitment()[0].equals(z)) {
System.out.println("Commitment to square sum wasn't computed "
- + "correctly.");
+ + "correctly.");
return false;
}
// Then check each bits
- BitCommitment bc = new BitCommitment(g_UV2, h_UV2);
+ BitCommitment bc = new BitCommitment(g, h);
BigInteger zz = BigInteger.ONE;
- DEBUG("Checking " + bcProofs.length + " bit commitments");
+ P4PParameters.DEBUG("Checking " + bcProofs.length + " bit commitments");
BigInteger ZZ = BigInteger.ONE;
for(int i = 0; i < bcProofs.length; i++) {
if(!bc.verify(bcProofs[i])) {
System.out.println("Bit commitment verification " + i
- + " failed.");
+ + " failed.");
return false;
}
@@ -781,8 +779,8 @@ public boolean serverVerify_uv2(L2NormBoundProof2 l2Proof, BigInteger[] Y_UV2_se
// enough bits!
NativeBigInteger Z =
- (NativeBigInteger)bcProofs[i].getCommitment()[0];
- ZZ = ZZ.multiply(Z.modPow(e, p)).mod(p);
+ (NativeBigInteger)bcProofs[i].getCommitment()[0];
+ ZZ = ZZ.multiply(Z.modPow(e, P4PParameters.p)).mod(P4PParameters.p);
}
if(!ZZ.equals(z)) {
@@ -792,253 +790,5 @@ public boolean serverVerify_uv2(L2NormBoundProof2 l2Proof, BigInteger[] Y_UV2_se
return true;
}
-
-
- /**
- * Test the UserVector L2 norm bound ZKP.
- */
- public static void main(String[] args) {
- int k = 512;
- int m = 10;
- int nLoops = 10;
- int l = 40;
- boolean doBench = false;
- boolean worstcase = false;
- // test the worst case cost. i.e. every vector should pass. this is
- // when the verifier spends longest time.
-
- // Definie the number of iterations that the bound ZKP must have:
- int zkpIterations = 50; // This is the N in the paper
-
- for (int i = 0; i < args.length; ) {
- String arg = args[i++];
- if(arg.length() > 0 && arg.charAt(0) == '-') {
- if (arg.equals("-k")) {
- try {
- k = Integer.parseInt(args[i++]);
- }
- catch (NumberFormatException e) {
- k = 512;
- }
- }
- else if(arg.equals("-m")) {
- try {
- m = Integer.parseInt(args[i++]);
- }
- catch (NumberFormatException e) {
- m = 10;
- }
- }
- else if(arg.equals("-N")) {
- try {
- zkpIterations = Integer.parseInt(args[i++]);
- }
- catch (NumberFormatException e) {
- zkpIterations = 50;
- }
- }
-
- else if(arg.equals("-o")) {
- try {
- nLoops = Integer.parseInt(args[i++]);
- }
- catch (NumberFormatException e) {
- nLoops = 10;
- }
- }
-
- else if(arg.equals("-l")) {
- try {
- l = Integer.parseInt(args[i++]);
- if(l > 52) {
- System.out.println("The system does not support l > 52. This will make "
- + "the field order too high so that it is not a small"
- + " field any more.");
- System.exit(0);
- }
- }
- catch (NumberFormatException e) {
- l = 40;
- }
- }
-
- else if(arg.equals("-d")) {
- debug = true;
- }
- else if(arg.equals("-w")) {
- worstcase = true;
- // test the worst case cost. i.e. every vector should pass.
- // this is when the verifier spends longest time.
- }
- else if(arg.equals("-bench")) {
- doBench = true;
- }
- }
- }
-
- System.out.println("k = " + k);
- System.out.println("m = " + m);
- System.out.println("nLoops = " + nLoops);
-
- // Setup the parameters:
- P4PParameters.initialize(k, false);
- SecureRandom rand = null;
- try {
- rand = SecureRandom.getInstance("SHA1PRNG");
- }
- catch(java.security.NoSuchAlgorithmException e) {
- System.err.println("NoSuchAlgorithmException!");
- e.printStackTrace();
- rand = new SecureRandom();
- }
-
- rand.nextBoolean();
-
- // Lets make l = log_2 (m)
- long L = ((long)2)<BigInteger between 1 to n-1, inclusive.
- *
- * @param set_size the size of the set
+ * Randomly generates a BigInteger between 1 to n-1, inclusive.
+ *
+ * @param m the size of the set
* @return a BigInteger uniformly randomly distributed between [1, n-1]
*/
- public static BigInteger randomBigInteger(BigInteger set_size) {
+ public static BigInteger randomBigInteger(BigInteger m) {
while(true) {
- BigInteger r = new BigInteger(set_size.bitLength()+close_t_uniform_q_minus_1, rand);
+ BigInteger r = new BigInteger(m.bitLength()+t, rand);
if(!r.equals(BigInteger.ZERO))
- return r.mod(set_size);
+ return r.mod(m);
}
}
/**
- * A hash function mapping the message to an element in Z_q. We just
- * compute SHA-512 hash of the messages and catenate them until we have
+ * A hash function mapping the message to an element in Z_q. We just
+ * compute SHA-512 hash of the messages and catenate them until we have
* enough bits.
*
* @param msg the array of messages
@@ -83,30 +80,30 @@ public static BigInteger randomBigInteger(BigInteger set_size) {
* @return an element in Z_q which is a hash of the given messages.
*
*/
- public static BigInteger secureHash(BigInteger[] msg, BigInteger size_set_secureHash)
- throws GeneralSecurityException {
+ public static BigInteger secureHash(BigInteger[] msg, BigInteger q)
+ throws GeneralSecurityException {
MessageDigest md = MessageDigest.getInstance("SHA-512");
- final int HASH_LENGTH = md.getDigestLength();
+ final int HASH_LENGTH = md.getDigestLength();
// The length of the hash in bytes
- int k = size_set_secureHash.bitLength()+1;
+ int k = q.bitLength()+1;
// The required length of output in bits
-
- int nRounds = k/(HASH_LENGTH*8+close_t_uniform_q_minus_1)+1;
+
+ int nRounds = k/(HASH_LENGTH*8+t)+1;
byte[] hash = new byte[HASH_LENGTH*nRounds];
-
+
for(int i = 0; i < nRounds; i++) {
md.reset();
for(int j = 0; j < msg.length; j++)
md.update(msg[j].toByteArray()); // hash all the messages
-
+
md.update((byte)i); // Also include the current index
md.digest(hash, i*HASH_LENGTH, HASH_LENGTH);
}
-
+
// Now we got all the bits. Make a BigInteger out of it:
- return new BigInteger(hash).mod(size_set_secureHash);
+ return new BigInteger(hash).mod(q);
}
-
+
/**
* Converts a short into its little-endian byte string representation.
@@ -119,7 +116,7 @@ public static void bytesFromShort(byte[] array, int offset, short value) {
array[offset+0] = (byte) ((value>>0)&0xFF);
array[offset+1] = (byte) ((value>>8)&0xFF);
}
-
+
/**
* Converts an int into its little-endian byte string representation.
*
@@ -133,7 +130,7 @@ public static void bytesFromInt(byte[] array, int offset, int value) {
array[offset+2] = (byte) ((value>>16)&0xFF);
array[offset+3] = (byte) ((value>>24)&0xFF);
}
-
+
/**
* Converts an int into its little-endian byte string representation, and
* return an array containing it.
@@ -146,7 +143,7 @@ public static byte[] bytesFromInt(int value) {
bytesFromInt(array, 0, value);
return array;
}
-
+
/**
* Converts an int into a little-endian byte string representation of the
* specified length.
@@ -159,17 +156,17 @@ public static byte[] bytesFromInt(int value) {
public static void bytesFromInt(byte[] array, int offset,
int length, int value) {
assert(length==1 || length==2 || length==4);
-
+
switch (length) {
- case 1:
- array[offset] = (byte) value;
- break;
- case 2:
- bytesFromShort(array, offset, (short) value);
- break;
- case 4:
- bytesFromInt(array, offset, value);
- break;
+ case 1:
+ array[offset] = (byte) value;
+ break;
+ case 2:
+ bytesFromShort(array, offset, (short) value);
+ break;
+ case 4:
+ bytesFromInt(array, offset, value);
+ break;
}
}
@@ -202,9 +199,9 @@ public static void bytesFromLong(byte[] array, int offset, long value) {
*/
public static short bytesToShort(byte[] array, int offset) {
return (short) ((((short) array[offset+0] & 0xFF) << 0) |
- (((short) array[offset+1] & 0xFF) << 8));
+ (((short) array[offset+1] & 0xFF) << 8));
}
-
+
/**
* Converts to an unsigned short from its little-endian byte string
* representation.
@@ -216,7 +213,7 @@ public static short bytesToShort(byte[] array, int offset) {
public static int bytesToUnsignedShort(byte[] array, int offset) {
return (((int) bytesToShort(array, offset)) & 0xFFFF);
}
-
+
/**
* Converts to an int from its little-endian byte string representation.
*
@@ -226,11 +223,11 @@ public static int bytesToUnsignedShort(byte[] array, int offset) {
*/
public static int bytesToInt(byte[] array, int offset) {
return (int) ((((int) array[offset+0] & 0xFF) << 0) |
- (((int) array[offset+1] & 0xFF) << 8) |
- (((int) array[offset+2] & 0xFF) << 16) |
- (((int) array[offset+3] & 0xFF) << 24));
+ (((int) array[offset+1] & 0xFF) << 8) |
+ (((int) array[offset+2] & 0xFF) << 16) |
+ (((int) array[offset+3] & 0xFF) << 24));
}
-
+
/**
* Converts to an int from a little-endian byte string representation of the
* specified length.
@@ -242,16 +239,16 @@ public static int bytesToInt(byte[] array, int offset) {
*/
public static int bytesToInt(byte[] array, int offset, int length) {
assert(length==1 || length==2 || length==4);
-
+
switch (length) {
- case 1:
- return array[offset];
- case 2:
- return bytesToShort(array, offset);
- case 4:
- return bytesToInt(array, offset);
- default:
- return -1;
+ case 1:
+ return array[offset];
+ case 2:
+ return bytesToShort(array, offset);
+ case 4:
+ return bytesToInt(array, offset);
+ default:
+ return -1;
}
}
@@ -270,11 +267,11 @@ public static String bytesToString(byte[] array, int offset, int length) {
if (array[offset+i] == 0)
break;
}
-
+
return new String(array, offset, i);
}
-
- /**
+
+ /**
* Masks out and shifts a bit substring.
*
* @param bits the bit string.
@@ -288,8 +285,8 @@ public static int extract(int bits, int lowest, int size) {
else
return ((bits >> lowest) & ((1<v1 and v2
- * @throws IllegalArgumentException if the dimesionalities of the two
+ * @throws IllegalArgumentException if the dimesionalities of the two
* vectors do not match.
*/
-
+
public static long innerProduct(long[] v1, long[] v2) {
- if(v1.length != v2.length)
+ if(v1.length != v2.length)
throw new IllegalArgumentException("dimesionalities do not match!");
- long s = 0;
+ long s = 0;
for(int i = 0; i < v1.length; i++)
s += v1[i]*v2[i];
-
+
return s;
}
-
+
/**
* Computes the inner product of one integer array and one long array.
*
* @param v1 the integer vector
* @param v2 the long vector
* @return inner product of v1 and v2
- * @throws RuntimeException if the dimesionalities of the two vectors do
+ * @throws RuntimeException if the dimesionalities of the two vectors do
* not match.
*/
public static long innerProduct(int[] v1, long[] v2) {
- if(v1.length != v2.length)
+ if(v1.length != v2.length)
throw new RuntimeException("dimesionalities do not match!");
- long s = 0;
+ long s = 0;
for(int i = 0; i < v1.length; i++)
s += v1[i]*v2[i];
-
+
return s;
}
@@ -415,31 +412,31 @@ public static long innerProduct(int[] v1, long[] v2) {
* @param v1 one double vector
* @param v2 the other double vector
* @return inner product of v1 and v2
- * @throws RuntimeException if the dimesionalities of the two vectors do
+ * @throws RuntimeException if the dimesionalities of the two vectors do
* not match.
*/
public static double innerProduct(double[] v1, double[] v2) {
- if(v1.length != v2.length)
+ if(v1.length != v2.length)
throw new RuntimeException("dimesionalities do not match!");
double s = 0;
for(int i = 0; i < v1.length; i++)
s += v1[i]*v2[i];
-
+
return s;
}
/**
- * A java and simplified version of daxpy, constant times a vector plus a
- * vector. Unlike its BLAS counterpart, it does NOT use unrolled loop. This
+ * A java and simplified version of daxpy, constant times a vector plus a
+ * vector. Unlike its BLAS counterpart, it does NOT use unrolled loop. This
* function is for verifying the computation. NO optimization is done.
- *
+ *
*
* This function does
*
* y = a*x + y
*
- * where a is a scaler and x, y are vectors.
+ * where a is a scaler and x, y are vectors.
*
*/
public static void laxpy(long a, long[] x, long[] y) {
@@ -456,80 +453,73 @@ public static void laxpy(double a, double[] x, double[] y) {
/**
- * Returns a number whose value is between [-m/2, m/2) and differs
+ * Returns a number whose value is between [-m/2, m/2) and differs
* from data by a multiple of m.
*
- * @param data_long_integer_mod a long integer.
- * @param modulus the modulus.
+ * @param data a long integer.
+ * @param m the modulus.
* @return a number between [-m/2, m/2) that differs from data by a multiple of m.
*/
- public static long mod(long data_long_integer_mod, long modulus) {
- long mod_result_long = data_long_integer_mod % modulus;
- if(mod_result_long < 0){
- mod_result_long += modulus;
- }
-
-
- double upperBound = Math.floor((double)modulus/2.);
- if(mod_result_long >= Math.floor((double)modulus/2.)){
- mod_result_long -= modulus;
- }
-
- return mod_result_long;
+ public static long mod(long data, long m) {
+ long r = data%m;
+ if(r < 0) r += m;
+ if(r >= Math.floor((double)m/2.))
+ r -= m;
+ return r;
}
/**
- * Converts the integers in the given array data into double
- * precision floating point numbers. The integers should be between
+ * Converts the integers in the given array data into double
+ * precision floating point numbers. The integers should be between
*
* [-floor(F/2), floor(F/2)] if F is odd
* [-floor(F/2), floor(F/2)-1] if F is even
- *
+ *
* and the real numbers will be between [-R, R].
* data into double
- * precision floating point numbers. The integers should be between
+ * Converts the integers in the given array data into double
+ * precision floating point numbers. The integers should be between
*
* [-floor(F/2), floor(F/2)] if F is odd
* [-floor(F/2), floor(F/2)-1] if F is even
- *
+ *
* and the real numbers will be between [-R, R].
* data into double
- * precision floating point numbers. The integers should be between
+ * Converts the integers in the given array data into double
+ * precision floating point numbers. The integers should be between
*
* [-floor(F/2), floor(F/2)] if F is odd
* [-floor(F/2), floor(F/2)-1] if F is even
- *
+ *
* and the real numbers will be between [-R, R].
* data into integers field. The integers should be between
+ * Converts the double precision floating point numbers in the given array
+ * data into integers field. The integers should be between
*
* [-floor(F/2), floor(F/2)] if F is odd
* [-floor(F/2), floor(F/2)-1] if F is even
- *
+ *
* and the real numbers will be between [-R, R].
* data into integers field. The integers should be between
+ * Converts the double precision floating point numbers in the given array
+ * data into integers field. The integers should be between
*
* [-floor(F/2), floor(F/2)] if F is odd
* [-floor(F/2), floor(F/2)-1] if F is even
- *
+ *
* and the real numbers will be between [-R, R].
* data into integers field. The integers should be between
+ * Converts the double precision floating point numbers in the given array
+ * data into integers field. The integers should be between
*
* [-floor(F/2), floor(F/2)] if F is odd
* [-floor(F/2), floor(F/2)-1] if F is even
- *
+ *
* and the real numbers will be between [-R, R].
* len between [-F/2, F/2).
*/
public static long[][] rtoi(double[][] data, long F, double R) {
long [][] v = new long[data.length][data[0].length];
-
+
for(int i = 0; i < data.length; i++)
v[i] = Util.rtoi(data[i], F, R);
-
+
return v;
}
-
+
/**
* Returns the minimum value in the given double array.
*
- * @param data the array of doubles
+ * @param data the array of doubles
* @return the minimum value in data
*/
public static double min(double[] data) {
- double min = Double.MAX_VALUE;
+ double min = Double.MAX_VALUE;
for(int i = 0; i < data.length; i++)
min = min > data[i] ? data[i] : min;
return min;
}
-
+
/**
* Returns the maximum value in the given double array.
*
- * @param data the array of doubles
+ * @param data the array of doubles
* @return the maximum value in data
*/
public static double max(double[] data) {
- double max = Double.MIN_VALUE;
+ double max = Double.MIN_VALUE;
for(int i = 0; i < data.length; i++)
max = max < data[i] ? data[i] : max;
return max;
@@ -701,29 +691,29 @@ public static double max(double[] data) {
/**
* Returns the maximum value in the given double array.
*
- * @param data the array of doubles
+ * @param data the array of doubles
* @return the maximum value in data
*/
public static double max(double[][] data) {
- double max = Double.MIN_VALUE;
+ double max = Double.MIN_VALUE;
for(int i = 0; i < data.length; i++) {
double mx = Util.max(data[i]);
max = max < mx ? mx : max;
}
return max;
}
-
+
/**
* Returns the maximum absolute value in the given double array.
*
- * @param data_array_double the array of doubles
+ * @param data the array of doubles
* @return the maximum absolute value in data
*/
- public static double maxAbs(double[] data_array_double) {
- return maxAbs(data_array_double, 0, data_array_double.length);
+ public static double maxAbs(double[] data) {
+ return maxAbs(data, 0, data.length);
/*
- double max = 0.;
+ double max = 0.;
for(int i = 0; i < data.length; i++) {
double mx = Math.abs(data[i]);
max = max < mx ? mx : max;
@@ -736,151 +726,146 @@ public static double maxAbs(double[] data_array_double) {
/**
* Returns the maximum absolute value in the given long array.
*
- * @param data the array of longs
+ * @param data the array of longs
* @return the maximum absolute value in data
*/
public static long maxAbs(long[] data) {
// return maxAbs(data, 0, data.length);
-
- long max = 0;
+
+ long max = 0;
for(int i = 0; i < data.length; i++) {
long mx = (long)Math.abs(data[i]);
max = max < mx ? mx : max;
}
return max;
-
+
}
-
+
/**
* Returns the maximum absolute value in the given long array.
*
- * @param data the array of longs
+ * @param data the array of longs
* @return the maximum absolute value in data
*/
public static long maxAbs(long[] data, int offset, int len) {
- long max = 0;
+ long max = 0;
for(int i = 0; i < len; i++) {
long mx = (long)Math.abs(data[offset+i]);
max = max < mx ? mx : max;
}
return max;
}
-
+
public static double maxAbs(double[] data, int offset, int len) {
- double max = 0.;
+ double max = 0.;
for(int i = 0; i < len; i++) {
double mx = Math.abs(data[offset+i]);
max = max < mx ? mx : max;
}
return max;
}
-
+
/**
* Returns the maximum absolute value in the given double array.
*
- * @param data_array_double the array of doubles
+ * @param data the array of doubles
* @return the maximum absolute value in data
*/
- public static double maxAbs(double[][] data_array_double) {
- double max = 0.;
- for(int i = 0; i < data_array_double.length; i++) {
- double mx = Util.maxAbs(data_array_double[i]);
+ public static double maxAbs(double[][] data) {
+ double max = 0.;
+ for(int i = 0; i < data.length; i++) {
+ double mx = Util.maxAbs(data[i]);
max = max < mx ? mx : max;
}
return max;
}
-
+
/**
* Returns the maximum value in the given long array.
*
- * @param data_arrays_long the array of longs
+ * @param data the array of longs
* @return the maximum value in data
*/
- public static long max(long[] data_arrays_long) {
- long max = Long.MIN_VALUE;
- for(int i = 0; i < data_arrays_long.length; i++)
- max = max < data_arrays_long[i] ? data_arrays_long[i] : max;
+ public static long max(long[] data) {
+ long max = Long.MIN_VALUE;
+ for(int i = 0; i < data.length; i++)
+ max = max < data[i] ? data[i] : max;
return max;
}
/**
* Generates a random vector in Z_F with approximately the given L2-norm.
* The algorithm is as follows: first a random m-dimensional vector over
- * Z_F is generated by selecting each elements randomly from Z_F. The
- * vector is then scaled to the desired length, rounding each element to
- * the nearest long. Note that Z_F is defined as
+ * Z_F is generated by selecting each elements randomly from Z_F. The
+ * vector is then scaled to the desired length, rounding each element to
+ * the nearest long. Note that Z_F is defined as
*
* [-floor(F/2), floor(F/2)] if F is odd
- * [-floor(F/2), floor(F/2)-1] if F is even
+ * [-floor(F/2), floor(F/2)-1] if F is even
*
- *
- * NOTE:
- * F is to big. A random vector generated this way is so big
+ *
+ * NOTE:
+ * F is to big. A random vector generated this way is so big
* that the scaling factor is essentially 0, resulting in a zero
- * vector. Instead, we restrict each element between [-L, L]. We
+ * vector. Instead, we restrict each element between [-L, L]. We
* are choosing from a set with (2L)^m elements, instead of F^m,
- * where L is chosen to be 1000. This function is only for test.
- * Should be OK.
- * @param dimension the dimensionality of the vector
- * @param Z_F_order_of_Group_Util the order of the group Z_F
- * @param l2_norm_5dot49755813888E11 the desired l2-norm of the vector. If it is 0, then a random
+ * where L is chosen to be 1000. This function is only for test.
+ * Should be OK.
+ * @param m the dimensionality of the vector
+ * @param F the order of the group Z_F
+ * @param l2 the desired l2-norm of the vector. If it is 0, then a random
* vector in (Z_F)^m is generated.
* @return a random vector over Z_F L2-norm equal l2
*/
-// order of Z_F
- public static long[] randVector(int dimension, long Z_F_order_of_Group_Util_RandV_long, double l2_norm_5dot49_Util_randVector) {
- long[] data_Util_randVector = new long[dimension];
+
+ public static long[] randVector(int m, long F, double l2) {
+ long[] data = new long[m];
BigInteger bigF = null;
- if(l2_norm_5dot49_Util_randVector <=0){
- bigF = new BigInteger(Long.toString(Z_F_order_of_Group_Util_RandV_long));
- }
- double myL2_square = 0.;
- int L_10000 = 10000;
- int[] l2_positive_counter_for_10_dimension = new int[2];
- for(int dimension_id = 0; dimension_id < dimension; dimension_id++) {
- if(l2_norm_5dot49_Util_randVector > 0) {
- data_Util_randVector[dimension_id] = rand.nextInt(2*L_10000+1)-L_10000;
- myL2_square += (double)((double)data_Util_randVector[dimension_id]*(double)data_Util_randVector[dimension_id]);
- l2_positive_counter_for_10_dimension[0]++;
+ if(l2 <=0) bigF = new BigInteger(Long.toString(F));
+ double myL2 = 0.;
+ int L = 10000;
+ for(int i = 0; i < m; i++) {
+ if(l2 > 0) {
+ /**
+ * NOTE: F is to big. A random vector generated this way is so
+ * big that the scaling factor is essentially 0, resulting in a
+ * zero vector. Instead, we restrict each element between
+ * [-L, L]. We are choosing from a set with (2L)^m elements,
+ * instead of F^m. This function is only for testing. Should be
+ * OK.
+ */
+ data[i] = rand.nextInt(2*L+1)-L;
+ myL2 += (double)((double)data[i]*(double)data[i]);
+ /**
+ * Let dmax = Double.MAX_VALUE = 1.7976931348623157E308 and
+ * lmax = Long.MAX_VALUE = 9223372036854775807L. The maximum
+ * L2-norm of data can be m*(lmax*lmax) = 8.5071e+037. Using a
+ * double to hold the value, m can be as large as 2.1132e+270.
+ * More than enough for our purpose and no overflow would
+ * happen.
+ */
}
else {
- data_Util_randVector[dimension_id] = randomBigInteger(bigF).longValue();
+ data[i] = randomBigInteger(bigF).longValue();
// A random long in [0, F-1]
- data_Util_randVector[dimension_id] -= Math.floor((double) Z_F_order_of_Group_Util_RandV_long / 2.);
+ data[i] -= Math.floor((double)F/2.);
// Shift to Z_F
- l2_positive_counter_for_10_dimension[1]++;
}
}
- System.out.println("l2_positive_counter_for_10_dimension: " + Arrays.toString(l2_positive_counter_for_10_dimension));
-
- System.out.println("data_Util_randVector: "+ Arrays.toString(data_Util_randVector));
-
-
-
-
- if(l2_norm_5dot49_Util_randVector > 0) {
- double myL2_SQRT = Math.sqrt(myL2_square);
- double scale_Util_randV = l2_norm_5dot49_Util_randVector/myL2_SQRT;
- for(int i = 0; i < dimension; i++) {
- long data_half_M_scale = 0;
- long data_ADD_half = (long)(((double)data_Util_randVector[i]+0.5)*scale_Util_randV);
- long data_MINUS_half = (long)(((double)data_Util_randVector[i]-0.5)*scale_Util_randV);
- if(data_Util_randVector[i] > 0) {
- data_half_M_scale = data_ADD_half;
- data_Util_randVector[i] = data_half_M_scale;
- }
- else{
- data_half_M_scale = data_MINUS_half;
- data_Util_randVector[i] = data_half_M_scale;
- }
+ if(l2 > 0) {
+ myL2 = Math.sqrt(myL2);
+ double scale = l2/myL2;
+ for(int i = 0; i < m; i++) {
+ if(data[i] > 0) data[i] = (long)(((double)data[i]+0.5)*scale);
+ else data[i] = (long)(((double)data[i]-0.5)*scale);
// Round to the closest long
}
}
- return data_Util_randVector;
+ return data;
}
@@ -888,23 +873,23 @@ public static long[] randVector(int dimension, long Z_F_order_of_Group_Util_Rand
* Adds two vectors in the field Z_F.
* @param v1 one vector
* @param v2 the other vector
- * @param vector_sum the vector where the resulting v1+v2 should
+ * @param s the vector where the resulting v1+v2 should
* be stored.
- * @param group_order_F_Util the order of the group Z_F
- * @throws IllegalArgumentException if the dimesionalities of the
+ * @param F the order of the group Z_F
+ * @throws IllegalArgumentException if the dimesionalities of the
* vectors do not match.
*/
- public static void vectorAdd(long[] v1, long[] v2, long[] vector_sum, long group_order_F_Util) {
- int vector_dimension = vector_sum.length; // dimensionality of vector
- if(v1.length != vector_dimension || v2.length != vector_dimension)
+ public static void vectorAdd(long[] v1, long[] v2, long[] s, long F) {
+ int m = s.length;
+ if(v1.length != m || v2.length != m)
throw new IllegalArgumentException("dimesionalities do not match!");
- for(int dimension_id = 0; dimension_id < vector_dimension; dimension_id++) {
- // Assuming F is at least a few bits less than a long, a single
+ for(int j = 0; j < m; j++) {
+ // Assuming F is at least a few bits less than a long, a single
// addition won't cause overflow. So we can do mod afterwards.
- // But we do need to do mod once for a few additions since the
- // shares can be any number in Z_F.
- vector_sum[dimension_id] = mod(v1[dimension_id] + v2[dimension_id], group_order_F_Util);
+ // But we do need to do mod once for a few additions since the
+ // shares can be any number in Z_F.
+ s[j] = mod(v1[j] + v2[j], F);
}
}
}
diff --git a/src/main/java/overview.html b/src/main/java/overview.html
new file mode 100644
index 0000000..3aab49f
--- /dev/null
+++ b/src/main/java/overview.html
@@ -0,0 +1,20 @@
+
+
+
+
+P4P uses the native big integer lib from I2P
+
+
+
diff --git a/src/main/proto/user_server.proto b/src/main/proto/user_server.proto
new file mode 100644
index 0000000..dfd66fc
--- /dev/null
+++ b/src/main/proto/user_server.proto
@@ -0,0 +1,39 @@
+// Copyright 2015 The gRPC Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+syntax = "proto3";
+
+option java_multiple_files = true;
+option java_package = "io.grpc.examples.helloworld";
+option java_outer_classname = "HelloProto";
+option objc_class_prefix = "HLW";
+
+package userserver;
+
+// The greeting service definition.
+service Greeter {
+ // Sends a greeting
+ rpc SayHello (HelloRequest) returns (HelloReply) {}
+ // Sends another greeting
+ rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
+}
+
+// The request message containing the user's name.
+message HelloRequest {
+ string name = 1;
+}
+
+// The response message containing the greetings
+message HelloReply {
+ string message = 1;
+}