7
7
using Org . BouncyCastle . Crypto . Parameters ;
8
8
using Org . BouncyCastle . Crypto . Signers ;
9
9
using Org . BouncyCastle . Pkcs ;
10
+ using Org . BouncyCastle . Pqc . Crypto . Tests ;
10
11
using Org . BouncyCastle . Security ;
11
12
using Org . BouncyCastle . Utilities ;
12
13
using Org . BouncyCastle . Utilities . Encoders ;
@@ -39,6 +40,44 @@ public class SlhDsaTest
39
40
{ "sigVer_SLH-DSA-SHAKE-256f.txt" , SlhDsaParameters . slh_dsa_shake_256f } ,
40
41
} ;
41
42
43
+ private static readonly Dictionary < string , SlhDsaParameters > ContextFastFileParameters =
44
+ new Dictionary < string , SlhDsaParameters > ( )
45
+ {
46
+ { "sha2-128f.rsp" , SlhDsaParameters . slh_dsa_sha2_128f } ,
47
+ { "sha2-128f-sha256.rsp" , SlhDsaParameters . slh_dsa_sha2_128f_with_sha256 } ,
48
+ { "sha2-192f.rsp" , SlhDsaParameters . slh_dsa_sha2_192f } ,
49
+ { "sha2-192f-sha512.rsp" , SlhDsaParameters . slh_dsa_sha2_192f_with_sha512 } ,
50
+ { "sha2-256f.rsp" , SlhDsaParameters . slh_dsa_sha2_256f } ,
51
+ { "sha2-256f-sha512.rsp" , SlhDsaParameters . slh_dsa_sha2_256f_with_sha512 } ,
52
+ { "shake-128f.rsp" , SlhDsaParameters . slh_dsa_shake_128f } ,
53
+ { "shake-128f-shake128.rsp" , SlhDsaParameters . slh_dsa_shake_128f_with_shake128 } ,
54
+ { "shake-192f.rsp" , SlhDsaParameters . slh_dsa_shake_192f } ,
55
+ { "shake-192f-shake256.rsp" , SlhDsaParameters . slh_dsa_shake_192f_with_shake256 } ,
56
+ { "shake-256f.rsp" , SlhDsaParameters . slh_dsa_shake_256f } ,
57
+ { "shake-256f-shake256.rsp" , SlhDsaParameters . slh_dsa_shake_256f_with_shake256 } ,
58
+ } ;
59
+
60
+ private static readonly IEnumerable < string > ContextFastFiles = ContextFastFileParameters . Keys ;
61
+
62
+ private static readonly Dictionary < string , SlhDsaParameters > ContextSlowFileParameters =
63
+ new Dictionary < string , SlhDsaParameters > ( )
64
+ {
65
+ { "sha2-128s.rsp" , SlhDsaParameters . slh_dsa_sha2_128s } ,
66
+ { "sha2-128s-sha256.rsp" , SlhDsaParameters . slh_dsa_sha2_128s_with_sha256 } ,
67
+ { "sha2-192s.rsp" , SlhDsaParameters . slh_dsa_sha2_192s } ,
68
+ { "sha2-192s-sha512.rsp" , SlhDsaParameters . slh_dsa_sha2_192s_with_sha512 } ,
69
+ { "sha2-256s.rsp" , SlhDsaParameters . slh_dsa_sha2_256s } ,
70
+ { "sha2-256s-sha512.rsp" , SlhDsaParameters . slh_dsa_sha2_256s_with_sha512 } ,
71
+ { "shake-128s.rsp" , SlhDsaParameters . slh_dsa_shake_128s } ,
72
+ { "shake-128s-shake128.rsp" , SlhDsaParameters . slh_dsa_shake_128s_with_shake128 } ,
73
+ { "shake-192s.rsp" , SlhDsaParameters . slh_dsa_shake_192s } ,
74
+ { "shake-192s-shake256.rsp" , SlhDsaParameters . slh_dsa_shake_192s_with_shake256 } ,
75
+ { "shake-256s.rsp" , SlhDsaParameters . slh_dsa_shake_256s } ,
76
+ { "shake-256s-shake256.rsp" , SlhDsaParameters . slh_dsa_shake_256s_with_shake256 } ,
77
+ } ;
78
+
79
+ private static readonly IEnumerable < string > ContextSlowFiles = ContextSlowFileParameters . Keys ;
80
+
42
81
private static readonly Dictionary < string , SlhDsaParameters > Parameters =
43
82
new Dictionary < string , SlhDsaParameters > ( )
44
83
{
@@ -118,6 +157,22 @@ public void Consistency(SlhDsaParameters parameters)
118
157
}
119
158
}
120
159
160
+ [ TestCaseSource ( nameof ( ContextFastFiles ) ) ]
161
+ [ Parallelizable ]
162
+ public void ContextFast ( string fileName )
163
+ {
164
+ RunTestVectors ( "pqc/crypto/slhdsa" , fileName , sampleOnly : true ,
165
+ ( name , data ) => ImplContext ( name , data , ContextFastFileParameters [ name ] ) ) ;
166
+ }
167
+
168
+ [ TestCaseSource ( nameof ( ContextSlowFiles ) ) , Explicit ]
169
+ [ Parallelizable ]
170
+ public void ContextSlow ( string fileName )
171
+ {
172
+ RunTestVectors ( "pqc/crypto/slhdsa" , fileName , sampleOnly : true ,
173
+ ( name , data ) => ImplContext ( name , data , ContextSlowFileParameters [ name ] ) ) ;
174
+ }
175
+
121
176
[ Test ]
122
177
[ Parallelizable ]
123
178
public void KeyGen ( )
@@ -166,6 +221,80 @@ public void KeyGenAcvp(string fileName)
166
221
// (name, data) => ImplSigVer(name, data, AcvpFileParameters[name]));
167
222
//}
168
223
224
+ private static void ImplContext ( string name , Dictionary < string , string > data , SlhDsaParameters parameters )
225
+ {
226
+ string count = data [ "count" ] ;
227
+ byte [ ] seed = Hex . Decode ( data [ "seed" ] ) ;
228
+ byte [ ] msg = Hex . Decode ( data [ "msg" ] ) ;
229
+ byte [ ] pk = Hex . Decode ( data [ "pk" ] ) ;
230
+ byte [ ] sk = Hex . Decode ( data [ "sk" ] ) ;
231
+ byte [ ] sm = Hex . Decode ( data [ "sm" ] ) ;
232
+ byte [ ] optrand = Hex . Decode ( data [ "optrand" ] ) ;
233
+
234
+ byte [ ] context = null ;
235
+ if ( data . TryGetValue ( "context" , out var contextValue ) )
236
+ {
237
+ context = Hex . Decode ( contextValue ) ;
238
+ }
239
+
240
+ var random = FixedSecureRandom . From ( seed ) ;
241
+
242
+ var kpg = new SlhDsaKeyPairGenerator ( ) ;
243
+ kpg . Init ( new SlhDsaKeyGenerationParameters ( random , parameters ) ) ;
244
+
245
+ var kp = kpg . GenerateKeyPair ( ) ;
246
+
247
+ var publicKey = ( SlhDsaPublicKeyParameters ) kp . Public ;
248
+ var privateKey = ( SlhDsaPrivateKeyParameters ) kp . Private ;
249
+
250
+ Assert . True ( Arrays . AreEqual ( pk , publicKey . GetEncoded ( ) ) , $ "{ name } { count } : public key") ;
251
+ Assert . True ( Arrays . AreEqual ( sk , privateKey . GetEncoded ( ) ) , $ "{ name } { count } : secret key") ;
252
+
253
+ var publicKeyRT = ( SlhDsaPublicKeyParameters ) PublicKeyFactory . CreateKey (
254
+ SubjectPublicKeyInfoFactory . CreateSubjectPublicKeyInfo ( publicKey ) ) ;
255
+ var privateKeyRT = ( SlhDsaPrivateKeyParameters ) PrivateKeyFactory . CreateKey (
256
+ PrivateKeyInfoFactory . CreatePrivateKeyInfo ( privateKey ) ) ;
257
+
258
+ Assert . True ( Arrays . AreEqual ( pk , publicKeyRT . GetEncoded ( ) ) , $ "{ name } { count } : public key (round-trip)") ;
259
+ Assert . True ( Arrays . AreEqual ( sk , privateKeyRT . GetEncoded ( ) ) , $ "{ name } { count } : secret key (round-trip)") ;
260
+
261
+ // Note that this is not a deterministic signature test, since we are given "optrand"
262
+ ISigner sig ;
263
+ if ( parameters . IsPreHash )
264
+ {
265
+ sig = new HashSlhDsaSigner ( parameters , deterministic : false ) ;
266
+ }
267
+ else
268
+ {
269
+ sig = new SlhDsaSigner ( parameters , deterministic : false ) ;
270
+ }
271
+
272
+ // The current test data is a bit weird and uses internal signing when no explicit context provided.
273
+ if ( context == null )
274
+ {
275
+ //byte[] generated = privateKey.SignInternal(optrand, msg, 0, msg.Length);
276
+ //Assert.True(Arrays.AreEqual(sm, generated), $"{name} {count}: SignInternal");
277
+
278
+ //bool shouldVerify = publicKey.VerifyInternal(msg, 0, msg.Length, sm);
279
+ //Assert.True(shouldVerify, $"{name} {count}: VerifyInternal");
280
+ }
281
+ else
282
+ {
283
+ sig . Init ( forSigning : true ,
284
+ ParameterUtilities . WithContext (
285
+ ParameterUtilities . WithRandom ( privateKey , FixedSecureRandom . From ( optrand ) ) ,
286
+ context ) ) ;
287
+ sig . BlockUpdate ( msg , 0 , msg . Length ) ;
288
+ byte [ ] generated = sig . GenerateSignature ( ) ;
289
+ Assert . True ( Arrays . AreEqual ( sm , generated ) , $ "{ name } { count } : GenerateSignature") ;
290
+
291
+ sig . Init ( forSigning : false , ParameterUtilities . WithContext ( publicKey , context ) ) ;
292
+ sig . BlockUpdate ( msg , 0 , msg . Length ) ;
293
+ bool shouldVerify = sig . VerifySignature ( sm ) ;
294
+ Assert . True ( shouldVerify , $ "{ name } { count } : VerifySignature") ;
295
+ }
296
+ }
297
+
169
298
private static void ImplKeyGen ( string name , Dictionary < string , string > data , SlhDsaParameters parameters )
170
299
{
171
300
byte [ ] skSeed = Hex . Decode ( data [ "skSeed" ] ) ;
@@ -204,7 +333,7 @@ private static void ImplKeyGen(string name, Dictionary<string, string> data, Slh
204
333
// additionalRandomness = Hex.Decode(data["additionalRandomness"]);
205
334
// }
206
335
207
- // var privateKey = new SlhDsaPrivateKeyParameters(parameters, sk);
336
+ // var privateKey = SlhDsaPrivateKeyParameters.FromEncoding (parameters, sk);
208
337
209
338
// byte[] generated = privateKey.SignInternal(optRand: additionalRandomness, message, 0, message.Length);
210
339
@@ -218,16 +347,21 @@ private static void ImplKeyGen(string name, Dictionary<string, string> data, Slh
218
347
// byte[] message = Hex.Decode(data["message"]);
219
348
// byte[] signature = Hex.Decode(data["signature"]);
220
349
221
- // var publicKey = new SlhDsaPublicKeyParameters(parameters, pk);
350
+ // var publicKey = SlhDsaPublicKeyParameters.FromEncoding (parameters, pk);
222
351
223
352
// bool verified = publicKey.VerifyInternal(message, 0, message.Length, signature);
224
353
225
354
// Assert.True(verified == testPassed, "expected " + testPassed);
226
355
//}
227
356
228
- private static void RunTestVectors ( string homeDir , string fileName , RunTestVector runTestVector )
357
+ private static void RunTestVectors ( string homeDir , string fileName , RunTestVector runTestVector ) =>
358
+ RunTestVectors ( homeDir , fileName , sampleOnly : false , runTestVector ) ;
359
+
360
+ private static void RunTestVectors ( string homeDir , string fileName , bool sampleOnly ,
361
+ RunTestVector runTestVector )
229
362
{
230
363
var data = new Dictionary < string , string > ( ) ;
364
+ var sampler = sampleOnly ? new TestSampler ( ) : null ;
231
365
using ( var src = new StreamReader ( SimpleTest . FindTestResource ( homeDir , fileName ) ) )
232
366
{
233
367
string line ;
@@ -249,14 +383,20 @@ private static void RunTestVectors(string homeDir, string fileName, RunTestVecto
249
383
250
384
if ( data . Count > 0 )
251
385
{
252
- runTestVector ( fileName , data ) ;
386
+ if ( sampler == null || ! sampler . SkipTest ( data [ "count" ] ) )
387
+ {
388
+ runTestVector ( fileName , data ) ;
389
+ }
253
390
data . Clear ( ) ;
254
391
}
255
392
}
256
393
257
394
if ( data . Count > 0 )
258
395
{
259
- runTestVector ( fileName , data ) ;
396
+ if ( sampler == null || ! sampler . SkipTest ( data [ "count" ] ) )
397
+ {
398
+ runTestVector ( fileName , data ) ;
399
+ }
260
400
data . Clear ( ) ;
261
401
}
262
402
}
0 commit comments