Skip to content

Commit 0026018

Browse files
Ho Nguyen PhamHo Nguyen Pham
authored andcommitted
add test for CommitteeMember
1 parent e8ecef1 commit 0026018

File tree

3 files changed

+172
-91
lines changed

3 files changed

+172
-91
lines changed

src/CommitteeMember.test.ts

Lines changed: 124 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,126 @@
1-
import { Field, Group, PrivateKey, PublicKey } from 'o1js';
2-
import {
3-
Round1Contribution,
4-
Round2Contribution,
5-
SecretPolynomial,
6-
} from './CommitteeMember';
1+
import { Field, Group, Provable, PrivateKey, PublicKey } from 'o1js';
2+
import * as Committee from './CommitteeMember';
73

8-
// describe('CommitteeMember', () => {
9-
// let T = 3;
10-
// let N = 5;
11-
// let keyId = Field(0);
12-
// let committees: {
13-
// privateKey: PrivateKey;
14-
// committeeMember: CommitteeMember;
15-
// secretPolynomial: SecretPolynomial;
16-
// round1Contribution: Round1Contribution | any;
17-
// round2Contribution: Round2Contribution | any;
18-
// }[] = [];
19-
// let round1Contributions: Round1Contribution[] = [];
20-
// let publicKey: PublicKey;
21-
// let w = {
22-
// isLeft: false,
23-
// sibling: Field(0),
24-
// };
25-
// let dummyWitness = Array.from(Array(10).keys()).map(() => w);
26-
// beforeAll(async () => {
27-
// for (let i = 0; i < N; i++) {
28-
// let privateKey = PrivateKey.random();
29-
// let committeeMember = new CommitteeMember({
30-
// publicKey: privateKey.toPublicKey(),
31-
// index: i + 1,
32-
// T: T,
33-
// N: N,
34-
// witness: new (getMerkleWitnessType(10))(dummyWitness),
35-
// });
36-
// let secretPolynomial = committeeMember.getRandomPolynomial();
37-
// let round1Contribution = committeeMember.getRound1Contribution(
38-
// secretPolynomial,
39-
// keyId
40-
// );
41-
// round1Contributions.push(round1Contribution);
42-
// committees.push({
43-
// privateKey: privateKey,
44-
// committeeMember: committeeMember,
45-
// secretPolynomial: secretPolynomial,
46-
// round1Contribution: round1Contribution,
47-
// round2Contribution: null,
48-
// });
49-
// }
4+
describe('CommitteeMember', () => {
5+
let T = 3;
6+
let N = 5;
7+
let keyId = Field(0);
8+
let committees: {
9+
privateKey: PrivateKey;
10+
index: number;
11+
secretPolynomial: Committee.SecretPolynomial;
12+
round1Contribution?: Committee.Round1Contribution;
13+
round2Contribution?: Committee.Round2Contribution;
14+
tallyContribution?: Committee.TallyContribution;
15+
}[] = [];
16+
let round1Contributions: Committee.Round1Contribution[] = [];
17+
let round2Contributions: Committee.Round2Contribution[] = [];
18+
let tallyContributions: Committee.TallyContribution[] = [];
19+
let publicKey: PublicKey;
20+
let R: Group[][] = [];
21+
let M: Group[][] = [];
22+
let sumR: Group[] = [];
23+
let sumM: Group[] = [];
24+
let D: Group[][] = [];
25+
let listIndex = [0, 3, 4];
5026

51-
// publicKey = CommitteeMember.getPublicKey(round1Contributions);
52-
// console.log(publicKey.x.toBigInt());
53-
// console.log(publicKey.toJSON());
54-
// });
55-
// it('Test Key Generation', async () => {
56-
// let m = 1;
57-
// // for (let i = 0; i < N; i++) {
58-
// // let senderIndex = i + 1;
59-
// // let publicKeys: Group[] = [];
60-
// // for (let j = 0; j < N; j++) {
61-
// // let recipientIndex = j + 1;
62-
// // if (senderIndex != recipientIndex) {
63-
// // publicKeys.push(
64-
// // committees[j].privateKey.toPublicKey().toGroup()
65-
// // );
66-
// // }
67-
// // }
68-
// // let round2Contribution = committees[
69-
// // i
70-
// // ].committeeMember.getRound2Contribution(
71-
// // committees[i].secretPolynomial,
72-
// // publicKeys,
73-
// // keyId
74-
// // );
75-
// // }
76-
// });
77-
// });
27+
beforeAll(async () => {
28+
for (let i = 0; i < N; i++) {
29+
let privateKey = PrivateKey.random();
30+
// let committeeMember = {
31+
// publicKey: privateKey.toPublicKey(),
32+
// index: i + 1,
33+
// round1Contribution: undefined,
34+
// round2Contribution: undefined,
35+
// };
36+
let secretPolynomial = Committee.generateRandomPolynomial(T, N);
37+
committees.push({
38+
privateKey: privateKey,
39+
index: i + 1,
40+
secretPolynomial: secretPolynomial,
41+
round1Contribution: undefined,
42+
round2Contribution: undefined,
43+
});
44+
}
45+
});
46+
47+
it('Should generate round 1 contribution', async () => {
48+
for (let i = 0; i < N; i++) {
49+
let round1Contribution = Committee.getRound1Contribution(
50+
committees[i].secretPolynomial
51+
);
52+
committees[i].round1Contribution = round1Contribution;
53+
round1Contributions.push(round1Contribution);
54+
}
55+
publicKey = Committee.calculatePublicKey(round1Contributions);
56+
// Provable.log(publicKey);
57+
// Provable.log(round1Contributions);
58+
});
59+
60+
it('Should generate round 2 contribution', async () => {
61+
for (let i = 0; i < N; i++) {
62+
let round2Contribution = Committee.getRound2Contribution(
63+
committees[i].secretPolynomial,
64+
committees[i].index,
65+
round1Contributions
66+
);
67+
committees[i].round2Contribution = round2Contribution;
68+
round2Contributions.push(round2Contribution);
69+
}
70+
// Provable.log(round2Contributions);
71+
// round2Contributions.map((e) => console.log(e.data));
72+
});
73+
74+
it('Should accumulate encryption', async () => {
75+
const plainVectors = [
76+
[1000n, 0n, 0n],
77+
[0n, 1000n, 0n],
78+
[0n, 0n, 1000n],
79+
[2000n, 0n, 0n],
80+
[2000n, 0n, 0n],
81+
];
82+
for (let i = 0; i < plainVectors.length; i++) {
83+
let encryptedVector = Committee.encryptVector(
84+
Committee.calculatePublicKey(round1Contributions),
85+
plainVectors[i]
86+
);
87+
R.push(encryptedVector.R);
88+
M.push(encryptedVector.M);
89+
}
90+
91+
let accumulatedEncryption = Committee.accumulateEncryption(R, M);
92+
sumR = accumulatedEncryption.sumR;
93+
sumM = accumulatedEncryption.sumM;
94+
// Provable.log(sumR, sumM);
95+
});
96+
97+
it('Should generate tally contribution', async () => {
98+
for (let i = 0; i < T; i++) {
99+
let round2Data: Committee.Round2Data[] = [];
100+
round2Contributions.reduce(
101+
(prev, curr, index) =>
102+
index == committees[listIndex[i]].index - 1
103+
? prev
104+
: round2Data.push(curr.data[committees[listIndex[i]].index - 1]),
105+
{}
106+
);
107+
let tallyContribution = Committee.getTallyContribution(
108+
committees[listIndex[i]].secretPolynomial,
109+
committees[listIndex[i]].index - 1,
110+
round2Data,
111+
sumR
112+
);
113+
committees[listIndex[i]].tallyContribution = tallyContribution;
114+
tallyContributions.push(tallyContribution);
115+
D.push(tallyContribution.D);
116+
}
117+
// Provable.log(tallyContributions);
118+
// tallyContributions.map((e) => Provable.log(e.D));
119+
});
120+
121+
it('Should calculate result vector', async () => {
122+
console.log(D.length);
123+
let resultVector = Committee.getResultVector(listIndex, D, sumM);
124+
Provable.log(resultVector);
125+
});
126+
});

