Skip to content

Commit 2326ee5

Browse files
committed
Refactoring in ML-KEM:
- remove Symmetric, make MLKemEngine immutable - avoid overproducing implicit-rejection data - reduce memory usage - "Kyber" cleanup
1 parent 947b9cf commit 2326ee5

File tree

17 files changed

+677
-1081
lines changed

17 files changed

+677
-1081
lines changed
Lines changed: 26 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,39 @@
11
package org.bouncycastle.pqc.crypto.mlkem;
22

3-
final class CBD
4-
{
3+
import org.bouncycastle.util.Pack;
54

6-
public static void mlkemCBD(Poly r, byte[] bytes, int eta)
5+
class CBD
6+
{
7+
static void eta2(Poly r, byte[] bytes)
78
{
8-
long t, d;
9-
int a, b;
10-
11-
switch (eta)
9+
for (int i = 0; i < MLKEMEngine.N / 8; i++)
1210
{
13-
case 3:
14-
for (int i = 0; i < MLKEMEngine.KyberN / 4; i++)
15-
{
16-
t = convertByteTo24BitUnsignedInt(bytes, 3 * i);
17-
d = t & 0x00249249;
18-
d = d + ((t >> 1) & 0x00249249);
19-
d = d + ((t >> 2) & 0x00249249);
20-
for (int j = 0; j < 4; j++)
21-
{
22-
a = (short)((d >> (6 * j + 0)) & 0x7);
23-
b = (short)((d >> (6 * j + 3)) & 0x7);
24-
// System.out.printf("a = %d, b = %d\n", a, b);
25-
r.setCoeffIndex(4 * i + j, (short)(a - b));
26-
}
27-
}
28-
break;
29-
default:
30-
// Only for Kyber512 where eta = 2
31-
for (int i = 0; i < MLKEMEngine.KyberN / 8; i++)
11+
int t = Pack.littleEndianToInt(bytes, 4 * i);
12+
int d = t & 0x55555555;
13+
d += (t >>> 1) & 0x55555555;
14+
for (int j = 0; j < 8; j++)
3215
{
33-
t = convertByteTo32BitUnsignedInt(bytes, 4 * i); // ? Problem
34-
d = t & 0x55555555;
35-
d = d + ((t >> 1) & 0x55555555);
36-
for (int j = 0; j < 8; j++)
37-
{
38-
a = (short)((d >> (4 * j + 0)) & 0x3);
39-
b = (short)((d >> (4 * j + eta)) & 0x3);
40-
r.setCoeffIndex(8 * i + j, (short)(a - b));
41-
}
16+
int a = (short)((d >>> (4 * j + 0)) & 0x3);
17+
int b = (short)((d >>> (4 * j + 2)) & 0x3);
18+
r.setCoeffIndex(8 * i + j, (short)(a - b));
4219
}
4320
}
4421
}
4522

46-
/**
47-
* Converts an Array of Bytes to a 32-bit Unsigned Integer
48-
* Returns a 32-bit unsigned integer as a long
49-
*
50-
* @param x
51-
* @return
52-
*/
53-
private static long convertByteTo32BitUnsignedInt(byte[] x, int offset)
23+
static void eta3(Poly r, byte[] bytes)
5424
{
55-
// Convert first byte to an unsigned integer
56-
// byte x & 0xFF allows us to grab the last 8 bits
57-
long r = (long)(x[offset] & 0xFF);
58-
59-
// Perform the same operation then left bit shift to store the next 8 bits without
60-
// altering the previous bits
61-
r = r | (long)((long)(x[offset + 1] & 0xFF) << 8);
62-
r = r | (long)((long)(x[offset + 2] & 0xFF) << 16);
63-
r = r | (long)((long)(x[offset + 3] & 0xFF) << 24);
64-
return r;
65-
}
66-
67-
/**
68-
* Converts an Array of Bytes to a 24-bit Unsigned Integer
69-
* Returns a 24-bit unsigned integer as a long from byte x
70-
*
71-
* @param x
72-
* @return
73-
*/
74-
private static long convertByteTo24BitUnsignedInt(byte[] x, int offset)
75-
{
76-
// Refer to convertByteTo32-BitUnsignedInt for explanation
77-
long r = (long)(x[offset] & 0xFF);
78-
r = r | (long)((long)(x[offset + 1] & 0xFF) << 8);
79-
r = r | (long)((long)(x[offset + 2] & 0xFF) << 16);
80-
return r;
25+
for (int i = 0; i < MLKEMEngine.N / 4; i++)
26+
{
27+
int t = Pack.littleEndianToInt24(bytes, 3 * i);
28+
int d = t & 0x00249249;
29+
d += (t >>> 1) & 0x00249249;
30+
d += (t >>> 2) & 0x00249249;
31+
for (int j = 0; j < 4; j++)
32+
{
33+
int a = (short)((d >>> (6 * j + 0)) & 0x7);
34+
int b = (short)((d >>> (6 * j + 3)) & 0x7);
35+
r.setCoeffIndex(4 * i + j, (short)(a - b));
36+
}
37+
}
8138
}
82-
83-
8439
}

0 commit comments

Comments
 (0)