Skip to content

Commit f3217ed

Browse files
author
royb
committed
Added aes variant to kyber
1 parent 0f9f61d commit f3217ed

File tree

5 files changed

+95
-55
lines changed

5 files changed

+95
-55
lines changed

core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/KyberEngine.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ public int getKyberEta1()
144144
return KyberEta1;
145145
}
146146

147-
public KyberEngine(int k)
147+
public KyberEngine(int k, boolean usingAes)
148148
{
149149
this.KyberK = k;
150150
switch (k)
@@ -185,7 +185,15 @@ public KyberEngine(int k)
185185
this.CryptoPublicKeyBytes = KyberPublicKeyBytes;
186186
this.CryptoCipherTextBytes = KyberCipherTextBytes;
187187

188-
symmetric = new Symmetric.ShakeSymmetric();
188+
if(usingAes)
189+
{
190+
symmetric = new Symmetric.AesSymmetric();
191+
}
192+
else
193+
{
194+
symmetric = new Symmetric.ShakeSymmetric();
195+
}
196+
189197
this.indCpa = new KyberIndCpa(this);
190198

191199

core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/KyberIndCpa.java

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,16 @@ public KyberIndCpa(KyberEngine engine)
2929
this.polyVecCompressedBytes = engine.getKyberPolyVecCompressedBytes();
3030
this.polyCompressedBytes = engine.getKyberPolyCompressedBytes();
3131
this.symmetric = engine.getSymmetric();
32+
33+
KyberGenerateMatrixNBlocks =
34+
(
35+
(
36+
12 * KyberEngine.KyberN
37+
/ 8 * (1 << 12)
38+
/ KyberEngine.KyberQ + symmetric.xofBlockBytes
39+
)
40+
/ symmetric.xofBlockBytes
41+
);
3242
}
3343

3444

@@ -311,21 +321,13 @@ public void unpackSecretKey(PolyVec secretKeyPolyVec, byte[] secretKey)
311321
secretKeyPolyVec.fromBytes(secretKey);
312322
}
313323

314-
public final static int KyberGenerateMatrixNBlocks =
315-
(
316-
(
317-
12 * KyberEngine.KyberN
318-
/ 8 * (1 << 12)
319-
/ KyberEngine.KyberQ + Symmetric.SHAKE128_rate
320-
)
321-
/ Symmetric.SHAKE128_rate
322-
);
324+
public final int KyberGenerateMatrixNBlocks;
323325