src/CommitteeMember.ts

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export {
2828
getTallyContribution,
2929
getLagrangeCoefficient,
3030
getResultVector,
31+
encryptVector,
3132
accumulateEncryption,
3233
};
3334

@@ -93,20 +94,24 @@ function getRound1Contribution(secret: SecretPolynomial): Round1Contribution {
9394
function getRound2Contribution(
9495
secret: SecretPolynomial,
9596
index: number,
96-
publicKeys: PublicKey[]
97+
round1Contributions: Round1Contribution[]
9798
): Round2Contribution {
9899
let data = new Array<Round2Data>(secret.f.length);
99100
for (let i = 0; i < data.length; i++) {
100-
if (i + 1 == Number(index)) {
101-
data[i].U = Group.zero;
102-
data[i].c = 0n;
101+
if (i + 1 == index) {
102+
data[i] = {
103+
U: Group.zero,
104+
c: 0n,
105+
};
103106
} else {
104107
let encryption = ElgamalECC.encrypt(
105108
secret.f[i].toBigInt(),
106-
publicKeys[i]
109+
PublicKey.fromGroup(round1Contributions[i].C[0])
107110
);
108-
data[i].U = encryption.U;
109-
data[i].c = encryption.c;
111+
data[i] = {
112+
U: encryption.U,
113+
c: encryption.c,
114+
};
110115
}
111116
}
112117
return { data };
@@ -117,7 +122,7 @@ function getTallyContribution(
117122
index: number,
118123
round2Data: Round2Data[],
119124
R: Group[]
120-
) {
125+
): TallyContribution {
121126
let decryptions: Scalar[] = round2Data.map((data) =>
122127
Scalar.from(
123128
ElgamalECC.decrypt(
@@ -180,12 +185,38 @@ function getResultVector(
180185
return result;
181186
}
182187

188+
function encryptVector(
189+
publicKey: PublicKey,
190+
vector: bigint[]
191+
): {
192+
r: Scalar[];
193+
R: Group[];
194+
M: Group[];
195+
} {
196+
let dimension = vector.length;
197+
let r = new Array<Scalar>(dimension);
198+
let R = new Array<Group>(dimension);
199+
let M = new Array<Group>(dimension);
200+
for (let i = 0; i < dimension; i++) {
201+
let random = Scalar.random();
202+
r[i] = random;
203+
R[i] = Group.generator.scale(random);
204+
M[i] =
205+
vector[i] > 0n
206+
? Group.generator
207+
.scale(Scalar.from(vector[i]))
208+
.add(publicKey.toGroup().scale(random))
209+
: Group.zero.add(publicKey.toGroup().scale(random));
210+
}
211+
return { r, R, M };
212+
}
213+
183214
function accumulateEncryption(
184215
R: Group[][],
185-
M: Group[][],
186-
quantity: number,
187-
dimension: number
188-
): { R: Group[]; M: Group[] } {
216+
M: Group[][]
217+
): { sumR: Group[]; sumM: Group[] } {
218+
let quantity = R.length;
219+
let dimension = R[0].length ?? 0;
189220
let sumR = new Array<Group>(dimension);
190221
let sumM = new Array<Group>(dimension);
191222
sumR.fill(Group.zero);
@@ -197,5 +228,5 @@ function accumulateEncryption(
197228
sumM[j] = sumM[j].add(M[i][j]);
198229
}
199230
}
200-
return { R: sumR, M: sumM };
231+
return { sumR, sumM };
201232
}

src/Elgamal.test.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1-
import { PrivateKey, Scalar } from 'o1js';
1+
import { PrivateKey, Provable, Scalar } from 'o1js';
22
import * as ElgamalECC from './Elgamal';
33

44
describe('ElgamalECC', () => {
55
it('Should decrypt successfully', async () => {
66
let msg = Scalar.random();
7+
console.log('Plain:', msg);
78
let privateKey = PrivateKey.random();
89
let publicKey = privateKey.toPublicKey();
910
let encrypted = ElgamalECC.encrypt(msg.toBigInt(), publicKey);
10-
11+
console.log('Cipher:', encrypted);
1112
let decrypted = ElgamalECC.decrypt(encrypted.c, encrypted.U, privateKey);
12-
13+
console.log('Plain:', decrypted);
1314
expect(msg.toBigInt()).toEqual(decrypted.m);
1415
});
1516
});

0 commit comments

Comments
 (0)