Skip to content

Commit de9c7b8

Browse files
author
gefeili
committed
Refactor of SnovaSigner
1 parent 8cbbf61 commit de9c7b8

File tree

4 files changed

+202
-189
lines changed

4 files changed

+202
-189
lines changed

core/src/main/java/org/bouncycastle/pqc/crypto/snova/GF16Utils.java

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,9 @@ public static void decode(byte[] m, int mOff, byte[] mdec, int decIndex, int mde
8686
* @param menc the output byte array that will hold the encoded bytes
8787
* @param mlen the number of nibbles in the input array
8888
*/
89-
public static void encode(byte[] m, byte[] menc, int outOff, int mlen)
89+
public static void encode(byte[] m, byte[] menc, int mlen)
9090
{
91-
int i, srcIndex = 0;
91+
int i, srcIndex = 0, outOff = 0;
9292
// Process pairs of 4-bit values
9393
for (i = 0; i < mlen / 2; i++)
9494
{
@@ -158,7 +158,6 @@ public static void decodeMergeInHalf(byte[] byteArray, byte[] gf16Array, int nGf
158158

159159
public static void gf16mMul(byte[] a, byte[] b, byte[] c, int rank)
160160
{
161-
162161
for (int i = 0; i < rank; i++)
163162
{
164163
for (int j = 0; j < rank; j++)
@@ -173,6 +172,21 @@ public static void gf16mMul(byte[] a, byte[] b, byte[] c, int rank)
173172
}
174173
}
175174

175+
public static void gf16mMulTo(byte[] a, byte[] b, byte[] c, int rank)
176+
{
177+
for (int i = 0; i < rank; i++)
178+
{
179+
for (int j = 0; j < rank; j++)
180+
{
181+
int cIndex = i * rank + j;
182+
for (int k = 0; k < rank; ++k)
183+
{
184+
c[cIndex] ^= mt(getGf16m(a, i, k, rank), getGf16m(b, k, j, rank));
185+
}
186+
}
187+
}
188+
}
189+
176190
static byte getGf16m(byte[] gf16m, int x, int y, int rank)
177191
{
178192
return gf16m[x * rank + y];
@@ -187,21 +201,6 @@ public static int gf16FromNibble(int idx)
187201
return ((middle & 0x41) | ((middle << 2) & 0x208));
188202
}
189203

190-
public static void gf16mAdd(byte[] a, byte[] b, byte[] c, int rank)
191-
{
192-
193-
for (int i = 0; i < rank; ++i)
194-
{
195-
for (int j = 0; j < rank; ++j)
196-
{
197-
int index = i * rank + j;
198-
// GF16 addition is XOR operation (equivalent to GF(2^4) addition)
199-
// Mask with 0x0F to ensure we only keep 4-bit values
200-
c[index] = (byte)((a[index] ^ b[index]) & 0x0F);
201-
}
202-
}
203-
}
204-
205204
public static byte mul(byte a, byte b)
206205
{
207206
return MT4B[(a & 0xF) << 4 | (b & 0xF)];

core/src/main/java/org/bouncycastle/pqc/crypto/snova/SnovaEngine.java

Lines changed: 124 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ public void makeInvertibleByAddingAS(byte[] source, int off)
137137
for (int a = 1; a < 16; a++)
138138
{
139139
generateASMatrix(temp, (byte)a);
140-
addMatrices(temp, 0, source, off, source, off);
140+
xorTo(source, off, temp);
141141

142142
if (gf16Determinant(source, off) != 0)
143143
{
@@ -153,7 +153,7 @@ private byte gf16Determinant(byte[] matrix, int off)
153153
case 2:
154154
return determinant2x2(matrix, off);
155155
case 3:
156-
return determinant3x3(matrix, off, 0, 1, 2);
156+
return determinant3x3(matrix, off);
157157
case 4:
158158
return determinant4x4(matrix, off);
159159
case 5:
@@ -165,23 +165,23 @@ private byte gf16Determinant(byte[] matrix, int off)
165165

166166
private byte determinant2x2(byte[] m, int off)
167167
{
168-
return (byte)
169-
(GF16Utils.mul(getGF16m(m, 0, off), getGF16m(m, 1, off + 1)) ^
170-
GF16Utils.mul(getGF16m(m, 0, off + 1), getGF16m(m, 1, off)));
168+
return (byte)(GF16Utils.mul(m[off], m[off + 3]) ^ GF16Utils.mul(m[off + 1], m[off + 2]));
171169
}
172170

173-
private byte determinant3x3(byte[] m, int off, int i0, int i1, int i2)
171+
private byte determinant3x3(byte[] m, int off)
174172
{
175-
return (byte)(
176-
GF16Utils.mul(getGF16m(m, 0, off + i0), (byte)(
177-
GF16Utils.mul(getGF16m(m, 1, off + i1), getGF16m(m, 2, off + i2)) ^
178-
GF16Utils.mul(getGF16m(m, 1, off + i2), getGF16m(m, 2, off + i1)))) ^
179-
GF16Utils.mul(getGF16m(m, 0, off + i1), (byte)(
180-
GF16Utils.mul(getGF16m(m, 1, off + i0), getGF16m(m, 2, off + i2)) ^
181-
GF16Utils.mul(getGF16m(m, 1, off + i2), getGF16m(m, 2, off + i0)))) ^
182-
GF16Utils.mul(getGF16m(m, 0, off + i2), (byte)(
183-
GF16Utils.mul(getGF16m(m, 1, off + i0), getGF16m(m, 2, off + i1)) ^
184-
GF16Utils.mul(getGF16m(m, 1, off + i1), getGF16m(m, 2, off + i0)))));
173+
byte m00 = m[off++];
174+
byte m01 = m[off++];
175+
byte m02 = m[off++];
176+
byte m10 = m[off++];
177+
byte m11 = m[off++];
178+
byte m12 = m[off++];
179+
byte m20 = m[off++];
180+
byte m21 = m[off++];
181+
byte m22 = m[off];
182+
return (byte)(GF16Utils.mul(m00, (byte)(GF16Utils.mul(m11, m22) ^ GF16Utils.mul(m12, m21))) ^
183+
GF16Utils.mul(m01, (byte)(GF16Utils.mul(m10, m22) ^ GF16Utils.mul(m12, m20))) ^
184+
GF16Utils.mul(m02, (byte)(GF16Utils.mul(m10, m21) ^ GF16Utils.mul(m11, m20))));
185185
}
186186

187187
private byte determinant4x4(byte[] m, int off)
@@ -222,36 +222,102 @@ private byte determinant4x4(byte[] m, int off)
222222

223223
private byte determinant5x5(byte[] m, int off)
224224
{
225-
byte m30 = getGF16m(m, 3, off);
226-
byte m31 = getGF16m(m, 3, off + 1);
227-
byte m32 = getGF16m(m, 3, off + 2);
228-
byte m33 = getGF16m(m, 3, off + 3);
229-
byte m34 = getGF16m(m, 3, off + 4);
230-
231-
byte m40 = getGF16m(m, 4, off);
232-
byte m41 = getGF16m(m, 4, off + 1);
233-
byte m42 = getGF16m(m, 4, off + 2);
234-
byte m43 = getGF16m(m, 4, off + 3);
235-
byte m44 = getGF16m(m, 4, off + 4);
236-
byte result = GF16Utils.mul(determinant3x3(m, off, 0, 1, 2),
225+
byte m00 = m[off++];
226+
byte m01 = m[off++];
227+
byte m02 = m[off++];
228+
byte m03 = m[off++];
229+
byte m04 = m[off++];
230+
byte m10 = m[off++];
231+
byte m11 = m[off++];
232+
byte m12 = m[off++];
233+
byte m13 = m[off++];
234+
byte m14 = m[off++];
235+
byte m20 = m[off++];
236+
byte m21 = m[off++];
237+
byte m22 = m[off++];
238+
byte m23 = m[off++];
239+
byte m24 = m[off++];
240+
byte m30 = m[off++];
241+
byte m31 = m[off++];
242+
byte m32 = m[off++];
243+
byte m33 = m[off++];
244+
byte m34 = m[off++];
245+
byte m40 = m[off++];
246+
byte m41 = m[off++];
247+
byte m42 = m[off++];
248+
byte m43 = m[off++];
249+
byte m44 = m[off];
250+
251+
byte m10xm21_m11xm20 = (byte)(GF16Utils.mul(m10, m21) ^ GF16Utils.mul(m11, m20));
252+
byte m10xm22_m12xm20 = (byte)(GF16Utils.mul(m10, m22) ^ GF16Utils.mul(m12, m20));
253+
byte m10xm23_m13xm20 = (byte)(GF16Utils.mul(m10, m23) ^ GF16Utils.mul(m13, m20));
254+
byte m10xm24_m14xm20 = (byte)(GF16Utils.mul(m10, m24) ^ GF16Utils.mul(m14, m20));
255+
byte m11xm22_m12xm21 = (byte)(GF16Utils.mul(m11, m22) ^ GF16Utils.mul(m12, m21));
256+
byte m11xm23_m13xm21 = (byte)(GF16Utils.mul(m11, m23) ^ GF16Utils.mul(m13, m21));
257+
byte m11xm24_m14xm21 = (byte)(GF16Utils.mul(m11, m24) ^ GF16Utils.mul(m14, m21));
258+
byte m12xm23_m13xm22 = (byte)(GF16Utils.mul(m12, m23) ^ GF16Utils.mul(m13, m22));
259+
byte m12xm24_m14xm22 = (byte)(GF16Utils.mul(m12, m24) ^ GF16Utils.mul(m14, m22));
260+
byte m13xm24_m14xm23 = (byte)(GF16Utils.mul(m13, m24) ^ GF16Utils.mul(m14, m23));
261+
262+
byte result = GF16Utils.mul(//determinant3x3(m, off, 0, 1, 2),
263+
(byte)(
264+
GF16Utils.mul(m00, m11xm22_m12xm21) ^
265+
GF16Utils.mul(m01, m10xm22_m12xm20) ^
266+
GF16Utils.mul(m02, m10xm21_m11xm20)),
237267
(byte)(GF16Utils.mul(m33, m44) ^ GF16Utils.mul(m34, m43)));
238-
result ^= GF16Utils.mul(determinant3x3(m, off, 0, 1, 3),
268+
result ^= GF16Utils.mul(//determinant3x3(m, off, 0, 1, 3),
269+
(byte)(
270+
GF16Utils.mul(m00, m11xm23_m13xm21) ^
271+
GF16Utils.mul(m01, m10xm23_m13xm20) ^
272+
GF16Utils.mul(m03, m10xm21_m11xm20)),
239273
(byte)(GF16Utils.mul(m32, m44) ^ GF16Utils.mul(m34, m42)));
240-
result ^= GF16Utils.mul(determinant3x3(m, off, 0, 1, 4),
274+
result ^= GF16Utils.mul(//determinant3x3(m, off, 0, 1, 4),
275+
(byte)(
276+
GF16Utils.mul(m00, m11xm24_m14xm21) ^
277+
GF16Utils.mul(m01, m10xm24_m14xm20) ^
278+
GF16Utils.mul(m04, m10xm21_m11xm20)),
241279
(byte)(GF16Utils.mul(m32, m43) ^ GF16Utils.mul(m33, m42)));
242-
result ^= GF16Utils.mul(determinant3x3(m, off, 0, 2, 3),
280+
result ^= GF16Utils.mul(//determinant3x3(m, off, 0, 2, 3),
281+
(byte)(
282+
GF16Utils.mul(m00, m12xm23_m13xm22) ^
283+
GF16Utils.mul(m02, m10xm23_m13xm20) ^
284+
GF16Utils.mul(m03, m10xm22_m12xm20)),
243285
(byte)(GF16Utils.mul(m31, m44) ^ GF16Utils.mul(m34, m41)));
244-
result ^= GF16Utils.mul(determinant3x3(m, off, 0, 2, 4),
286+
result ^= GF16Utils.mul(//determinant3x3(m, off, 0, 2, 4),
287+
(byte)(
288+
GF16Utils.mul(m00, m12xm24_m14xm22) ^
289+
GF16Utils.mul(m02, m10xm24_m14xm20) ^
290+
GF16Utils.mul(m04, m10xm22_m12xm20)),
245291
(byte)(GF16Utils.mul(m31, m43) ^ GF16Utils.mul(m33, m41)));
246-
result ^= GF16Utils.mul(determinant3x3(m, off, 0, 3, 4),
292+
result ^= GF16Utils.mul(//determinant3x3(m, off, 0, 3, 4),
293+
(byte)(
294+
GF16Utils.mul(m00, m13xm24_m14xm23) ^
295+
GF16Utils.mul(m03, m10xm24_m14xm20) ^
296+
GF16Utils.mul(m04, m10xm23_m13xm20)),
247297
(byte)(GF16Utils.mul(m31, m42) ^ GF16Utils.mul(m32, m41)));
248-
result ^= GF16Utils.mul(determinant3x3(m, off, 1, 2, 3),
298+
result ^= GF16Utils.mul(//determinant3x3(m, off, 1, 2, 3),
299+
(byte)(
300+
GF16Utils.mul(m01, m12xm23_m13xm22) ^
301+
GF16Utils.mul(m02, m11xm23_m13xm21) ^
302+
GF16Utils.mul(m03, m11xm22_m12xm21)),
249303
(byte)(GF16Utils.mul(m30, m44) ^ GF16Utils.mul(m34, m40)));
250-
result ^= GF16Utils.mul(determinant3x3(m, off, 1, 2, 4),
304+
result ^= GF16Utils.mul(//determinant3x3(m, off, 1, 2, 4),
305+
(byte)(
306+
GF16Utils.mul(m01, m12xm24_m14xm22) ^
307+
GF16Utils.mul(m02, m11xm24_m14xm21) ^
308+
GF16Utils.mul(m04, m11xm22_m12xm21)),
251309
(byte)(GF16Utils.mul(m30, m43) ^ GF16Utils.mul(m33, m40)));
252-
result ^= GF16Utils.mul(determinant3x3(m, off, 1, 3, 4),
310+
result ^= GF16Utils.mul(//determinant3x3(m, off, 1, 3, 4),
311+
(byte)(
312+
GF16Utils.mul(m01, m13xm24_m14xm23) ^
313+
GF16Utils.mul(m03, m11xm24_m14xm21) ^
314+
GF16Utils.mul(m04, m11xm23_m13xm21)),
253315
(byte)(GF16Utils.mul(m30, m42) ^ GF16Utils.mul(m32, m40)));
254-
result ^= GF16Utils.mul(determinant3x3(m, off, 2, 3, 4),
316+
result ^= GF16Utils.mul(//determinant3x3(m, off, 2, 3, 4),
317+
(byte)(
318+
GF16Utils.mul(m02, m13xm24_m14xm23) ^
319+
GF16Utils.mul(m03, m12xm24_m14xm22) ^
320+
GF16Utils.mul(m04, m12xm23_m13xm22)),
255321
(byte)(GF16Utils.mul(m30, m41) ^ GF16Utils.mul(m31, m40)));
256322
return result;
257323
}
@@ -273,13 +339,13 @@ private void generateASMatrix(byte[] target, byte a)
273339
}
274340

275341

276-
private void addMatrices(byte[] a, int aOff, byte[] b, int bOff, byte[] c, int cOff)
342+
private void xorTo(byte[] a, int aOff, byte[] b)
277343
{
278344
for (int i = 0; i < l; i++)
279345
{
280346
for (int j = 0; j < l; j++)
281347
{
282-
setGF16m(c, i, cOff + j, (byte)(getGF16m(a, i, aOff + j) ^ getGF16m(b, i, bOff + j)));
348+
setGF16m(a, i, aOff + j, (byte)(getGF16m(a, i, aOff + j) ^ getGF16m(b, i, j)));
283349
}
284350
}
285351
}
@@ -295,13 +361,13 @@ public void genAFqS(byte[] c, int cOff, byte[] ptMatrix, int off)
295361
for (int i = 1; i < l - 1; ++i)
296362
{
297363
gf16mScale(S[i], c[cOff + i], temp);
298-
addMatrices(ptMatrix, off, temp, 0, ptMatrix, off);
364+
xorTo(ptMatrix, off, temp);
299365
}
300366

301367
// Handle last term with special case
302368
byte lastScalar = (byte)((c[cOff + l - 1] != 0) ? c[cOff + l - 1] : 16 - (c[cOff] + (c[cOff] == 0 ? 1 : 0)));
303369
gf16mScale(S[l - 1], lastScalar, temp);
304-
addMatrices(ptMatrix, off, temp, 0, ptMatrix, off);
370+
xorTo(ptMatrix, off, temp);
305371

306372
// Clear temporary matrix
307373
//clearMatrix(temp);
@@ -342,8 +408,8 @@ public void genF(MapGroup2 map2, MapGroup1 map1, byte[][][] T12)
342408
{
343409
for (int index = 0; index < v; index++)
344410
{
345-
GF16Utils.gf16mMul(map1.p11[i][j][index], T12[index][k], temp, l);
346-
GF16Utils.gf16mAdd(map2.f12[i][j][k], temp, map2.f12[i][j][k], l);
411+
412+
GF16Utils.gf16mMulTo(map1.p11[i][j][index], T12[index][k], map2.f12[i][j][k], l);
347413
}
348414
}
349415
}
@@ -358,8 +424,7 @@ public void genF(MapGroup2 map2, MapGroup1 map1, byte[][][] T12)
358424
{
359425
for (int index = 0; index < v; index++)
360426
{
361-
GF16Utils.gf16mMul(T12[index][j], map1.p11[i][index][k], temp, l);
362-
GF16Utils.gf16mAdd(map2.f21[i][j][k], temp, map2.f21[i][j][k], l);
427+
GF16Utils.gf16mMulTo(T12[index][j], map1.p11[i][index][k], map2.f21[i][j][k], l);
363428
}
364429
}
365430
}
@@ -378,11 +443,7 @@ private static void copy4DMatrix(byte[][][][] src, byte[][][][] dest,
378443
{
379444
for (int k = 0; k < dim3; k++)
380445
{
381-
System.arraycopy(
382-
src[i][j][k], 0,
383-
dest[i][j][k], 0,
384-
lsq
385-
);
446+
System.arraycopy(src[i][j][k], 0, dest[i][j][k], 0, lsq);
386447
}
387448
}
388449
}
@@ -399,47 +460,28 @@ public void genP22(byte[] outP22, byte[][][] T12, byte[][][][] P21, byte[][][][]
399460
// Initialize P22 with zeros
400461
byte[][][][] P22 = new byte[m][o][o][lsq];
401462

402-
// Temporary buffers
403-
byte[] temp1 = new byte[lsq];
404-
byte[] temp2 = new byte[lsq];
405-
406-
try
463+
for (int i = 0; i < m; i++)
407464
{
408-
for (int i = 0; i < m; i++)
465+
for (int j = 0; j < o; j++)
409466
{
410-
for (int j = 0; j < o; j++)
467+
for (int k = 0; k < o; k++)
411468
{
412-
for (int k = 0; k < o; k++)
469+
for (int index = 0; index < v; index++)
413470
{
414-
for (int index = 0; index < v; index++)
415-
{
416-
// temp1 = T12[index][j] * F12[i][index][k]
417-
GF16Utils.gf16mMul(T12[index][j], F12[i][index][k], temp1, l);
418-
419-
// temp2 = P21[i][j][index] * T12[index][k]
420-
GF16Utils.gf16mMul(P21[i][j][index], T12[index][k], temp2, l);
421-
422-
// temp1 += temp2
423-
GF16Utils.gf16mAdd(temp1, temp2, temp1, l);
471+
// temp1 = T12[index][j] * F12[i][index][k]
472+
GF16Utils.gf16mMulTo(T12[index][j], F12[i][index][k], P22[i][j][k], l);
424473

425-
// P22[i][j][k] += temp1
426-
GF16Utils.gf16mAdd(P22[i][j][k], temp1, P22[i][j][k], l);
427-
}
474+
// temp2 = P21[i][j][index] * T12[index][k]
475+
GF16Utils.gf16mMulTo(P21[i][j][index], T12[index][k], P22[i][j][k], l);
428476
}
429477
}
430478
}
431-
432-
// Convert GF16 elements to packed bytes
433-
byte[] tmp = new byte[outP22.length << 1];
434-
MapGroup1.copyTo(P22, tmp);
435-
GF16Utils.encode(tmp, outP22, 0, tmp.length);
436-
}
437-
finally
438-
{
439-
// Secure clear temporary buffers
440-
Arrays.fill(temp1, (byte)0);
441-
Arrays.fill(temp2, (byte)0);
442479
}
480+
481+
// Convert GF16 elements to packed bytes
482+
byte[] tmp = new byte[outP22.length << 1];
483+
MapGroup1.copyTo(P22, tmp);
484+
GF16Utils.encode(tmp, outP22, tmp.length);
443485
}
444486

445487
void genSeedsAndT12(byte[][][] T12, byte[] skSeed)

0 commit comments

Comments
 (0)