-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathElgamalEnc.java
127 lines (95 loc) · 3.76 KB
/
ElgamalEnc.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package examples.generators;
import java.math.BigInteger;
import java.util.Random;
import java.nio.charset.StandardCharsets;
import util.Util;
import circuit.config.Config;
import circuit.eval.CircuitEvaluator;
import circuit.structure.CircuitGenerator;
import circuit.structure.Wire;
import circuit.structure.WireArray;
public class ElgamalEnc extends CircuitGenerator {
private static Random rand;
private static BigInteger p = Config.FIELD_PRIME; // set fieldPeime
private static BigInteger g = new BigInteger("5"); // set generator
private static BigInteger r; // declare rand;
private static BigInteger sk; // 원래 없어야함
public static BigInteger pk; // 원래는 input으로 받아야한다.
private static String s = "hello";
private static BigInteger Message = new BigInteger(s.getBytes(StandardCharsets.US_ASCII));
private static BigInteger[] CipherText = new BigInteger [2];
private Wire[] c;
private Wire pkWire;
private Wire gWire;
private Wire rWire;
private Wire mWire;
public ElgamalEnc(String circuitName, int seed) {
super(circuitName);
rand = new Random(seed);
ElgamalSetup();
}
@Override
protected void buildCircuit() {
gWire = createInputWire("generator Wire");
c = createInputWireArray(2, "cipher text");
pkWire = createInputWire("pk wire");
rWire = createProverWitnessWire("r Wire");
mWire = createProverWitnessWire("Message wire");
Wire c1_ = pow(gWire, rWire); // c1 = g^r
addEqualityAssertion(c1_, c[0], "c1 error");
Wire c2_ = pow(pkWire, rWire).mul(mWire); // c2 = pk^r * M
addEqualityAssertion(c2_, c[1], "c2 error");
}
// square and multiply
Wire pow(Wire a, Wire b){
Wire[] bBitArray = b.getBitWires(Config.LOG2_FIELD_PRIME).asArray();
Wire tmp = oneWire.mul(a);
Wire result = oneWire;
for (int i=0; i < bBitArray.length ; i++){
// if bBit == 1 : check = tmp
// if bBit == 0 : check = 1
Wire check = bBitArray[i].mul(tmp).add(bBitArray[i].isEqualTo(zeroWire));
result = result.mul(check);
tmp = tmp.mul(tmp);
}
return result;
}
@Override
public void generateSampleInput(CircuitEvaluator circuitEvaluator) {
circuitEvaluator.setWireValue(pkWire, pk);
circuitEvaluator.setWireValue(gWire, g);
circuitEvaluator.setWireValue(rWire, r);
circuitEvaluator.setWireValue(mWire, Message);
circuitEvaluator.setWireValue(c[0], CipherText[0]);
circuitEvaluator.setWireValue(c[1], CipherText[1]);
}
private void ElgamalSetup(){
sk = new BigInteger(254, rand).mod(p);
pk = g.modPow(sk, p);
System.out.println("sk : " + pk.toString());
System.out.println("pk : " + sk.toString());
}
private static BigInteger[] ElgamalEncryption(BigInteger M){
BigInteger[] c = new BigInteger[2];
r = new BigInteger(254, rand).mod(p);
c[0] = g.modPow(r, p); // c1 = g^r mod p
c[1] = pk.modPow(r, p).multiply(M).mod(p); // c2 = pk^r * M mod p
System.out.println("Message : "+ M.toString());
System.out.println("r : " + r.toString());
System.out.println("c[0] : " + c[0].toString());
System.out.println("c[1] : " + c[1].toString());
return c;
}
private static void Enc(){
CipherText = ElgamalEncryption(Message);
return;
}
public static void main(String[] args) throws Exception {
ElgamalEnc generator = new ElgamalEnc("elgamal enc", 12);
Enc();
generator.generateCircuit();
generator.evalCircuit();
generator.prepFiles();
generator.runLibsnark();
}
}