Skip to content

Commit d24c6be

Browse files
committed
Merge branch 'main' of gitlab.cryptoworkshop.com:root/bc-java
2 parents e776ac2 + 6e8f4fd commit d24c6be

File tree

9 files changed

+110
-68
lines changed

9 files changed

+110
-68
lines changed

core/src/main/java/org/bouncycastle/pqc/crypto/lms/HSSPrivateKeyParameters.java

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ else if (src instanceof byte[])
129129
{
130130
// old style single LMS key.
131131
LMSPrivateKeyParameters lmsKey = LMSPrivateKeyParameters.getInstance(src);
132-
return new HSSPrivateKeyParameters(lmsKey, lmsKey.getIndex(), lmsKey.getIndex() + lmsKey.getUsagesRemaining());
132+
return new HSSPrivateKeyParameters(lmsKey, lmsKey.getIndex(), lmsKey.getIndexLimit());
133133
}
134134
}
135135
finally
@@ -212,7 +212,7 @@ long getIndexLimit()
212212

213213
public long getUsagesRemaining()
214214
{
215-
return indexLimit - index;
215+
return getIndexLimit() - getIndex();
216216
}
217217

218218
LMSPrivateKeyParameters getRootKey()
@@ -233,32 +233,33 @@ public HSSPrivateKeyParameters extractKeyShard(int usageCount)
233233
{
234234
synchronized (this)
235235
{
236-
237-
if (getUsagesRemaining() < usageCount)
236+
if (usageCount < 0)
237+
{
238+
throw new IllegalArgumentException("usageCount cannot be negative");
239+
}
240+
if (usageCount > indexLimit - index)
238241
{
239242
throw new IllegalArgumentException("usageCount exceeds usages remaining in current leaf");
240243
}
241244

242-
long maxIndexForShard = index + usageCount;
243-
long shardStartIndex = index;
245+
long shardIndex = index;
246+
long shardIndexLimit = index + usageCount;
244247

245-
//
246-
// Move this keys index along
247-
//
248-
index += usageCount;
248+
// Move this key's index along
249+
index = shardIndexLimit;
249250

250251
List<LMSPrivateKeyParameters> keys = new ArrayList<LMSPrivateKeyParameters>(this.getKeys());
251252
List<LMSSignature> sig = new ArrayList<LMSSignature>(this.getSig());
252253

253-
HSSPrivateKeyParameters shard = makeCopy(new HSSPrivateKeyParameters(l, keys, sig, shardStartIndex, maxIndexForShard, true));
254+
HSSPrivateKeyParameters shard = makeCopy(
255+
new HSSPrivateKeyParameters(l, keys, sig, shardIndex, shardIndexLimit, true));
254256

255257
resetKeyToIndex();
256258

257259
return shard;
258260
}
259261
}
260262

261-
262263
synchronized List<LMSPrivateKeyParameters> getKeys()
263264
{
264265
return keys;

core/src/main/java/org/bouncycastle/pqc/crypto/lms/LMSPrivateKeyParameters.java

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -253,14 +253,22 @@ public LMSPrivateKeyParameters extractKeyShard(int usageCount)
253253
{
254254
synchronized (this)
255255
{
256-
if (q + usageCount >= maxQ)
256+
if (usageCount < 0)
257+
{
258+
throw new IllegalArgumentException("usageCount cannot be negative");
259+
}
260+
if (usageCount > maxQ - q)
257261
{
258262
throw new IllegalArgumentException("usageCount exceeds usages remaining");
259263
}
260-
LMSPrivateKeyParameters keyParameters = new LMSPrivateKeyParameters(this, q, q + usageCount);
261-
q += usageCount;
262264

263-
return keyParameters;
265+
int shardIndex = q;
266+
int shardIndexLimit = q + usageCount;
267+
268+
// Move this key's index along
269+
q = shardIndexLimit;
270+
271+
return new LMSPrivateKeyParameters(this, shardIndex, shardIndexLimit);
264272
}
265273
}
266274

@@ -284,9 +292,15 @@ public byte[] getMasterSecret()
284292
return Arrays.clone(masterSecret);
285293
}
286294

