Skip to content

Commit 0503ef0

Browse files
committed
promoted pqc/crypto/mldsa to the universal crypto package. Deprecated pqc/crypto/mldsa.
1 parent 74077f8 commit 0503ef0

32 files changed

Lines changed: 3936 additions & 12 deletions
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package org.bouncycastle.crypto.generators;
2+
3+
import java.security.SecureRandom;
4+
5+
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
6+
import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
7+
import org.bouncycastle.crypto.KeyGenerationParameters;
8+
import org.bouncycastle.crypto.params.MLDSAKeyGenerationParameters;
9+
import org.bouncycastle.crypto.params.MLDSAParameters;
10+
import org.bouncycastle.crypto.params.MLDSAPrivateKeyParameters;
11+
import org.bouncycastle.crypto.params.MLDSAPublicKeyParameters;
12+
import org.bouncycastle.crypto.signers.mldsa.MLDSAEngine;
13+
14+
public class MLDSAKeyPairGenerator
15+
implements AsymmetricCipherKeyPairGenerator
16+
{
17+
private MLDSAParameters parameters;
18+
private SecureRandom random;
19+
20+
public void init(KeyGenerationParameters param)
21+
{
22+
this.parameters = ((MLDSAKeyGenerationParameters)param).getParameters();
23+
this.random = param.getRandom();
24+
}
25+
26+
public AsymmetricCipherKeyPair generateKeyPair()
27+
{
28+
MLDSAEngine engine = new MLDSAEngine(parameters.getK(), random);
29+
30+
byte[][] keyPair = engine.generateKeyPair();
31+
MLDSAPublicKeyParameters pubKey = new MLDSAPublicKeyParameters(parameters, keyPair[0], keyPair[6]);
32+
MLDSAPrivateKeyParameters privKey = new MLDSAPrivateKeyParameters(parameters, keyPair[0], keyPair[1], keyPair[2], keyPair[3], keyPair[4], keyPair[5], keyPair[6], keyPair[7]);
33+
34+
return new AsymmetricCipherKeyPair(pubKey, privKey);
35+
}
36+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package org.bouncycastle.crypto.params;
2+
3+
import java.security.SecureRandom;
4+
5+
import org.bouncycastle.crypto.KeyGenerationParameters;
6+
7+
public class MLDSAKeyGenerationParameters
8+
extends KeyGenerationParameters
9+
{
10+
private final MLDSAParameters params;
11+
12+
public MLDSAKeyGenerationParameters(
13+
SecureRandom random,
14+
MLDSAParameters mldsaParameters)
15+
{
16+
super(random, 256);
17+
this.params = mldsaParameters;
18+
}
19+
20+
public MLDSAParameters getParameters()
21+
{
22+
return params;
23+
}
24+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.bouncycastle.crypto.params;
2+
3+
public class MLDSAKeyParameters
4+
extends AsymmetricKeyParameter
5+
{
6+
private final MLDSAParameters params;
7+
8+
public MLDSAKeyParameters(
9+
boolean isPrivate,
10+
MLDSAParameters params)
11+
{
12+
super(isPrivate);
13+
this.params = params;
14+
}
15+
16+
public MLDSAParameters getParameters()
17+
{
18+
return params;
19+
}
20+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package org.bouncycastle.crypto.params;
2+
3+
public class MLDSAParameters
4+
{
5+
public static final int TYPE_PURE = 0;
6+
public static final int TYPE_SHA2_512 = 1;
7+
8+
public static final MLDSAParameters ml_dsa_44 = new MLDSAParameters("ml-dsa-44", 2, TYPE_PURE);
9+
public static final MLDSAParameters ml_dsa_65 = new MLDSAParameters("ml-dsa-65", 3, TYPE_PURE);
10+
public static final MLDSAParameters ml_dsa_87 = new MLDSAParameters("ml-dsa-87", 5, TYPE_PURE);
11+
12+
public static final MLDSAParameters ml_dsa_44_with_sha512 = new MLDSAParameters("ml-dsa-44-with-sha512", 2, TYPE_SHA2_512);
13+
public static final MLDSAParameters ml_dsa_65_with_sha512 = new MLDSAParameters("ml-dsa-65-with-sha512", 3, TYPE_SHA2_512);
14+
public static final MLDSAParameters ml_dsa_87_with_sha512 = new MLDSAParameters("ml-dsa-87-with-sha512", 5, TYPE_SHA2_512);
15+
16+
private final int k;
17+
private final String name;
18+
private final int preHashDigest;
19+
20+
private MLDSAParameters(String name, int k, int preHashDigest)
21+
{
22+
this.name = name;
23+
this.k = k;
24+
this.preHashDigest = preHashDigest;
25+
}
26+
27+
public boolean isPreHash()
28+
{
29+
return preHashDigest != TYPE_PURE;
30+
}
31+
32+
public int getType()
33+
{
34+
return preHashDigest;
35+
}
36+
37+
public int getK()
38+
{
39+
return k;
40+
}
41+
42+
public String getName()
43+
{
44+
return name;
45+
}
46+
}
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
package org.bouncycastle.crypto.params;
2+
3+
import org.bouncycastle.crypto.signers.mldsa.MLDSAEngine;
4+
import org.bouncycastle.util.Arrays;
5+
6+
public class MLDSAPrivateKeyParameters
7+
extends MLDSAKeyParameters
8+
{
9+
public static final int BOTH = 0;
10+
public static final int SEED_ONLY = 1;
11+
public static final int EXPANDED_KEY = 2;
12+
13+
final byte[] rho;
14+
final byte[] k;
15+
final byte[] tr;
16+
final byte[] s1;
17+
final byte[] s2;
18+
final byte[] t0;
19+
20+
private final byte[] t1;
21+
private final byte[] seed;
22+
23+
private final int prefFormat;
24+
25+
public MLDSAPrivateKeyParameters(MLDSAParameters params, byte[] encoding)
26+
{
27+
this(params, encoding, null);
28+
}
29+
30+
public MLDSAPrivateKeyParameters(MLDSAParameters params, byte[] rho, byte[] K, byte[] tr, byte[] s1, byte[] s2, byte[] t0, byte[] t1)
31+
{
32+
this(params, rho, K, tr, s1, s2, t0, t1, null);
33+
}
34+
35+
public MLDSAPrivateKeyParameters(MLDSAParameters params, byte[] rho, byte[] K, byte[] tr, byte[] s1, byte[] s2, byte[] t0, byte[] t1, byte[] seed)
36+
{
37+
super(true, params);
38+
this.rho = Arrays.clone(rho);
39+
this.k = Arrays.clone(K);
40+
this.tr = Arrays.clone(tr);
41+
this.s1 = Arrays.clone(s1);
42+
this.s2 = Arrays.clone(s2);
43+
this.t0 = Arrays.clone(t0);
44+
this.t1 = Arrays.clone(t1);
45+
this.seed = Arrays.clone(seed);
46+
this.prefFormat = (seed != null) ? BOTH : EXPANDED_KEY;
47+
}
48+
49+
public MLDSAPrivateKeyParameters(MLDSAParameters params, byte[] encoding, MLDSAPublicKeyParameters pubKey)
50+
{
51+
super(true, params);
52+
53+
MLDSAEngine eng = new MLDSAEngine(params.getK(), null);
54+
if (encoding.length == MLDSAEngine.SeedBytes)
55+
{
56+
byte[][] keyDetails = eng.generateKeyPairInternal(encoding);
57+
58+
this.rho = keyDetails[0];
59+
this.k = keyDetails[1];
60+
this.tr = keyDetails[2];
61+
this.s1 = keyDetails[3];
62+
this.s2 = keyDetails[4];
63+
this.t0 = keyDetails[5];
64+
this.t1 = keyDetails[6];
65+
this.seed = keyDetails[7];
66+
}
67+
else
68+
{
69+
int index = 0;
70+
this.rho = Arrays.copyOfRange(encoding, 0, MLDSAEngine.SeedBytes);
71+
index += MLDSAEngine.SeedBytes;
72+
this.k = Arrays.copyOfRange(encoding, index, index + MLDSAEngine.SeedBytes);
73+
index += MLDSAEngine.SeedBytes;
74+
this.tr = Arrays.copyOfRange(encoding, index, index + MLDSAEngine.TrBytes);
75+
index += MLDSAEngine.TrBytes;
76+
int delta = eng.getDilithiumL() * eng.getDilithiumPolyEtaPackedBytes();
77+
this.s1 = Arrays.copyOfRange(encoding, index, index + delta);
78+
index += delta;
79+
delta = eng.getDilithiumK() * eng.getDilithiumPolyEtaPackedBytes();
80+
this.s2 = Arrays.copyOfRange(encoding, index, index + delta);
81+
index += delta;
82+
delta = eng.getDilithiumK() * MLDSAEngine.DilithiumPolyT0PackedBytes;
83+
this.t0 = Arrays.copyOfRange(encoding, index, index + delta);
84+
index += delta;
85+
this.t1 = eng.deriveT1(rho, k, tr, s1, s2, t0);
86+
this.seed = null;
87+
}
88+
89+
if (pubKey != null)
90+
{
91+
if (!Arrays.constantTimeAreEqual(this.t1, pubKey.getT1()))
92+
{
93+
throw new IllegalArgumentException("passed in public key does not match private values");
94+
}
95+
}
96+
97+
this.prefFormat = (seed != null) ? BOTH : EXPANDED_KEY;
98+
}
99+
100+
private MLDSAPrivateKeyParameters(MLDSAPrivateKeyParameters params, int preferredFormat)
101+
{
102+
super(true, params.getParameters());
103+
104+
this.rho = params.rho;
105+
this.k = params.k;
106+
this.tr = params.tr;
107+
this.s1 = params.s1;
108+
this.s2 = params.s2;
109+
this.t0 = params.t0;
110+
this.t1 = params.t1;
111+
this.seed = params.seed;
112+
this.prefFormat = preferredFormat;
113+
}
114+
115+
public MLDSAPrivateKeyParameters getParametersWithFormat(int format)
116+
{
117+
if (this.prefFormat == format)
118+
{
119+
return this;
120+
}
121+
122+
switch (format)
123+
{
124+
case BOTH:
125+
case SEED_ONLY:
126+
{
127+
if (this.seed == null)
128+
{
129+
throw new IllegalStateException("no seed available");
130+
}
131+
break;
132+
}
133+
case EXPANDED_KEY:
134+
break;
135+
default:
136+
throw new IllegalArgumentException("unknown format");
137+
}
138+
139+
return new MLDSAPrivateKeyParameters(this, format);
140+
}
141+
142+
public int getPreferredFormat()
143+
{
144+
return prefFormat;
145+
}
146+
147+
public byte[] getEncoded()
148+
{
149+
return Arrays.concatenate(new byte[][]{rho, k, tr, s1, s2, t0});
150+
}
151+
152+
public byte[] getK()
153+
{
154+
return Arrays.clone(k);
155+
}
156+
157+
/**
158+
* @deprecated Use {@link #getEncoded()} instead.
159+
*/
160+
@Deprecated
161+
@SuppressWarnings("InlineMeSuggester")
162+
public byte[] getPrivateKey()
163+
{
164+
return getEncoded();
165+
}
166+
167+
public byte[] getPublicKey()
168+
{
169+
return MLDSAPublicKeyParameters.getEncoded(rho, t1);
170+
}
171+
172+
public byte[] getSeed()
173+
{
174+
return Arrays.clone(seed);
175+
}
176+
177+
public MLDSAPublicKeyParameters getPublicKeyParameters()
178+
{
179+
if (this.t1 == null)
180+
{
181+
return null;
182+
}
183+
184+
return new MLDSAPublicKeyParameters(getParameters(), rho, t1);
185+
}
186+
187+
public byte[] getRho()
188+
{
189+
return Arrays.clone(rho);
190+
}
191+
192+
public byte[] getS1()
193+
{
194+
return Arrays.clone(s1);
195+
}
196+
197+
public byte[] getS2()
198+
{
199+
return Arrays.clone(s2);
200+
}
201+
202+
public byte[] getT0()
203+
{
204+
return Arrays.clone(t0);
205+
}
206+
207+
public byte[] getT1()
208+
{
209+
return Arrays.clone(t1);
210+
}
211+
212+
public byte[] getTr()
213+
{
214+
return Arrays.clone(tr);
215+
}
216+
}

0 commit comments

Comments
 (0)