Skip to content

Commit 5e2f64e

Browse files
committed
polyval gfmulint disambiguate ghash gfmulint
1 parent aa55b78 commit 5e2f64e

File tree

5 files changed

+195
-3
lines changed

5 files changed

+195
-3
lines changed

circuits/aes-gcm/ghash.circom

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
pragma circom 2.1.9;
22

3-
include "gfmul_int.circom";
3+
include "ghash_gfmul_int.circom";
44
include "helper_functions.circom";
55

66
// GHASH computes the authentication tag for AES-GCM.
File renamed without changes.

circuits/aes-gcm/polyval.circom

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
pragma circom 2.1.9;
22

3-
include "gfmul_int.circom";
3+
include "polyval_gfmul_int.circom";
44
include "helper_functions.circom";
55

66
template POLYVAL(n_bits)

circuits/aes-gcm/polyval_gfmul_int

+192
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
pragma circom 2.1.9;
2+
3+
include "vclmul_emulator.circom";
4+
include "helper_functions.circom";
5+
6+
// GFMULInt multiplies two 128-bit numbers in GF(2^128) and returns the result.
7+
//
8+
// Inputs:
9+
// - `a` the first 128-bit number, encoded as a polynomial over GF(2^128)
10+
// - `b` the second 128-bit number, encoded as a polynomial over GF(2^128)
11+
//
12+
// Outputs:
13+
// - `res` the result of the multiplication
14+
//
15+
// Computes:
16+
// res = a * b mod p
17+
// where p = x^128 + x^7 + x^2 + x + 1
18+
template GFMULInt()
19+
{
20+
signal input a[2][64];
21+
signal input b[2][64];
22+
signal output res[2][64];
23+
24+
25+
// TODO(TK 2024-08-10): note about magic nuhmebr
26+
var tmp[5][2][64];
27+
28+
// XMMMask is x^128 + x^7 + x^2 + x + 1
29+
// GHASH is big endian, polyval is little endian
30+
// bitwise: 11100001 .... 00000001
31+
//
32+
// 0x87 = 0b1000_0111 => encode x^7 + x^2 + x + 1
33+
var XMMMASK[2] = [0x87, 0x0];
34+
35+
var i, j, k;
36+
37+
log("GFMULInt");
38+
log(a[0][0]);
39+
// log(b);
40+
// log("res", res);
41+
42+
component num2bits_1[2];
43+
var XMMMASK_bits[2][64];
44+
for(i=0; i<2; i++)
45+
{
46+
num2bits_1[i] = Num2Bits(64);
47+
num2bits_1[i].in <== XMMMASK[i];
48+
for(j=0; j<8; j++)
49+
{
50+
for(k=0; k<8; k++) XMMMASK_bits[i][j*8+k] = num2bits_1[i].out[j*8+7-k];
51+
}
52+
}
53+
54+
component vclmul_emulator_1[4];
55+
56+
for(i=0; i<4; i++)
57+
{
58+
vclmul_emulator_1[i] = VCLMULEmulator(i);
59+
for(j=0; j<2; j++)
60+
{
61+
for(k=0; k<64; k++)
62+
{
63+
vclmul_emulator_1[i].src1[j][k] <== a[j][k];
64+
vclmul_emulator_1[i].src2[j][k] <== b[j][k];
65+
}
66+
}
67+
68+
tmp[i+1] = vclmul_emulator_1[i].destination;
69+
}
70+
71+
component xor_1[2][64];
72+
for(i=0; i<2; i++)
73+
{
74+
for(j=0; j<64; j++)
75+
{
76+
xor_1[i][j] = XOR();
77+
xor_1[i][j].a <== tmp[2][i][j];
78+
xor_1[i][j].b <== tmp[3][i][j];
79+
80+
tmp[2][i][j] = xor_1[i][j].out;
81+
}
82+
}
83+
84+
for(i=0; i<64; i++) tmp[3][0][i] = 0;
85+
86+
for(i=0; i<64; i++) tmp[3][1][i] = tmp[2][0][i];
87+
88+
for(i=0; i<64; i++) tmp[2][0][i] = tmp[2][1][i];
89+
90+
for(i=0; i<64; i++) tmp[2][1][i] = 0;
91+
92+
component xor_2[2][64];
93+
for(i=0; i<2; i++)
94+
{
95+
for(j=0; j<64; j++)
96+
{
97+
xor_2[i][j] = XOR();
98+
xor_2[i][j].a <== tmp[1][i][j];
99+
xor_2[i][j].b <== tmp[3][i][j];
100+
101+
tmp[1][i][j] = xor_2[i][j].out;
102+
}
103+
}
104+
105+
component xor_3[2][64];
106+
for(i=0; i<2; i++)
107+
{
108+
for(j=0; j<64; j++)
109+
{
110+
xor_3[i][j] = XOR();
111+
xor_3[i][j].a <== tmp[4][i][j];
112+
xor_3[i][j].b <== tmp[2][i][j];
113+
114+
tmp[4][i][j] = xor_3[i][j].out;
115+
}
116+
}
117+
118+
component vclmul_emulator_2 = VCLMULEmulator(1);
119+
for(i=0; i<2; i++)
120+
{
121+
for(j=0; j<64; j++)
122+
{
123+
vclmul_emulator_2.src1[i][j] <== XMMMASK_bits[i][j];
124+
vclmul_emulator_2.src2[i][j] <== tmp[1][i][j];
125+
}
126+
}
127+
128+
tmp[2] = vclmul_emulator_2.destination;
129+
130+
for(i=0; i<64; i++)
131+
{
132+
tmp[3][0][i] = tmp[1][1][i];
133+
tmp[3][1][i] = tmp[1][0][i];
134+
}
135+
136+
component xor_4[2][64];
137+
for(i=0; i<2; i++)
138+
{
139+
for(j=0; j<64; j++)
140+
{
141+
xor_4[i][j] = XOR();
142+
xor_4[i][j].a <== tmp[2][i][j];
143+
xor_4[i][j].b <== tmp[3][i][j];
144+
145+
tmp[1][i][j] = xor_4[i][j].out;
146+
}
147+
}
148+
149+
component vclmul_emulator_3 = VCLMULEmulator(1);
150+
for(i=0; i<2; i++)
151+
{
152+
for(j=0; j<64; j++)
153+
{
154+
vclmul_emulator_3.src1[i][j] <== XMMMASK_bits[i][j];
155+
vclmul_emulator_3.src2[i][j] <== tmp[1][i][j];
156+
}
157+
}
158+
159+
tmp[2] = vclmul_emulator_3.destination;
160+
161+
for(i=0; i<64; i++)
162+
{
163+
tmp[3][0][i] = tmp[1][1][i];
164+
tmp[3][1][i] = tmp[1][0][i];
165+
}
166+
167+
component xor_5[2][64];
168+
for(i=0; i<2; i++)
169+
{
170+
for(j=0; j<64; j++)
171+
{
172+
xor_5[i][j] = XOR();
173+
xor_5[i][j].a <== tmp[2][i][j];
174+
xor_5[i][j].b <== tmp[3][i][j];
175+
176+
tmp[1][i][j] = xor_5[i][j].out;
177+
}
178+
}
179+
180+
component xor_6[2][64];
181+
for(i=0; i<2; i++)
182+
{
183+
for(j=0; j<64; j++)
184+
{
185+
xor_6[i][j] = XOR();
186+
xor_6[i][j].a <== tmp[1][i][j];
187+
xor_6[i][j].b <== tmp[4][i][j];
188+
189+
res[i][j] <== xor_6[i][j].out;
190+
}
191+
}
192+
}

circuits/test/gfmulint/gfmulint.test.ts circuits/test/polyval_gfmulint/polyval_gfmulint.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ describe("gfmulint", () => {
1010

1111
before(async () => {
1212
circuit = await circomkit.WitnessTester("gfmulint", {
13-
file: "aes-gcm/gfmul_int",
13+
file: "aes-gcm/polyval_gfmul_int",
1414
template: "GFMULInt",
1515
});
1616
console.log("#constraints:", await circuit.getConstraintCount());

0 commit comments

Comments
 (0)