295+
public int getIndexLimit()
296+
{
297+
return maxQ;
298+
}
299+
300+
// TODO Only needs 'int'
287301
public long getUsagesRemaining()
288302
{
289-
return maxQ - getIndex();
303+
return getIndexLimit() - getIndex();
290304
}
291305

292306
public LMSPublicKeyParameters getPublicKey()

core/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUKEMExtractor.java

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
public class NTRUKEMExtractor
1212
implements EncapsulatedSecretExtractor
1313
{
14-
private final NTRUParameters params;
1514
private final NTRUPrivateKeyParameters ntruPrivateKey;
1615

1716
/**
@@ -22,53 +21,50 @@ public class NTRUKEMExtractor
2221
*/
2322
public NTRUKEMExtractor(NTRUPrivateKeyParameters ntruPrivateKey)
2423
{
25-
this.params = ntruPrivateKey.getParameters();
24+
if (ntruPrivateKey == null)
25+
{
26+
throw new NullPointerException("'ntruPrivateKey' cannot be null");
27+
}
28+
2629
this.ntruPrivateKey = ntruPrivateKey;
2730
}
2831

29-
30-
@Override
3132
public byte[] extractSecret(byte[] encapsulation)
3233
{
33-
// assert this.ntruPrivateKey != null;
34-
NTRUParameterSet parameterSet = this.params.parameterSet;
34+
NTRUParameterSet parameterSet = ntruPrivateKey.getParameters().getParameterSet();
35+
36+
if (encapsulation == null)
37+
{
38+
throw new NullPointerException("'encapsulation' cannot be null");
39+
}
40+
if (encapsulation.length != parameterSet.ntruCiphertextBytes())
41+
{
42+
throw new IllegalArgumentException("encapsulation");
43+
}
3544

3645
byte[] sk = this.ntruPrivateKey.privateKey;
37-
int i, fail;
38-
byte[] rm;
39-
byte[] buf = new byte[parameterSet.prfKeyBytes() + parameterSet.ntruCiphertextBytes()];
4046

4147
NTRUOWCPA owcpa = new NTRUOWCPA(parameterSet);
42-
OWCPADecryptResult owcpaResult = owcpa.decrypt(encapsulation, ntruPrivateKey.privateKey);
43-
rm = owcpaResult.rm;
44-
fail = owcpaResult.fail;
48+
OWCPADecryptResult owcpaResult = owcpa.decrypt(encapsulation, sk);
49+
byte[] rm = owcpaResult.rm;
50+
int fail = owcpaResult.fail;
4551
/* If fail = 0 then c = Enc(h, rm). There is no need to re-encapsulate. */
4652
/* See comment in owcpa_dec for details. */
4753

4854
SHA3Digest sha3256 = new SHA3Digest(256);
49-
5055
byte[] k = new byte[sha3256.getDigestSize()];
5156

5257
sha3256.update(rm, 0, rm.length);
5358
sha3256.doFinal(k, 0);
5459

5560
/* shake(secret PRF key || input ciphertext) */
56-
for (i = 0; i < parameterSet.prfKeyBytes(); i++)
57-
{
58-
buf[i] = sk[i + parameterSet.owcpaSecretKeyBytes()];
59-
}
60-
for (i = 0; i < parameterSet.ntruCiphertextBytes(); i++)
61-
{
62-
buf[parameterSet.prfKeyBytes() + i] = encapsulation[i];
63-
}
64-
sha3256.reset();
65-
sha3256.update(buf, 0, buf.length);
61+
sha3256.update(sk, parameterSet.owcpaSecretKeyBytes(), parameterSet.prfKeyBytes());
62+
sha3256.update(encapsulation, 0, encapsulation.length);
6663
sha3256.doFinal(rm, 0);
6764

6865
cmov(k, rm, (byte)fail);
6966

7067
byte[] sharedKey = Arrays.copyOfRange(k, 0, parameterSet.sharedKeyBytes());
71-
7268
Arrays.clear(k);
7369

7470
return sharedKey;
@@ -85,6 +81,6 @@ private void cmov(byte[] r, byte[] x, byte b)
8581

8682
public int getEncapsulationLength()
8783
{
88-
return params.parameterSet.ntruCiphertextBytes();
84+
return ntruPrivateKey.getParameters().getParameterSet().ntruCiphertextBytes();
8985
}
9086
}

core/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUKEMGenerator.java

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,42 +29,51 @@ public class NTRUKEMGenerator
2929
*/
3030
public NTRUKEMGenerator(SecureRandom random)
3131
{
32+
if (random == null)
33+
{
34+
throw new NullPointerException("'random' cannot be null");
35+
}
36+
3237
this.random = random;
3338
}
3439

3540
public SecretWithEncapsulation generateEncapsulated(AsymmetricKeyParameter recipientKey)
3641
{
37-
NTRUParameterSet parameterSet = ((NTRUPublicKeyParameters)recipientKey).getParameters().parameterSet;
42+
if (recipientKey == null)
43+
{
44+
throw new NullPointerException("'recipientKey' cannot be null");
45+
}
46+
47+
NTRUPublicKeyParameters publicKey = (NTRUPublicKeyParameters)recipientKey;
48+
49+
NTRUParameterSet parameterSet = publicKey.getParameters().getParameterSet();
3850
NTRUSampling sampling = new NTRUSampling(parameterSet);
3951
NTRUOWCPA owcpa = new NTRUOWCPA(parameterSet);
40-
Polynomial r;
41-
Polynomial m;
4252
byte[] rm = new byte[parameterSet.owcpaMsgBytes()];
4353
byte[] rmSeed = new byte[parameterSet.sampleRmBytes()];
4454

4555
random.nextBytes(rmSeed);
4656

4757
PolynomialPair pair = sampling.sampleRm(rmSeed);
48-
r = pair.r();
49-
m = pair.m();
58+
Polynomial r = pair.r();
59+
Polynomial m = pair.m();
5060

5161
r.s3ToBytes(rm, 0);
5262
m.s3ToBytes(rm, parameterSet.packTrinaryBytes());
5363

5464
SHA3Digest sha3256 = new SHA3Digest(256);
55-
sha3256.update(rm, 0, rm.length);
56-
5765
byte[] k = new byte[sha3256.getDigestSize()];
5866

67+
sha3256.update(rm, 0, rm.length);
5968
sha3256.doFinal(k, 0);
6069

6170
r.z3ToZq();
62-
byte[] c = owcpa.encrypt(r, m, ((NTRUPublicKeyParameters)recipientKey).publicKey);
6371

64-
byte[] sharedKey = Arrays.copyOfRange(k, 0, parameterSet.sharedKeyBytes());
72+
byte[] c = owcpa.encrypt(r, m, publicKey.publicKey);
6573

74+
byte[] sharedKey = Arrays.copyOfRange(k, 0, parameterSet.sharedKeyBytes());
6675
Arrays.clear(k);
67-
76+
6877
return new SecretWithEncapsulationImpl(sharedKey, c);
6978
}
7079
}

