|
1 | 1 | package org.bouncycastle.pqc.crypto.mlkem; |
2 | 2 |
|
3 | | -final class CBD |
4 | | -{ |
| 3 | +import org.bouncycastle.util.Pack; |
5 | 4 |
|
6 | | - public static void mlkemCBD(Poly r, byte[] bytes, int eta) |
| 5 | +class CBD |
| 6 | +{ |
| 7 | + static void eta2(Poly r, byte[] bytes) |
7 | 8 | { |
8 | | - long t, d; |
9 | | - int a, b; |
10 | | - |
11 | | - switch (eta) |
| 9 | + for (int i = 0; i < MLKEMEngine.N / 8; i++) |
12 | 10 | { |
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++) |
32 | 15 | { |
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)); |
42 | 19 | } |
43 | 20 | } |
44 | 21 | } |
45 | 22 |
|
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) |
54 | 24 | { |
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 | + } |
81 | 38 | } |
82 | | - |
83 | | - |
84 | 39 | } |
0 commit comments