Skip to content

Commit 1503a6c

Browse files
committed
added support for external-mu
1 parent f726873 commit 1503a6c

File tree

7 files changed

+344
-16
lines changed

7 files changed

+344
-16
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,9 @@ public byte[] generateSignature() throws CryptoException, DataLengthException
119119
{
120120
random.nextBytes(rnd);
121121
}
122+
byte[] mu = engine.generateMu(msgDigest);
122123

123-
return engine.generateSignature(msgDigest, privKey.rho, privKey.k, privKey.t0, privKey.s1, privKey.s2, rnd);
124+
return engine.generateSignature(mu, msgDigest, privKey.rho, privKey.k, privKey.t0, privKey.s1, privKey.s2, rnd);
124125
}
125126

126127
public boolean verifySignature(byte[] signature)

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

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -388,15 +388,20 @@ byte[] signInternal(byte[] msg, int msglen, byte[] rho, byte[] key, byte[] t0Enc
388388

389389
shake256.update(msg, 0, msglen);
390390

391-
return generateSignature(shake256, rho, key, t0Enc, s1Enc, s2Enc, rnd);
391+
return generateSignature(generateMu(shake256), shake256, rho, key, t0Enc, s1Enc, s2Enc, rnd);
392392
}
393393

394-
byte[] generateSignature(SHAKEDigest shake256Digest, byte[] rho, byte[] key, byte[] t0Enc, byte[] s1Enc, byte[] s2Enc, byte[] rnd)
394+
byte[] generateMu(SHAKEDigest shake256Digest)
395395
{
396396
byte[] mu = new byte[CrhBytes];
397397

398398
shake256Digest.doFinal(mu, 0, CrhBytes);
399399

400+
return mu;
401+
}
402+
403+
byte[] generateSignature(byte[] mu, SHAKEDigest shake256Digest, byte[] rho, byte[] key, byte[] t0Enc, byte[] s1Enc, byte[] s2Enc, byte[] rnd)
404+
{
400405
byte[] outSig = new byte[CryptoBytes];
401406
byte[] rhoPrime = new byte[CrhBytes];
402407
short nonce = 0;
@@ -491,7 +496,36 @@ byte[] generateSignature(SHAKEDigest shake256Digest, byte[] rho, byte[] key, byt
491496
return null;
492497
}
493498

499+
boolean verifyInternalMu(byte[] providedMu)
500+
{
501+
byte[] mu = new byte[CrhBytes];
502+
503+
shake256Digest.doFinal(mu, 0);
504+
505+
return Arrays.constantTimeAreEqual(mu, providedMu);
506+
}
507+
508+
boolean verifyInternalMuSignature(byte[] mu, byte[] sig, int siglen, SHAKEDigest shake256Digest, byte[] rho, byte[] encT1)
509+
{
510+
byte[] buf = new byte[Math.max(CrhBytes + DilithiumK * DilithiumPolyW1PackedBytes, DilithiumCTilde)];
511+
512+
// Mu
513+
System.arraycopy(mu, 0, buf, 0, mu.length);
514+
515+
return doVerifyInternal(buf, sig, siglen, shake256Digest, rho, encT1);
516+
}
517+
494518
boolean verifyInternal(byte[] sig, int siglen, SHAKEDigest shake256Digest, byte[] rho, byte[] encT1)
519+
{
520+
byte[] buf = new byte[Math.max(CrhBytes + DilithiumK * DilithiumPolyW1PackedBytes, DilithiumCTilde)];
521+
522+
// Mu
523+
shake256Digest.doFinal(buf, 0);
524+
525+
return doVerifyInternal(buf, sig, siglen, shake256Digest, rho, encT1);
526+
}
527+
528+
private boolean doVerifyInternal(byte[] buf, byte[] sig, int siglen, SHAKEDigest shake256Digest, byte[] rho, byte[] encT1)
495529
{
496530
if (siglen != CryptoBytes)
497531
{
@@ -511,11 +545,6 @@ boolean verifyInternal(byte[] sig, int siglen, SHAKEDigest shake256Digest, byte[
511545
return false;
512546
}
513547

514-
byte[] buf = new byte[Math.max(CrhBytes + DilithiumK * DilithiumPolyW1PackedBytes, DilithiumCTilde)];
515-
516-
// Mu
517-
shake256Digest.doFinal(buf, 0);
518-
519548
Poly cp = new Poly(this);
520549
PolyVecMatrix aMatrix = new PolyVecMatrix(this);
521550
PolyVecK t1 = new PolyVecK(this), w1 = new PolyVecK(this);

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

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,34 @@ public void update(byte[] in, int off, int len)
9393
msgDigest.update(in, off, len);
9494
}
9595

96+
public byte[] generateMu()
97+
throws CryptoException, DataLengthException
98+
{
99+
byte[] mu = engine.generateMu(msgDigest);
100+
101+
reset();
102+
103+
return mu;
104+
}
105+
106+
public byte[] generateMuSignature(byte[] mu)
107+
throws CryptoException, DataLengthException
108+
{
109+
byte[] rnd = new byte[MLDSAEngine.RndBytes];
110+
if (random != null)
111+
{
112+
random.nextBytes(rnd);
113+
}
114+
115+
msgDigest.reset();
116+
117+
byte[] sig = engine.generateSignature(mu, msgDigest, privKey.rho, privKey.k, privKey.t0, privKey.s1, privKey.s2, rnd);
118+
119+
reset();
120+
121+
return sig;
122+
}
123+
96124
public byte[] generateSignature()
97125
throws CryptoException, DataLengthException
98126
{
@@ -102,13 +130,23 @@ public byte[] generateSignature()
102130
random.nextBytes(rnd);
103131
}
104132

105-
byte[] sig = engine.generateSignature(msgDigest, privKey.rho, privKey.k, privKey.t0, privKey.s1, privKey.s2, rnd);
133+
byte[] mu = engine.generateMu(msgDigest);
134+
byte[] sig = engine.generateSignature(mu, msgDigest, privKey.rho, privKey.k, privKey.t0, privKey.s1, privKey.s2, rnd);
106135

107136
reset();
108137

109138
return sig;
110139
}
111140

141+
public boolean verifyMu(byte[] mu)
142+
{
143+
boolean isTrue = engine.verifyInternalMu(mu);
144+
145+
reset();
146+
147+
return isTrue;
148+
}
149+
112150
public boolean verifySignature(byte[] signature)
113151
{
114152
boolean isTrue = engine.verifyInternal(signature, signature.length, msgDigest, pubKey.rho, pubKey.t1);
@@ -118,6 +156,17 @@ public boolean verifySignature(byte[] signature)
118156
return isTrue;
119157
}
120158

159+
public boolean verifyMuSignature(byte[] mu, byte[] signature)
160+
{
161+
msgDigest.reset();
162+
163+
boolean isTrue = engine.verifyInternalMuSignature(mu, signature, signature.length, msgDigest, pubKey.rho, pubKey.t1);
164+
165+
reset();
166+
167+
return isTrue;
168+
}
169+
121170
public void reset()
122171
{
123172
msgDigest = engine.getShake256Digest();
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package org.bouncycastle.jcajce;
2+
3+
import java.security.PublicKey;
4+
5+
import org.bouncycastle.jcajce.interfaces.MLDSAPrivateKey;
6+
import org.bouncycastle.jcajce.interfaces.MLDSAPublicKey;
7+
import org.bouncycastle.jcajce.spec.MLDSAParameterSpec;
8+
9+
/**
10+
* An ML-DSA private key wrapper which acts as a proxy to allow an ML-DSA public key
11+
* to be passed in for external-mu calculation.
12+
*/
13+
public class MLDSAProxyPrivateKey
14+
implements MLDSAPrivateKey
15+
{
16+
private final MLDSAPublicKey publicKey;
17+
18+
public MLDSAProxyPrivateKey(PublicKey publicKey)
19+
{
20+
if (!(publicKey instanceof MLDSAPublicKey))
21+
{
22+
throw new IllegalArgumentException("public key must be an ML-DSA public key");
23+
}
24+
this.publicKey = (MLDSAPublicKey)publicKey;
25+
}
26+
27+
public MLDSAPublicKey getPublicKey()
28+
{
29+
return publicKey;
30+
}
31+
32+
@Override
33+
public String getAlgorithm()
34+
{
35+
return publicKey.getAlgorithm();
36+
}
37+
38+
@Override
39+
public String getFormat()
40+
{
41+
return null;
42+
}
43+
44+
@Override
45+
public byte[] getEncoded()
46+
{
47+
return new byte[0];
48+
}
49+
50+
@Override
51+
public MLDSAParameterSpec getParameterSpec()
52+
{
53+
return publicKey.getParameterSpec();
54+
}
55+
56+
@Override
57+
public byte[] getPrivateData()
58+
{
59+
return new byte[0];
60+
}
61+
62+
@Override
63+
public byte[] getSeed()
64+
{
65+
return new byte[0];
66+
}
67+
68+
@Override
69+
public MLDSAPrivateKey getPrivateKey(boolean preferSeedOnly)
70+
{
71+
return null;
72+
}
73+
}

prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/MLDSA.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@ public void configure(ConfigurableProvider provider)
4949
addSignatureAlgorithm(provider, "ML-DSA-87", PREFIX + "SignatureSpi$MLDSA87", NISTObjectIdentifiers.id_ml_dsa_87);
5050
provider.addAlgorithm("Alg.Alias.Signature.MLDSA", "ML-DSA");
5151

52+
addSignatureAlgorithm(provider, "ML-DSA-CALCULATE-MU", PREFIX + "SignatureSpi$MLDSACalcMu", (ASN1ObjectIdentifier)null);
53+
provider.addAlgorithm("Alg.Alias.Signature.MLDSA-CALCULATE-MU", "ML-DSA-CALCULATE-MU");
54+
55+
addSignatureAlgorithm(provider, "ML-DSA-EXTERNAL-MU", PREFIX + "SignatureSpi$MLDSAExtMu", (ASN1ObjectIdentifier)null);
56+
provider.addAlgorithm("Alg.Alias.Signature.MLDSA-EXTERNAL-MU", "ML-DSA-EXTERNAL-MU");
57+
5258
addSignatureAlgorithm(provider, "HASH-ML-DSA", PREFIX + "HashSignatureSpi$MLDSA", (ASN1ObjectIdentifier)null);
5359
addSignatureAlgorithm(provider, "ML-DSA-44-WITH-SHA512", PREFIX + "HashSignatureSpi$MLDSA44", NISTObjectIdentifiers.id_hash_ml_dsa_44_with_sha512);
5460
addSignatureAlgorithm(provider, "ML-DSA-65-WITH-SHA512", PREFIX + "HashSignatureSpi$MLDSA65", NISTObjectIdentifiers.id_hash_ml_dsa_65_with_sha512);

0 commit comments

Comments
 (0)