core/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUKeyPairGenerator.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
77
import org.bouncycastle.crypto.KeyGenerationParameters;
88
import org.bouncycastle.pqc.math.ntru.parameters.NTRUParameterSet;
9+
import org.bouncycastle.util.Arrays;
910

1011
/**
1112
* Key generator for NTRU.
@@ -19,32 +20,31 @@ public class NTRUKeyPairGenerator
1920
private NTRUKeyGenerationParameters params;
2021
private SecureRandom random;
2122

22-
@Override
2323
public void init(KeyGenerationParameters param)
2424
{
2525
this.params = (NTRUKeyGenerationParameters)param;
2626
this.random = param.getRandom();
2727
}
2828

29-
@Override
3029
public AsymmetricCipherKeyPair generateKeyPair()
3130
{
32-
// assert this.random != null;
33-
NTRUParameterSet parameterSet = this.params.getParameters().parameterSet;
31+
NTRUParameters parameters = params.getParameters();
32+
NTRUParameterSet parameterSet = parameters.getParameterSet();
33+
3434
byte[] seed = new byte[parameterSet.sampleFgBytes()];
3535
random.nextBytes(seed);
3636

3737
NTRUOWCPA owcpa = new NTRUOWCPA(parameterSet);
3838
OWCPAKeyPair owcpaKeys = owcpa.keypair(seed);
39+
3940
byte[] publicKey = owcpaKeys.publicKey;
40-
byte[] privateKey = new byte[parameterSet.ntruSecretKeyBytes()];
41-
byte[] owcpaPrivateKey = owcpaKeys.privateKey;
42-
System.arraycopy(owcpaPrivateKey, 0, privateKey, 0, owcpaPrivateKey.length);
4341

4442
byte[] prfBytes = new byte[parameterSet.prfKeyBytes()];
4543
random.nextBytes(prfBytes);
46-
System.arraycopy(prfBytes, 0, privateKey, parameterSet.owcpaSecretKeyBytes(), prfBytes.length);
44+
byte[] privateKey = Arrays.concatenate(owcpaKeys.privateKey, prfBytes);
4745

48-
return new AsymmetricCipherKeyPair(new NTRUPublicKeyParameters(params.getParameters(), publicKey), new NTRUPrivateKeyParameters(params.getParameters(), privateKey));
46+
return new AsymmetricCipherKeyPair(
47+
new NTRUPublicKeyParameters(parameters, publicKey),
48+
new NTRUPrivateKeyParameters(parameters, privateKey));
4949
}
5050
}

core/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUParameters.java

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package org.bouncycastle.pqc.crypto.ntru;
22

3-
import org.bouncycastle.crypto.CipherParameters;
43
import org.bouncycastle.pqc.crypto.KEMParameters;
54
import org.bouncycastle.pqc.math.ntru.parameters.NTRUHPS2048509;
65
import org.bouncycastle.pqc.math.ntru.parameters.NTRUHPS2048677;
@@ -45,10 +44,7 @@ public class NTRUParameters
4544
public static final NTRUParameters ntruhrss1373 = new NTRUParameters("ntruhrss1373", new NTRUHRSS1373());
4645

4746
private final String name;
48-
/**
49-
* Currently selected parameter set
50-
*/
51-
final NTRUParameterSet parameterSet;
47+
private final NTRUParameterSet parameterSet;
5248

