Skip to content

Commit 13a7c84

Browse files
committed
Refactoring in NTRU
1 parent 200b399 commit 13a7c84

File tree

5 files changed

+75
-50
lines changed

5 files changed

+75
-50
lines changed

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/test/NTRUTest.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
public class NTRUTest
3232
extends TestCase
3333
{
34-
private final String KAT_ROOT = "/org/bouncycastle/pqc/crypto/test/ntru/";
3534
private final NTRUParameters[] params = {
3635
NTRUParameters.ntruhps2048509,
3736
NTRUParameters.ntruhps2048677,
@@ -59,6 +58,16 @@ public class NTRUTest
5958
"PQCkemKAT_2983.rsp"
6059
};
6160

61+
public void testParameters()
62+
{
63+
assertEquals(256, NTRUParameters.ntruhps2048509.getSessionKeySize());
64+
assertEquals(256, NTRUParameters.ntruhps2048677.getSessionKeySize());
65+
assertEquals(256, NTRUParameters.ntruhps4096821 .getSessionKeySize());
66+
assertEquals(256, NTRUParameters.ntruhps40961229.getSessionKeySize());
67+
assertEquals(256, NTRUParameters.ntruhrss701.getSessionKeySize());
68+
assertEquals(256, NTRUParameters.ntruhrss1373.getSessionKeySize());
69+
}
70+
6271
public void testPrivInfoGeneration()
6372
throws IOException
6473
{

0 commit comments

Comments
 (0)