324326
public void generateMatrix(PolyVec[] aMatrix, byte[] seed, boolean transposed)
325327
{
326328
int i, j, k, ctr, off;
327329
SHAKEDigest kyberXOF;
328-
byte[] buf = new byte[KyberGenerateMatrixNBlocks * Symmetric.SHAKE128_rate + 2];
330+
byte[] buf = new byte[KyberGenerateMatrixNBlocks * symmetric.xofBlockBytes + 2];
329331
for (i = 0; i < kyberK; i++)
330332
{
331333
for (j = 0; j < kyberK; j++)
@@ -338,9 +340,9 @@ public void generateMatrix(PolyVec[] aMatrix, byte[] seed, boolean transposed)
338340
{
339341
symmetric.xofAbsorb(seed, (byte) j, (byte) i);
340342
}
341-
symmetric.xofSqueezeBlocks(buf, 0, Symmetric.SHAKE128_rate * KyberGenerateMatrixNBlocks);
343+
symmetric.xofSqueezeBlocks(buf, 0, symmetric.xofBlockBytes * KyberGenerateMatrixNBlocks);
342344

343-
int buflen = KyberGenerateMatrixNBlocks * Symmetric.SHAKE128_rate;
345+
int buflen = KyberGenerateMatrixNBlocks * symmetric.xofBlockBytes;
344346
ctr = rejectionSampling(aMatrix[i].getVectorIndex(j), 0, KyberEngine.KyberN, buf, buflen);
345347

346348
while (ctr < KyberEngine.KyberN)
@@ -350,8 +352,8 @@ public void generateMatrix(PolyVec[] aMatrix, byte[] seed, boolean transposed)
350352
{
351353
buf[k] = buf[buflen - off + k];
352354
}
353-
symmetric.xofSqueezeBlocks(buf, off, Symmetric.SHAKE128_rate * 2);
354-
buflen = off + Symmetric.SHAKE128_rate;
355+
symmetric.xofSqueezeBlocks(buf, off, symmetric.xofBlockBytes * 2);
356+
buflen = off + symmetric.xofBlockBytes;
355357
// Error in code Section Unsure
356358
ctr += rejectionSampling(aMatrix[i].getVectorIndex(j), ctr, KyberEngine.KyberN - ctr, buf, buflen);
357359
}

core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/KyberParameters.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,24 @@
22

33
public class KyberParameters
44
{
5-
public static final KyberParameters kyber512 = new KyberParameters("kyber512", 2, 128);
6-
public static final KyberParameters kyber768 = new KyberParameters("kyber768", 3, 192);
7-
public static final KyberParameters kyber1024 = new KyberParameters("kyber1024", 4, 256);
5+
public static final KyberParameters kyber512 = new KyberParameters("kyber512", 2, 128, false);
6+
public static final KyberParameters kyber768 = new KyberParameters("kyber768", 3, 192, false);
7+
public static final KyberParameters kyber1024 = new KyberParameters("kyber1024", 4, 256, false);
8+
public static final KyberParameters kyber512_aes = new KyberParameters("kyber512-aes", 2, 128, true);
9+
public static final KyberParameters kyber768_aes = new KyberParameters("kyber768-aes", 3, 192, true);
10+
public static final KyberParameters kyber1024_aes = new KyberParameters("kyber1024-aes", 4, 256, true);
811

912
private final String name;
1013
private final int k;
1114
private final int sessionKeySize;
15+
private final boolean usingAes;
1216

13-
private KyberParameters(String name, int k, int sessionKeySize)
17+
private KyberParameters(String name, int k, int sessionKeySize, boolean usingAes)
1418
{
1519
this.name = name;
1620
this.k = k;
1721
this.sessionKeySize = sessionKeySize;
22+
this.usingAes = usingAes;
1823
}
1924

2025
public String getName()
@@ -24,7 +29,7 @@ public String getName()
2429

2530
KyberEngine getEngine()
2631
{
27-
return new KyberEngine(k);
32+
return new KyberEngine(k, usingAes);
2833
}
2934

3035
public int getSessionKeySize()

core/src/main/java/org/bouncycastle/pqc/crypto/crystals/kyber/Symmetric.java

Lines changed: 53 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
package org.bouncycastle.pqc.crypto.crystals.kyber;
22

3+
import org.bouncycastle.crypto.ExtendedDigest;
4+
import org.bouncycastle.crypto.digests.SHA256Digest;
35
import org.bouncycastle.crypto.digests.SHA3Digest;
6+
import org.bouncycastle.crypto.digests.SHA512Digest;
47
import org.bouncycastle.crypto.digests.SHAKEDigest;
8+
import org.bouncycastle.crypto.engines.AESEngine;
9+
import org.bouncycastle.crypto.modes.SICBlockCipher;
10+
import org.bouncycastle.crypto.params.KeyParameter;
11+
import org.bouncycastle.crypto.params.ParametersWithIV;
12+
import org.bouncycastle.util.Arrays;
513

614
abstract class Symmetric
715
{
@@ -93,71 +101,82 @@ void kdf(byte[] out, byte[] in)
93101
static class AesSymmetric
94102
extends Symmetric
95103
{
96-
AesSymmetric()
97-
{
104+
private final SHA256Digest sha256Digest;
105+
private final SHA512Digest sha512Digest;
106+
private final SICBlockCipher cipher;
107+
108+
AesSymmetric() {
98109
super(64);
110+
this.sha256Digest = new SHA256Digest();
111+
this.sha512Digest = new SHA512Digest();
112+
this.cipher = new SICBlockCipher(new AESEngine());
113+
}
114+
115+
private void doDigest(ExtendedDigest digest, byte[] out, byte[] in, int outOffset)
116+
{
117+
digest.update(in, 0, in.length);
118+
digest.doFinal(out, outOffset);
119+
}
120+
121+
private void aes128(byte[] out, int offset, int size)
122+
{
123+
byte[] buf = new byte[size]; // TODO: there might be a more efficient way of doing this...
124+
cipher.processBytes(buf, 0, size, out, offset);
99125
}
100126

101127
@Override
102128
void hash_h(byte[] out, byte[] in, int outOffset)
103129
{
104-
130+
sha256Digest.update(in, 0, in.length);
131+
sha256Digest.doFinal(out, outOffset);
132+
// doDigest(sha256Digest, out, in, outOffset);
105133
}
106134

107135
@Override
108136
void hash_g(byte[] out, byte[] in)
109137
{
110-
138+
sha512Digest.update(in, 0, in.length);
139+
sha512Digest.doFinal(out, 0);
140+
// doDigest(sha512Digest, out, in, 0);
111141
}
112142

113143
@Override
114-
void xofAbsorb(byte[] seed, byte x, byte y)
144+
void xofAbsorb(byte[] key, byte x, byte y)
115145
{
146+
byte[] expnonce = new byte[12];
147+
expnonce[0] = x;
148+
expnonce[1] = y;
116149

150+
ParametersWithIV kp = new ParametersWithIV(new KeyParameter(Arrays.copyOfRange(key, 0, 32)), expnonce);
151+
cipher.init(true, kp);
117152
}
118153

119154
@Override
120155
void xofSqueezeBlocks(byte[] out, int outOffset, int outLen)
121156
{
122-
157+
aes128(out, outOffset, outLen);
123158
}
124159

125160
@Override
126161
void prf(byte[] out, byte[] key, byte nonce)
127162
{
128-
163+
SICBlockCipher prf = new SICBlockCipher(new AESEngine());
164+
byte[] expnonce = new byte[12];
165+
expnonce[0] = nonce;
166+
167+
ParametersWithIV kp = new ParametersWithIV(new KeyParameter(Arrays.copyOfRange(key, 0, 32)), expnonce);
168+
prf.init(true, kp);
169+
aes128(out, 0, out.length);
170+
byte[] buf = new byte[out.length]; // TODO: there might be a more efficient way of doing this...
171+
prf.processBytes(buf, 0, out.length, out, 0);
129172
}
130173

131174
@Override
132175
void kdf(byte[] out, byte[] in)
133176
{
134-
177+
sha256Digest.update(in, 0, in.length);
178+
sha256Digest.doFinal(out, 0);
179+
// doDigest(sha256Digest, out, in, 0);
135180
}
136181
}
137-
public static SHAKEDigest KyberXOF(byte[] seed, int a, int b)
138-
{
139-
SHAKEDigest xof = new SHAKEDigest(128);
140-
byte[] buf = new byte[seed.length + 2];
141-
System.arraycopy(seed, 0, buf, 0, seed.length);
142-
buf[seed.length] = (byte)a;
143-
buf[seed.length + 1] = (byte)b;
144-
145-
xof.update(buf, 0, seed.length + 2);
146-
147-
148-
return xof;
149-
}
150-
151-
public final static int SHAKE128_rate = 168;
152-
153-
public static SHAKEDigest KyberPRF(byte[] seed, byte nonce)
154-
{
155-
SHAKEDigest prf = new SHAKEDigest(256);
156-
157-
byte[] extSeed = new byte[seed.length + 1];
158-
System.arraycopy(seed, 0, extSeed, 0, seed.length);
159-
extSeed[seed.length] = nonce;
160-
prf.update(extSeed, 0, extSeed.length);
161-
return prf;
162-
}
163182
}

core/src/test/java/org/bouncycastle/pqc/crypto/test/CrystalsKyberTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,18 @@ public void testVectors()
103103
KyberParameters.kyber512,
104104
KyberParameters.kyber768,
105105
KyberParameters.kyber1024,
106+
// KyberParameters.kyber512,
107+
// KyberParameters.kyber768,
108+
// KyberParameters.kyber1024,
106109
};
107110

108111
String[] files = new String[]{
109112
"kyber512.rsp",
110113
"kyber768.rsp",
111114
"kyber1024.rsp",
115+
// "kyber512aes.rsp",
116+
// "kyber768aes.rsp",
117+
// "kyber1024aes.rsp",
112118
};
113119

114120
TestSampler sampler = new TestSampler();

0 commit comments

Comments
 (0)