Skip to content

Commit 62c55b0

Browse files
committed
Merge branch 'pqc-dilithium-rejection-testvectors' into 'main'
Pqc MLDSA rejection testvectors See merge request root/bc-java!101
2 parents 0b9e141 + e52d75e commit 62c55b0

File tree

5 files changed

+516
-255
lines changed

5 files changed

+516
-255
lines changed

core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/HashMLDSASigner.java

Lines changed: 26 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,11 @@
44
import java.security.SecureRandom;
55

66
import org.bouncycastle.asn1.ASN1Encoding;
7-
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
87
import org.bouncycastle.crypto.CipherParameters;
98
import org.bouncycastle.crypto.CryptoException;
109
import org.bouncycastle.crypto.DataLengthException;
1110
import org.bouncycastle.crypto.Digest;
1211
import org.bouncycastle.crypto.Signer;
13-
import org.bouncycastle.crypto.digests.SHA512Digest;
14-
import org.bouncycastle.crypto.digests.SHAKEDigest;
1512
import org.bouncycastle.crypto.params.ParametersWithContext;
1613
import org.bouncycastle.crypto.params.ParametersWithRandom;
1714
import org.bouncycastle.pqc.crypto.DigestUtils;
@@ -27,7 +24,6 @@ public class HashMLDSASigner
2724

2825
private MLDSAEngine engine;
2926
private Digest digest;
30-
private byte[] digestOIDEncoding;
3127

3228
public HashMLDSASigner()
3329
{
@@ -67,37 +63,28 @@ public void init(boolean forSigning, CipherParameters param)
6763

6864
parameters = privKey.getParameters();
6965
engine = parameters.getEngine(random);
70-
7166
engine.initSign(privKey.tr, true, ctx);
7267
}
7368
else
7469
{
7570
pubKey = (MLDSAPublicKeyParameters)param;
7671
privKey = null;
7772
random = null;
78-
7973
parameters = pubKey.getParameters();
8074
engine = parameters.getEngine(null);
81-
8275
engine.initVerify(pubKey.rho, pubKey.t1, true, ctx);
8376
}
84-
85-
initDigest(parameters);
86-
}
87-
88-
private void initDigest(MLDSAParameters parameters)
89-
{
90-
digest = createDigest(parameters);
91-
92-
ASN1ObjectIdentifier oid = DigestUtils.getDigestOid(digest.getAlgorithmName());
77+
digest = engine.shake256Digest;
78+
byte[] digestOIDEncoding;
9379
try
9480
{
95-
digestOIDEncoding = oid.getEncoded(ASN1Encoding.DER);
81+
digestOIDEncoding = DigestUtils.getDigestOid(digest.getAlgorithmName()).getEncoded(ASN1Encoding.DER);
9682
}
9783
catch (IOException e)
9884
{
9985
throw new IllegalStateException("oid encoding failed: " + e.getMessage());
10086
}
87+
digest.update(digestOIDEncoding, 0, digestOIDEncoding.length);
10188
}
10289

10390
public void update(byte b)
@@ -110,25 +97,22 @@ public void update(byte[] in, int off, int len)
11097
digest.update(in, off, len);
11198
}
11299

113-
public byte[] generateSignature() throws CryptoException, DataLengthException
100+
public byte[] generateSignature()
101+
throws CryptoException, DataLengthException
114102
{
115-
SHAKEDigest msgDigest = finishPreHash();
116-
117103
byte[] rnd = new byte[MLDSAEngine.RndBytes];
118104
if (random != null)
119105
{
120106
random.nextBytes(rnd);
121107
}
122-
byte[] mu = engine.generateMu(msgDigest);
123-
124-
return engine.generateSignature(mu, msgDigest, privKey.rho, privKey.k, privKey.t0, privKey.s1, privKey.s2, rnd);
108+
byte[] mu = engine.generateMu(engine.shake256Digest);
109+
return engine.generateSignature(mu, engine.getShake256Digest(), privKey.rho, privKey.k, privKey.t0, privKey.s1, privKey.s2, rnd);
125110
}
126111

