|
11 | 11 | import java.io.InputStream;
|
12 | 12 | import java.io.OutputStream;
|
13 | 13 | import java.math.BigInteger;
|
| 14 | +import java.util.concurrent.ExecutionException; |
| 15 | +import java.util.concurrent.ForkJoinPool; |
| 16 | +import java.util.concurrent.ForkJoinTask; |
| 17 | +import java.util.stream.IntStream; |
14 | 18 |
|
15 | 19 | /**
|
16 | 20 | * Implementation of the {@link NROPRFEvaluator} class that uses the <a href="https://eprint.iacr.org/2019/517">KALES19 variant</a>.
|
@@ -40,36 +44,48 @@ public Pair<boolean[], BigInteger[]> executeOfflinePhase(BigInteger[] elements,
|
40 | 44 | }
|
41 | 45 |
|
42 | 46 | @Override
|
43 |
| - public BigInteger[] executeOnlinePhase(Pair<boolean[], BigInteger[]> resultOfflinePhase, BigInteger[] elements, int bitLength, InputStream inputStream, OutputStream outputStream) throws IOException { |
| 47 | + public BigInteger[] executeOnlinePhase(Pair<boolean[], BigInteger[]> resultOfflinePhase, BigInteger[] elements, int bitLength, InputStream inputStream, OutputStream outputStream) throws IOException, ExecutionException, InterruptedException { |
44 | 48 | boolean[] choices = resultOfflinePhase.getLeft();
|
45 | 49 | boolean[] b = new boolean[elements.length * bitLength];
|
46 |
| - for (int i = 0; i < elements.length; i ++) { |
| 50 | + IntStream.range(0, elements.length).parallel().forEach(i -> { |
47 | 51 | BigInteger element = elements[i];
|
48 | 52 | for (int j = 0; j < bitLength; j ++) b[i * bitLength + j] = (choices[i * bitLength + j] != element.testBit(j));
|
49 |
| - } |
| 53 | + }); |
50 | 54 | BigInteger bAsBigInteger = ArrayUtils.convertToBigInteger(b);
|
51 | 55 | StreamUtils.writeBigIntegerToOutputStream(bAsBigInteger, outputStream);
|
52 | 56 | outputStream.flush();
|
53 | 57 |
|
54 | 58 | BigInteger[] r_i_j_c_i_j = resultOfflinePhase.getRight();
|
55 |
| - BigInteger[] R = new BigInteger[elements.length * bitLength]; |
56 |
| - for (int i = 0; i < elements.length; i ++) { |
| 59 | + BigInteger[] C_i = new BigInteger[elements.length]; |
| 60 | + BigInteger[] xor_product = new BigInteger[elements.length * bitLength]; |
| 61 | + for (int i = 0; i < xor_product.length; i ++) xor_product[i] = StreamUtils.readBigIntegerFromInputStream(inputStream); |
| 62 | + ForkJoinTask<BigInteger[]> g_modded_task = ForkJoinPool.commonPool().submit(() -> { |
| 63 | + BigInteger[] g_modded = new BigInteger[elements.length]; |
| 64 | + for (int i = 0; i < g_modded.length; i ++) { |
| 65 | + try { |
| 66 | + g_modded[i] = StreamUtils.readBigIntegerFromInputStream(inputStream); |
| 67 | + } catch (IOException e) { |
| 68 | + throw new RuntimeException(e); |
| 69 | + } |
| 70 | + } |
| 71 | + return g_modded; |
| 72 | + }); |
| 73 | + IntStream.range(0, elements.length).parallel().forEach(i -> { |
57 | 74 | BigInteger element = elements[i];
|
58 |
| - for (int j = 0; j < bitLength; j ++) R[i * bitLength + j] = r_i_j_c_i_j[i * bitLength + j].xor((element.testBit(j) ? BigInteger.ONE : BigInteger.ZERO).multiply(StreamUtils.readBigIntegerFromInputStream(inputStream))); |
59 |
| - } |
60 | 75 |
|
61 |
| - BigInteger[] C_i = new BigInteger[elements.length]; |
62 |
| - for (int i = 0; i < elements.length; i ++) { |
| 76 | + BigInteger[] R = new BigInteger[bitLength]; |
| 77 | + for (int j = 0; j < bitLength; j ++) R[j] = r_i_j_c_i_j[i * bitLength + j].xor((element.testBit(j) ? BigInteger.ONE : BigInteger.ZERO).multiply(xor_product[i * bitLength + j])); |
| 78 | + |
63 | 79 | BigInteger exponent = BigInteger.ONE;
|
64 |
| - for (int j = 0; j < bitLength; j ++) exponent = exponent.multiply(R[i * bitLength + j]); |
| 80 | + for (int j = 0; j < bitLength; j ++) exponent = exponent.multiply(R[j]); |
65 | 81 | C_i[i] = exponent.mod(getQ());
|
66 |
| - } |
| 82 | + }); |
67 | 83 |
|
68 | 84 | BigInteger[] returnValue = new BigInteger[elements.length];
|
69 |
| - for (int i = 0; i < returnValue.length; i ++) { |
70 |
| - BigInteger g_modded = StreamUtils.readBigIntegerFromInputStream(inputStream); |
71 |
| - returnValue[i] = g_modded.modPow(C_i[i], getP()); |
72 |
| - } |
| 85 | + BigInteger[] g_modded = g_modded_task.get(); |
| 86 | + IntStream.range(0, returnValue.length).parallel().forEach(i -> { |
| 87 | + returnValue[i] = g_modded[i].modPow(C_i[i], getP()); |
| 88 | + }); |
73 | 89 | return returnValue;
|
74 | 90 | }
|
75 | 91 | }
|
0 commit comments