5349
private NTRUParameters(String name, NTRUParameterSet parameterSet)
5450
{
@@ -61,6 +57,21 @@ public String getName()
6157
return name;
6258
}
6359

60+
NTRUParameterSet getParameterSet()
61+
{
62+
return parameterSet;
63+
}
64+
65+
int getPrivateKeyLength()
66+
{
67+
return getParameterSet().ntruSecretKeyBytes();
68+
}
69+
70+
int getPublicKeyLength()
71+
{
72+
return getParameterSet().ntruPublicKeyBytes();
73+
}
74+
6475
public int getSessionKeySize()
6576
{
6677
return parameterSet.sharedKeyBytes() * 8;

core/src/test/java/org/bouncycastle/pqc/crypto/lms/HSSTests.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,7 @@ else if (line.startsWith("Signature:"))
543543

544544
assertEquals(1024, keyPair.getUsagesRemaining());
545545
assertEquals(1024, keyPair.getIndexLimit());
546+
assertEquals(0, keyPair.getIndex());
546547

547548
//
548549
// Split the space up with a shard.
@@ -555,7 +556,6 @@ else if (line.startsWith("Signature:"))
555556
HSSPrivateKeyParameters pair = shard1;
556557

557558
int c = 0;
558-
String exhaustionMessage = null;
559559
for (int i = 0; i < keyPair.getIndexLimit(); i++)
560560
{
561561
if (i == 500)
@@ -640,6 +640,7 @@ public void testRemaining()
640640

641641
HSSPrivateKeyParameters shard = keyPair.extractKeyShard(10);
642642

643+
assertEquals(10, shard.getUsagesRemaining());
643644
assertEquals(15, shard.getIndexLimit());
644645
assertEquals(5, shard.getIndex());
645646

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ public void testKeyGenAndSignTwoSigsWithShard()
112112
LMSSigner signer = new LMSSigner();
113113

114114
assertEquals(2, privKey.getUsagesRemaining());
115+
assertEquals(2, privKey.getIndexLimit());
115116
assertEquals(0, privKey.getIndex());
116117

117118
signer.init(true, privKey);

0 commit comments

Comments
 (0)