· 4 years ago · Jun 14, 2021, 02:38 PM
1public class ThresholdElGamal extends ElGamal
2{
3 // comments to this code will be presented during the lecture
4
5 public static ElGamalSK Setup(ElGamalSK SK) {
6
7 SecureRandom sc=new SecureRandom();
8 BigInteger s=new BigInteger(SK.PK.securityparameter,sc);
9 BigInteger h=SK.PK.g.modPow(s, SK.PK.p);
10
11 ElGamalPK PK=new ElGamalPK(SK.PK.p,SK.PK.q,SK.PK.g,h,SK.PK.securityparameter);
12 return new ElGamalSK(s,PK);
13 }
14
15 public static ElGamalSK SetupParameters(int securityparameter) {
16 BigInteger p,q,g,h,s;
17
18 SecureRandom sc=new SecureRandom();
19
20 while(true) {
21 q = BigInteger.probablePrime(securityparameter, sc);
22
23 p=q.multiply(BigInteger.TWO);
24 p=p.add(BigInteger.ONE);
25
26 if (p.isProbablePrime(50)==true) break;
27
28 }
29
30
31
32 g=new BigInteger("2");
33
34 while(true) {
35
36 if (isqr(g,p)==1)break;
37 g=g.add(BigInteger.ONE);
38 }
39
40 s=BigInteger.ZERO;
41 h=BigInteger.ZERO;
42
43 ElGamalPK PK=new ElGamalPK(p,q,g,h,securityparameter);
44
45 return new ElGamalSK(s,PK);
46 }
47
48
49
50 public static ElGamalPK AggregatePartialPublicKeys(ElGamalPK PK[]) {
51 BigInteger tmp=BigInteger.ONE;
52 for (int i=0;i<PK.length;i++)tmp=tmp.multiply(PK[i].h).mod(PK[0].p);
53 return new ElGamalPK(PK[0].p,PK[0].q,PK[0].g,tmp,PK[0].securityparameter);
54
55 }
56
57
58
59 public static ElGamalCT PartialDecrypt(ElGamalCT CT,ElGamalSK SK)
60 {
61
62 BigInteger tmp = CT.C2.modPow(SK.s, SK.PK.p);
63 tmp=tmp.modInverse(SK.PK.p);
64 BigInteger newC = tmp.multiply(CT.C).mod(SK.PK.p);
65 return new ElGamalCT(newC,CT.C2);
66 }
67
68
69
70
71 public static void main(String[] args) throws IOException
72 {
73
74
75 SecureRandom sc = new SecureRandom();
76
77 ElGamalSK Params=SetupParameters(64);
78 ElGamalSK []SK=new ElGamalSK[3];
79
80 for (int i=0;i<3;i++) {
81 SK[i]=Setup(Params);
82
83 System.out.println("Setup for "+i+"-th authority:");
84 System.out.println("partial secret-key = " + SK[i].s);
85 System.out.println("partial public-key = " + SK[i].PK.h);
86 System.out.println("p = " + SK[i].PK.p);
87 System.out.println("q = " + SK[i].PK.q);
88 System.out.println("g = " + SK[i].PK.g);
89 }
90
91
92 ElGamalPK []PartialPK=new ElGamalPK[3];
93
94 for (int i=0;i<3;i++) PartialPK[i]=SK[i].PK;
95 ElGamalPK PK= AggregatePartialPublicKeys(PartialPK);
96
97
98 BigInteger M;
99 while(true) {
100 M=new BigInteger(Params.PK.securityparameter,sc);
101 if (isqr(M,Params.PK.p)==1) break;
102 }
103 System.out.println("plaintext to encrypt with threshold El Gamal = " + M);
104 ElGamalCT CT=Encrypt(PK,M);
105
106 ElGamalCT PartialDecCT=CT;
107 for (int i=0;i<2;i++) PartialDecCT=PartialDecrypt(PartialDecCT,SK[i]);
108 BigInteger D=Decrypt(PartialDecCT,SK[2]);
109 System.out.println("decrypted plaintext with threshold El Gamal = " + D+"\n"); // it should print the same integer as before
110
111
112
113 }
114}