Skip to content

Commit 8c3b112

Browse files
author
gefeili
committed
Code refactor on GeMSS.
1 parent 5c2eb33 commit 8c3b112

File tree

9 files changed

+570
-978
lines changed

9 files changed

+570
-978
lines changed

core/src/main/java/org/bouncycastle/pqc/crypto/gemss/GeMSSEngine.java

Lines changed: 333 additions & 717 deletions
Large diffs are not rendered by default.

core/src/main/java/org/bouncycastle/pqc/crypto/gemss/GeMSSKeyPairGenerator.java

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public void init(KeyGenerationParameters param)
2525
public AsymmetricCipherKeyPair generateKeyPair()
2626
{
2727
GeMSSEngine engine = parameters.getEngine();
28-
int i;
28+
int i, ret;
2929
byte[] seed = sec_rand(engine.SIZE_SEED_SK);
3030
int NB_COEFS_HFEPOLY = (2 + engine.HFEDegJ + ((engine.HFEDegI * (engine.HFEDegI + 1)) >>> 1));
3131
int NB_COEFS_HFEVPOLY = (NB_COEFS_HFEPOLY + (engine.NB_MONOMIAL_VINEGAR - 1) + (engine.HFEDegI + 1) * engine.HFEv);
@@ -43,14 +43,9 @@ public AsymmetricCipherKeyPair generateKeyPair()
4343
F.fill(0, sk_uncomp, 0, sk_uncomp.length);
4444
engine.cleanMonicHFEv_gf2nx(F);
4545
Pointer Q = new Pointer(engine.NB_MONOMIAL_PK * engine.NB_WORD_GFqn);
46-
int ret;
4746
if (engine.HFEDeg > 34)
4847
{
4948
engine.genSecretMQS_gf2_opt(Q, F);
50-
// if (ret != 0)
51-
// {
52-
// throw new IllegalArgumentException("Error");
53-
// }
5449
}
5550
Pointer S = new Pointer(engine.MATRIXnv_SIZE);
5651
Pointer T = new Pointer(S);
@@ -80,51 +75,46 @@ public AsymmetricCipherKeyPair generateKeyPair()
8075
if (engine.HFEmr8 != 0)
8176
{
8277
final int MQ_GFqm8_SIZE = (engine.NB_MONOMIAL_PK * engine.NB_BYTES_GFqm + ((8 - (engine.NB_BYTES_GFqm & 7)) & 7));
83-
Pointer pk_tmp = new PointerUnion(MQ_GFqm8_SIZE);
84-
i = (engine.NB_BYTES_GFqm & 7) != 0 ? 1 : 0;
85-
Pointer Q_cp = new Pointer(Q);
86-
PointerUnion pk_cp = new PointerUnion((PointerUnion)pk_tmp);
78+
PointerUnion pk_cp = new PointerUnion(MQ_GFqm8_SIZE);
8779
/* for each monomial of MQS and pk */
88-
for (; i < engine.NB_MONOMIAL_PK; ++i)
80+
for (i = (engine.NB_BYTES_GFqm & 7) != 0 ? 1 : 0; i < engine.NB_MONOMIAL_PK; ++i)
8981
{
90-
engine.vecMatProduct(pk_cp, Q_cp, T, GeMSSEngine.FunctionParams.M);
82+
engine.vecMatProduct(pk_cp, Q, T, GeMSSEngine.FunctionParams.M);
9183
/* next monomial */
92-
Q_cp.move(engine.NB_WORD_GFqn);
84+
Q.move(engine.NB_WORD_GFqn);
9385
pk_cp.moveNextBytes(engine.NB_BYTES_GFqm);
9486
}
9587
/* Last monomial: we fill the last bytes of pk without 64-bit cast. */
9688
if ((engine.NB_BYTES_GFqm & 7) != 0)
9789
{
9890
Pointer pk_last = new Pointer(engine.NB_WORD_GF2m);
99-
engine.vecMatProduct(pk_last, Q_cp, T, GeMSSEngine.FunctionParams.M);
91+
engine.vecMatProduct(pk_last, Q, T, GeMSSEngine.FunctionParams.M);
10092
for (i = 0; i < engine.NB_WORD_GF2m; ++i)
10193
{
10294
pk_cp.set(i, pk_last.get(i));
10395
}
10496
}
10597
pk_cp.indexReset();
98+
byte[] pk_U = new byte[engine.HFEmr8 * engine.NB_BYTES_EQUATION];
99+
engine.convMQS_one_to_last_mr8_equations_gf2(pk_U, pk_cp);
100+
pk_cp.indexReset();
106101
if (engine.HFENr8 != 0 && engine.HFEmr8 > 1)
107102
{
108-
engine.convMQS_one_eq_to_hybrid_rep8_uncomp_gf2(pk, pk_cp);
103+
engine.convMQS_one_eq_to_hybrid_rep8_uncomp_gf2(pk, pk_cp, pk_U);
109104
}
110105
else
111106
{
112-
engine.convMQS_one_eq_to_hybrid_rep8_comp_gf2(pk, pk_cp);
107+
engine.convMQS_one_eq_to_hybrid_rep8_comp_gf2(pk, pk_cp, pk_U);
113108
}
114109
}
115110
else
116111
{
117112
PointerUnion pk_last = new PointerUnion(engine.NB_WORD_GF2m << 3);
118-
int pk_p = 0, j;
113+
int pk_p = 0;
119114
for (i = 0; i < engine.NB_MONOMIAL_PK; ++i)
120115
{
121116
engine.vecMatProduct(pk_last, Q, T, GeMSSEngine.FunctionParams.M);
122-
for (j = 0; j < engine.NB_BYTES_GFqm; ++j)
123-
{
124-
pk[pk_p] = pk_last.getByte();
125-
pk_p++;
126-
pk_last.moveNextByte();
127-
}
117+
pk_p = pk_last.toBytesMove(pk, pk_p, engine.NB_BYTES_GFqm);
128118
pk_last.indexReset();
129119
Q.move(engine.NB_WORD_GFqn);
130120
}

core/src/main/java/org/bouncycastle/pqc/crypto/gemss/GeMSSUtils.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@ static long ORBITS_UINT(long n)
5151
/* Compare two UINT in constant-time */
5252
static long CMP_LT_UINT(long a, long b)
5353
{
54-
return (((((a) >>> 63) ^ ((b) >>> 63)) & ((((a) >>> 63) - ((b) >>> 63)) >>> 63))
55-
^ ((((a) >>> 63) ^ ((b) >>> 63) ^ 1L) & ((((a) & (0x7FFFFFFFFFFFFFFFL))
56-
- ((b) & (0x7FFFFFFFFFFFFFFFL))) >>> 63)));
54+
return ((((a >>> 63) ^ (b >>> 63)) & (((a >>> 63) - (b >>> 63)) >>> 63))
55+
^ (((a >>> 63) ^ (b >>> 63) ^ 1L) & (((a & (0x7FFFFFFFFFFFFFFFL))
56+
- (b & (0x7FFFFFFFFFFFFFFFL))) >>> 63)));
5757
}
5858

5959
static long maskUINT(int k)

core/src/main/java/org/bouncycastle/pqc/crypto/gemss/Mul_GF2x.java

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,6 @@ public void sqr_gf2x(long[] res, long[] A, int a_cp)
119119
public void mul_gf2x_xor(Pointer res, Pointer A, Pointer B)
120120
{
121121
mul416_no_simd_gf2x_xor(res.array, A.array, A.cp, B.array, B.cp, Buffer, Buffer2);
122-
// res.setXorRange(C, C.array.length);
123122
}
124123
}
125124

@@ -702,7 +701,7 @@ public static void mul192_no_simd_gf2x_xor(long[] C, int c_cp, long[] A, int a_c
702701

703702
private static void mul288_no_simd_gf2x(long[] C, int c_cp, long[] A, int a_cp, long[] B, int b_cp, long[] RESERVED_BUF)
704703
{
705-
mul128_no_simd_gf2x(C, c_cp, A, a_cp, B, b_cp);
704+
mul128_no_simd_gf2x(C, c_cp, A[a_cp], A[a_cp + 1], B[b_cp], B[b_cp + 1]);
706705
MUL64_NO_SIMD_GF2X(C, c_cp + 4, A[a_cp + 2], B[b_cp + 2]); //x0,x1
707706
MUL64_NO_SIMD_GF2X(C, c_cp + 7, A[a_cp + 3], B[b_cp + 3]);//x2,x3
708707
C[c_cp + 7] ^= C[c_cp + 5];//x1+x2
@@ -740,7 +739,7 @@ private static void mul288_no_simd_gf2x(long[] C, int c_cp, long[] A, int a_cp,
740739

741740
private static void mul288_no_simd_gf2x_xor(long[] C, int c_cp, long[] A, int a_cp, long[] B, int b_cp, long[] Buffer)
742741
{
743-
mul128_no_simd_gf2x(Buffer, 0, A, a_cp, B, b_cp);
742+
mul128_no_simd_gf2x(Buffer, 0, A[a_cp], A[a_cp + 1], B[b_cp], B[b_cp + 1]);
744743
MUL64_NO_SIMD_GF2X(Buffer, 4, A[a_cp + 2], B[b_cp + 2]); //x0,x1
745744
MUL64_NO_SIMD_GF2X(Buffer, 7, A[a_cp + 3], B[b_cp + 3]);//x2,x3
746745
Buffer[7] ^= Buffer[5];//x1+x2
@@ -870,7 +869,7 @@ private static void mul384_no_simd_gf2x_xor(long[] C, long[] A, int a_cp, long[]
870869
private static void mul416_no_simd_gf2x(long[] C, long[] A, int a_cp, long[] B, int b_cp, long[] RESERVED_BUF)
871870
{
872871
mul192_no_simd_gf2x(C, 0, A, a_cp, B, b_cp);
873-
mul128_no_simd_gf2x(C, 6, A, a_cp + 3, B, b_cp + 3);
872+
mul128_no_simd_gf2x(C, 6, A[a_cp + 3], A[a_cp + 4], B[b_cp + 3], B[b_cp + 4]);
874873
MUL64_NO_SIMD_GF2X(C, 10, A[a_cp + 5], B[b_cp + 5]);
875874
C[12] = MUL32_NO_SIMD_GF2X(A[a_cp + 6], B[b_cp + 6]) ^ C[11];
876875
C[11] = C[10] ^ C[12];
@@ -913,7 +912,7 @@ private static void mul416_no_simd_gf2x(long[] C, long[] A, int a_cp, long[] B,
913912
private static void mul416_no_simd_gf2x_xor(long[] C, long[] A, int a_cp, long[] B, int b_cp, long[] Buffer, long[] Buffer2)
914913
{
915914
mul192_no_simd_gf2x(Buffer, 0, A, a_cp, B, b_cp);
916-
mul128_no_simd_gf2x(Buffer, 6, A, a_cp + 3, B, b_cp + 3);
915+
mul128_no_simd_gf2x(Buffer, 6, A[a_cp + 3], A[a_cp + 4], B[b_cp + 3], B[b_cp + 4]);
917916
MUL64_NO_SIMD_GF2X(Buffer, 10, A[a_cp + 5], B[b_cp + 5]);
918917
Buffer[12] = MUL32_NO_SIMD_GF2X(A[a_cp + 6], B[b_cp + 6]) ^ Buffer[11];
919918
Buffer[11] = Buffer[10] ^ Buffer[12];
@@ -969,8 +968,8 @@ private static void mul416_no_simd_gf2x_xor(long[] C, long[] A, int a_cp, long[]
969968
private static void mul544_no_simd_gf2x(long[] C, long[] A, int a_cp, long[] B, int b_cp, long[] AA, long[] BB,
970969
long[] RESERVED_BUF9)
971970
{
972-
mul128_no_simd_gf2x(C, 0, A, a_cp, B, b_cp);
973-
mul128_no_simd_gf2x(C, 4, A, a_cp + 2, B, b_cp + 2);
971+
mul128_no_simd_gf2x(C, 0, A[a_cp], A[a_cp + 1], B[b_cp], B[b_cp + 1]);
972+
mul128_no_simd_gf2x(C, 4, A[a_cp + 2], A[a_cp + 3], B[b_cp + 2], B[b_cp + 3]);
974973
C[4] ^= C[2];
975974
C[5] ^= C[3];
976975
C[2] = C[4] ^ C[0];
@@ -1009,8 +1008,8 @@ private static void mul544_no_simd_gf2x(long[] C, long[] A, int a_cp, long[] B,
10091008
private static void mul544_no_simd_gf2x_xor(long[] C, long[] A, int a_cp, long[] B, int b_cp, long[] AA, long[] BB,
10101009
long[] Buffer, long[] Buffer2)
10111010
{
1012-
mul128_no_simd_gf2x(Buffer, 0, A, a_cp, B, b_cp);
1013-
mul128_no_simd_gf2x(Buffer, 4, A, a_cp + 2, B, b_cp + 2);
1011+
mul128_no_simd_gf2x(Buffer, 0, A[a_cp], A[a_cp + 1], B[b_cp], B[b_cp + 1]);
1012+
mul128_no_simd_gf2x(Buffer, 4, A[a_cp + 2], A[a_cp + 3], B[b_cp + 2], B[b_cp + 3]);
10141013
Buffer[4] ^= Buffer[2];
10151014
Buffer[5] ^= Buffer[3];
10161015
Buffer[2] = Buffer[4] ^ Buffer[0];

core/src/main/java/org/bouncycastle/pqc/crypto/gemss/Pointer.java

Lines changed: 100 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -162,20 +162,10 @@ public void setXorRange(int outOff, PointerUnion p, int inOff, int len)
162162
}
163163
}
164164

165-
public void setRangeAndMask(int outOff, Pointer p, int inOff, int len, long mask)
165+
public void setXorRangeAndMask(Pointer p, int len, long mask)
166166
{
167-
outOff += cp;
168-
inOff += p.cp;
169-
for (int i = 0; i < len; ++i)
170-
{
171-
array[outOff++] = p.array[inOff++] & mask;
172-
}
173-
}
174-
175-
public void setXorRangeAndMask(int outOff, Pointer p, int inOff, int len, long mask)
176-
{
177-
outOff += cp;
178-
inOff += p.cp;
167+
int outOff = cp;
168+
int inOff = p.cp;
179169
for (int i = 0; i < len; ++i)
180170
{
181171
array[outOff++] ^= p.array[inOff++] & mask;
@@ -279,7 +269,6 @@ public void set1_gf2n(int startPos, int size)
279269
{
280270
int pos = cp + startPos;
281271
array[pos++] = 1L;
282-
//Arrays.fill(array, pos, size - 1, 0L);
283272
for (int i = 1; i < size; ++i)
284273
{
285274
array[pos++] = 0L;
@@ -339,6 +328,27 @@ public void setRangeFromXor(int outOff, Pointer a, int aOff, Pointer b, int bOff
339328
}
340329
}
341330

331+
public void setRangeFromXor(Pointer a, Pointer b, int len)
332+
{
333+
for (int i = 0, outOff = cp, aOff = a.cp, bOff = b.cp; i < len; ++i)
334+
{
335+
array[outOff++] = a.array[aOff++] ^ b.array[bOff++];
336+
}
337+
}
338+
339+
public void setRangeFromXorAndMask_xor(Pointer a, Pointer b, long mask, int len)
340+
{
341+
int outOff = cp;
342+
int a_cp = a.cp;
343+
int b_cp = b.cp;
344+
for (int i = 0; i < len; ++i)
345+
{
346+
array[outOff] = (a.array[a_cp] ^ b.array[b_cp]) & mask;
347+
a.array[a_cp++] ^= array[outOff];
348+
b.array[b_cp++] ^= array[outOff++];
349+
}
350+
}
351+
342352
public int is0_gf2n(int p, int size)
343353
{
344354
long r = get(p);
@@ -361,15 +371,23 @@ public long getDotProduct(int off, Pointer b, int bOff, int len)
361371
return res;
362372
}
363373

364-
public long isNot0_gf2n(int off, int size)
374+
public int getD_for_not0_or_plus(int NB_WORD_GFqn, int start)
365375
{
366-
off += cp;
367-
long r = array[off];
368-
for (int i = 1; i < size; ++i)
376+
int i, j, d, pos;
377+
long mask, b;
378+
/* Search the degree of X^(2^n) - X mod (F-U) */
379+
for (i = start, d = 0, mask = 0L, pos = cp; i > 0; --i)
369380
{
370-
r |= array[off++];
381+
b = array[pos++];
382+
for (j = 1; j < NB_WORD_GFqn; ++j)
383+
{
384+
b |= array[pos++];
385+
}
386+
mask |= GeMSSUtils.ORBITS_UINT(b);
387+
/* We add 1 to d as soon as we exceed all left zero coefficients */
388+
d += mask;
371389
}
372-
return GeMSSUtils.ORBITS_UINT(r);
390+
return d;
373391
}
374392

375393
public int setRange_xi(long xi, int k, int len)
@@ -419,8 +437,7 @@ public void setRangePointerUnion(PointerUnion p, int len, int shift)
419437
{
420438
for (int i = 0; i < len; ++i)
421439
{
422-
array[outOff++] = (p.array[inOff] >>> right2) ^ (p.array[inOff + 1] << left2);
423-
inOff++;
440+
array[outOff++] = (p.array[inOff] >>> right2) ^ (p.array[++inOff] << left2);
424441
}
425442
}
426443
else
@@ -429,10 +446,68 @@ public void setRangePointerUnion(PointerUnion p, int len, int shift)
429446
int left1 = ((8 - p.remainder) << 3);
430447
for (int i = 0; i < len; ++i)
431448
{
432-
array[outOff++] = (((p.array[inOff] >>> right1) | (p.array[inOff + 1] << left1)) >>> right2) ^
433-
(((p.array[inOff + 1] >>> right1) | (p.array[inOff + 2] << left1)) << left2);
434-
inOff++;
449+
array[outOff++] = (((p.array[inOff] >>> right1) | (p.array[++inOff] << left1)) >>> right2) ^
450+
(((p.array[inOff] >>> right1) | (p.array[inOff + 1] << left1)) << left2);
451+
}
452+
}
453+
}
454+
455+
public void setRangePointerUnion_Check(PointerUnion p, int len, int shift)
456+
{
457+
int right2 = shift & 63;
458+
int left2 = 64 - right2;
459+
int outOff = cp;
460+
int inOff = p.cp;
461+
int i;
462+
if (p.remainder == 0)
463+
{
464+
for (i = 0; i < len && inOff < p.array.length - 1; ++i)
465+
{
466+
array[outOff++] = (p.array[inOff] >>> right2) ^ (p.array[++inOff] << left2);
467+
}
468+
if (i < len)
469+
{
470+
array[outOff] = (p.array[inOff] >>> right2);
471+
}
472+
}
473+
else
474+
{
475+
int right1 = p.remainder << 3;
476+
int left1 = ((8 - p.remainder) << 3);
477+
for (i = 0; i < len && inOff < p.array.length - 2; ++i)
478+
{
479+
array[outOff++] = (((p.array[inOff] >>> right1) | (p.array[++inOff] << left1)) >>> right2) ^
480+
(((p.array[inOff] >>> right1) | (p.array[inOff + 1] << left1)) << left2);
481+
}
482+
if (i < len)
483+
{
484+
array[outOff] = (((p.array[inOff] >>> right1) | (p.array[++inOff] << left1)) >>> right2) ^
485+
((p.array[inOff] >>> right1) << left2);
486+
}
487+
}
488+
}
489+
490+
public int isEqual_nocst_gf2(Pointer b, int len)
491+
{
492+
int inOff = b.cp;
493+
int outOff = cp;
494+
for (int i = 0; i < len; ++i)
495+
{
496+
if (array[outOff++] != b.array[inOff++])
497+
{
498+
return 0;
435499
}
436500
}
501+
return 1;
502+
}
503+
504+
public void swap(Pointer b)
505+
{
506+
long[] tmp_array = b.array;
507+
int tmp_cp = b.cp;
508+
b.array = array;
509+
b.cp = cp;
510+
array = tmp_array;
511+
cp = tmp_cp;
437512
}
438513
}

core/src/main/java/org/bouncycastle/pqc/crypto/gemss/Pointer32.java

Lines changed: 0 additions & 53 deletions
This file was deleted.

0 commit comments

Comments
 (0)