127112
public boolean verifySignature(byte[] signature)
128113
{
129-
SHAKEDigest msgDigest = finishPreHash();
130-
131-
return engine.verifyInternal(signature, signature.length, msgDigest, pubKey.rho, pubKey.t1);
114+
byte[] mu = engine.generateMu(engine.shake256Digest);
115+
return engine.verifyInternalMuSignature(mu, signature, signature.length, engine.getShake256Digest(), pubKey.rho, pubKey.t1);
132116
}
133117

134118
/**
@@ -139,20 +123,8 @@ public void reset()
139123
digest.reset();
140124
}
141125

142-
private SHAKEDigest finishPreHash()
143-
{
144-
byte[] hash = new byte[digest.getDigestSize()];
145-
digest.doFinal(hash, 0);
146-
147-
SHAKEDigest msgDigest = engine.getShake256Digest();
148-
// TODO It should be possible to include digestOIDEncoding in the memo'ed digest
149-
msgDigest.update(digestOIDEncoding, 0, digestOIDEncoding.length);
150-
msgDigest.update(hash, 0, hash.length);
151-
return msgDigest;
152-
}
153-
154126
// TODO: these are probably no longer correct and also need to be marked as protected
155-
// protected byte[] internalGenerateSignature(byte[] message, byte[] random)
127+
// protected byte[] internalGenerateSignature(byte[] message, SecureRandom random)
156128
// {
157129
// MLDSAEngine engine = privKey.getParameters().getEngine(random);
158130
//
@@ -166,15 +138,19 @@ private SHAKEDigest finishPreHash()
166138
// return engine.verifyInternal(signature, signature.length, message, message.length, pubKey.rho, pubKey.t1);
167139
// }
168140

169-
private static Digest createDigest(MLDSAParameters parameters)
170-
{
171-
switch (parameters.getType())
172-
{
173-
case MLDSAParameters.TYPE_PURE:
174-
case MLDSAParameters.TYPE_SHA2_512:
175-
return new SHA512Digest();
176-
default:
177-
throw new IllegalArgumentException("unknown parameters type");
178-
}
179-
}
141+
// private static Digest createDigest(MLDSAParameters parameters)
142+
// {
143+
//TODO: MLDSA44 may use SHA2-256, SHA3-256, SHAKE128
144+
// MLDSA65 may use SHA3-384, SHA2-512
145+
// MLDSA44/65/87 may use SHA2-512, SHA3-512, SHAKE256
146+
147+
// switch (parameters.getType())
148+
// {
149+
// case MLDSAParameters.TYPE_PURE:
150+
// case MLDSAParameters.TYPE_SHA2_512:
151+
// return new SHAKEDigest(256);
152+
// default:
153+
// throw new IllegalArgumentException("unknown parameters type");
154+
// }
155+
// }
180156
}

core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/MLDSAEngine.java

Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,20 @@
22

33
import java.security.SecureRandom;
44

5+
import org.bouncycastle.crypto.Digest;
56
import org.bouncycastle.crypto.digests.SHAKEDigest;
67
import org.bouncycastle.util.Arrays;
78

89
class MLDSAEngine
910
{
1011
private final SecureRandom random;
11-
12-
private final SHAKEDigest shake256Digest = new SHAKEDigest(256);
12+
final SHAKEDigest shake256Digest = new SHAKEDigest(256);
1313

1414
public final static int DilithiumN = 256;
1515
public final static int DilithiumQ = 8380417;
1616
public final static int DilithiumQinv = 58728449; // q^(-1) mod 2^32
1717
public final static int DilithiumD = 13;
18-
public final static int DilithiumRootOfUnity = 1753;
18+
//public final static int DilithiumRootOfUnity = 1753;
1919
public final static int SeedBytes = 32;
2020
public final static int CrhBytes = 64;
2121
public final static int RndBytes = 32;
@@ -55,10 +55,10 @@ protected Symmetric GetSymmetric()
5555
return symmetric;
5656
}
5757

58-
int getDilithiumPolyVecHPackedBytes()
59-
{
60-
return DilithiumPolyVecHPackedBytes;
61-
}
58+
// int getDilithiumPolyVecHPackedBytes()
59+
// {
60+
// return DilithiumPolyVecHPackedBytes;
61+
// }
6262

6363
int getDilithiumPolyZPackedBytes()
6464
{
@@ -75,10 +75,10 @@ int getDilithiumPolyEtaPackedBytes()
7575
return DilithiumPolyEtaPackedBytes;
7676
}
7777

78-
int getDilithiumMode()
79-
{
80-
return DilithiumMode;
81-
}
78+
// int getDilithiumMode()
79+
// {
80+
// return DilithiumMode;
81+
// }
8282

8383
int getDilithiumK()
8484
{
@@ -130,15 +130,15 @@ int getCryptoPublicKeyBytes()
130130
return CryptoPublicKeyBytes;
131131
}
132132

133-
int getCryptoSecretKeyBytes()
134-
{
135-
return CryptoSecretKeyBytes;
136-
}
137-
138-
int getCryptoBytes()
139-
{
140-
return CryptoBytes;
141-
}
133+
// int getCryptoSecretKeyBytes()
134+
// {
135+
// return CryptoSecretKeyBytes;
136+
// }
137+
//
138+
// int getCryptoBytes()
139+
// {
140+
// return CryptoBytes;
141+
// }
142142

143143
int getPolyUniformGamma1NBlocks()
144144
{
@@ -357,12 +357,7 @@ SHAKEDigest getShake256Digest()
357357
void initSign(byte[] tr, boolean isPreHash, byte[] ctx)
358358
{
359359
shake256Digest.update(tr, 0, TrBytes);
360-
if (ctx != null)
361-
{
362-
shake256Digest.update(isPreHash ? (byte)1 : (byte)0);
363-
shake256Digest.update((byte)ctx.length);
364-
shake256Digest.update(ctx, 0, ctx.length);
365-
}
360+
absorbCtx(isPreHash, ctx);
366361
}
367362

368363
void initVerify(byte[] rho, byte[] encT1, boolean isPreHash, byte[] ctx)
@@ -374,6 +369,11 @@ void initVerify(byte[] rho, byte[] encT1, boolean isPreHash, byte[] ctx)
374369
shake256Digest.doFinal(mu, 0, TrBytes);
375370

376371
shake256Digest.update(mu, 0, TrBytes);
372+
absorbCtx(isPreHash, ctx);
373+
}
374+
375+
void absorbCtx(boolean isPreHash, byte[] ctx)
376+
{
377377
if (ctx != null)
378378
{
379379
shake256Digest.update(isPreHash ? (byte)1 : (byte)0);
@@ -396,7 +396,6 @@ byte[] generateMu(SHAKEDigest shake256Digest)
396396
byte[] mu = new byte[CrhBytes];
397397

398398
shake256Digest.doFinal(mu, 0, CrhBytes);
399-
400399
return mu;
401400
}
402401

core/src/main/java/org/bouncycastle/pqc/crypto/mldsa/MLDSASigner.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,9 @@ public class MLDSASigner
1414
implements Signer
1515
{
1616
private static final byte[] EMPTY_CONTEXT = new byte[0];
17-
1817
private MLDSAPublicKeyParameters pubKey;
1918
private MLDSAPrivateKeyParameters privKey;
2019
private SecureRandom random;
21-
2220
private MLDSAEngine engine;
2321
private SHAKEDigest msgDigest;
2422

@@ -148,7 +146,7 @@ public boolean verifyMu(byte[] mu)
148146
{
149147
throw new DataLengthException("mu value must be " + MLDSAEngine.CrhBytes + " bytes");
150148
}
151-
149+
152150
boolean isTrue = engine.verifyInternalMu(mu);
153151

154152
reset();
@@ -171,9 +169,9 @@ public boolean verifyMuSignature(byte[] mu, byte[] signature)
171169
{
172170
throw new DataLengthException("mu value must be " + MLDSAEngine.CrhBytes + " bytes");
173171
}
174-
172+
175173
msgDigest.reset();
176-
174+
177175
boolean isTrue = engine.verifyInternalMuSignature(mu, signature, signature.length, msgDigest, pubKey.rho, pubKey.t1);
178176

179177
reset();

0 commit comments

Comments
 (0)