1
2
3
4
5
6
7 package mldsa_test
8
9 import (
10 "bytes"
11 "crypto"
12 "crypto/fips140"
13 "crypto/internal/cryptotest"
14 . "crypto/mldsa"
15 "crypto/sha3"
16 "encoding/hex"
17 "flag"
18 "math/rand/v2"
19 "strings"
20 "testing"
21 )
22
23 var _ crypto.Signer = (*PrivateKey)(nil)
24
25 var sixtyMillionFlag = flag.Bool("60million", false, "run 60M-iterations accumulated test")
26
27
28
29
30
31
32
33
34
35
36 func TestAccumulated(t *testing.T) {
37 t.Run("ML-DSA-44/100", func(t *testing.T) {
38 testAccumulated(t, MLDSA44(), 100,
39 "d51148e1f9f4fa1a723a6cf42e25f2a99eb5c1b378b3d2dbbd561b1203beeae4")
40 })
41 t.Run("ML-DSA-65/100", func(t *testing.T) {
42 testAccumulated(t, MLDSA65(), 100,
43 "8358a1843220194417cadbc2651295cd8fc65125b5a5c1a239a16dc8b57ca199")
44 })
45 t.Run("ML-DSA-87/100", func(t *testing.T) {
46 testAccumulated(t, MLDSA87(), 100,
47 "8c3ad714777622b8f21ce31bb35f71394f23bc0fcf3c78ace5d608990f3b061b")
48 })
49 if !testing.Short() {
50 t.Run("ML-DSA-44/10k", func(t *testing.T) {
51 t.Parallel()
52 testAccumulated(t, MLDSA44(), 10000,
53 "e7fd21f6a59bcba60d65adc44404bb29a7c00e5d8d3ec06a732c00a306a7d143")
54 })
55 t.Run("ML-DSA-65/10k", func(t *testing.T) {
56 t.Parallel()
57 testAccumulated(t, MLDSA65(), 10000,
58 "5ff5e196f0b830c3b10a9eb5358e7c98a3a20136cb677f3ae3b90175c3ace329")
59 })
60 t.Run("ML-DSA-87/10k", func(t *testing.T) {
61 t.Parallel()
62 testAccumulated(t, MLDSA87(), 10000,
63 "80a8cf39317f7d0be0e24972c51ac152bd2a3e09bc0c32ce29dd82c4e7385e60")
64 })
65 }
66 if *sixtyMillionFlag {
67 t.Run("ML-DSA-44/60M", func(t *testing.T) {
68 t.Parallel()
69 testAccumulated(t, MLDSA44(), 60000000,
70 "080b48049257f5cd30dee17d6aa393d6c42fe52a29099df84a460ebaf4b02330")
71 })
72 t.Run("ML-DSA-65/60M", func(t *testing.T) {
73 t.Parallel()
74 testAccumulated(t, MLDSA65(), 60000000,
75 "0af0165db2b180f7a83dbecad1ccb758b9c2d834b7f801fc49dd572a9d4b1e83")
76 })
77 t.Run("ML-DSA-87/60M", func(t *testing.T) {
78 t.Parallel()
79 testAccumulated(t, MLDSA87(), 60000000,
80 "011166e9d5032c9bdc5c9bbb5dbb6c86df1c3d9bf3570b65ebae942dd9830057")
81 })
82 }
83 }
84
85 func testAccumulated(t *testing.T, params Parameters, n int, expected string) {
86 s := sha3.NewSHAKE128()
87 o := sha3.NewSHAKE128()
88 seed := make([]byte, PrivateKeySize)
89 msg := make([]byte, 0)
90
91 for i := 0; i < n; i++ {
92 s.Read(seed)
93 dk, err := NewPrivateKey(params, seed)
94 if err != nil {
95 t.Fatalf("NewPrivateKey: %v", err)
96 }
97 pk := dk.PublicKey().Bytes()
98 o.Write(pk)
99 sig, err := dk.SignDeterministic(msg, nil)
100 if err != nil {
101 t.Fatalf("SignDeterministic: %v", err)
102 }
103 o.Write(sig)
104 pub, err := NewPublicKey(params, pk)
105 if err != nil {
106 t.Fatalf("NewPublicKey: %v", err)
107 }
108 if *pub != *dk.PublicKey() {
109 t.Fatalf("public key mismatch")
110 }
111 if err := Verify(dk.PublicKey(), msg, sig, nil); err != nil {
112 t.Fatalf("Verify: %v", err)
113 }
114 }
115
116 sum := make([]byte, 32)
117 o.Read(sum)
118 got := hex.EncodeToString(sum)
119 if got != expected {
120 t.Errorf("got %s, expected %s", got, expected)
121 }
122 }
123
124 func testAllParameters(t *testing.T, f func(*testing.T, Parameters)) {
125 for _, params := range []Parameters{MLDSA44(), MLDSA65(), MLDSA87()} {
126 t.Run(params.String(), func(t *testing.T) {
127 f(t, params)
128 })
129 }
130 }
131
132 func TestGenerateKey(t *testing.T) {
133 testAllParameters(t, testGenerateKey)
134 }
135
136 func testGenerateKey(t *testing.T, params Parameters) {
137 k1, err := GenerateKey(params)
138 if err != nil {
139 t.Fatalf("GenerateKey: %v", err)
140 }
141 k2, err := GenerateKey(params)
142 if err != nil {
143 t.Fatalf("GenerateKey: %v", err)
144 }
145 if k1.Equal(k2) {
146 t.Errorf("two generated keys are equal")
147 }
148 k1x, err := NewPrivateKey(params, k1.Bytes())
149 if err != nil {
150 t.Fatalf("NewPrivateKey: %v", err)
151 }
152 if !k1.Equal(k1x) {
153 t.Errorf("generated key and re-parsed key are not equal")
154 }
155 }
156
157 func TestAllocations(t *testing.T) {
158
159
160
161
162
163
164
165
166
167
168
169 var expected float64 = 7
170 if fips140.Enabled() {
171
172 expected += 1
173 }
174 if fips140.Version() == "v1.26.0" {
175
176
177
178 expected += 3
179 }
180 cryptotest.SkipTestAllocations(t)
181 if allocs := testing.AllocsPerRun(100, func() {
182 k, err := GenerateKey(MLDSA44())
183 if err != nil {
184 t.Fatalf("GenerateKey: %v", err)
185 }
186 seed := k.Bytes()
187 kk, err := NewPrivateKey(MLDSA44(), seed)
188 if err != nil {
189 t.Fatalf("NewPrivateKey: %v", err)
190 }
191 if !k.Equal(kk) {
192 t.Fatalf("keys not equal")
193 }
194 pkBytes := k.PublicKey().Bytes()
195 pk, err := NewPublicKey(MLDSA44(), pkBytes)
196 if err != nil {
197 t.Fatalf("NewPublicKey: %v", err)
198 }
199 message := []byte("Hello, world!")
200 context := "test"
201 sig, err := k.Sign(nil, message, &Options{Context: context})
202 if err != nil {
203 t.Fatalf("Sign: %v", err)
204 }
205 if err := Verify(pk, message, sig, &Options{Context: context}); err != nil {
206 t.Fatalf("Verify: %v", err)
207 }
208 }); allocs > expected {
209 t.Errorf("expected %0.0f allocations, got %0.1f", expected, allocs)
210 }
211 }
212
213 func TestParametersIdentity(t *testing.T) {
214
215
216 if MLDSA44() != MLDSA44() || MLDSA65() != MLDSA65() || MLDSA87() != MLDSA87() {
217 t.Errorf("MLDSA*() returned different values across calls")
218 }
219 if MLDSA44() == MLDSA65() || MLDSA65() == MLDSA87() || MLDSA44() == MLDSA87() {
220 t.Errorf("distinct parameter sets compare equal")
221 }
222 }
223
224
225
226 func computeMu(pk, ctx, msg []byte) []byte {
227 tr := sha3.NewSHAKE256()
228 tr.Write(pk)
229 trOut := make([]byte, 64)
230 tr.Read(trOut)
231
232 h := sha3.NewSHAKE256()
233 h.Write(trOut)
234 h.Write([]byte{0x00, byte(len(ctx))})
235 h.Write(ctx)
236 h.Write(msg)
237 out := make([]byte, 64)
238 h.Read(out)
239 return out
240 }
241
242
243
244
245 type fakeSignerOpts struct{ h crypto.Hash }
246
247 func (f fakeSignerOpts) HashFunc() crypto.Hash { return f.h }
248
249 func TestSign(t *testing.T) {
250 testAllParameters(t, func(t *testing.T, params Parameters) {
251 sk, err := GenerateKey(params)
252 if err != nil {
253 t.Fatalf("GenerateKey: %v", err)
254 }
255 pk := sk.PublicKey()
256 msg := []byte("test message")
257
258
259
260 sig1, err := sk.Sign(nil, msg, nil)
261 if err != nil {
262 t.Fatalf("Sign(nil opts): %v", err)
263 }
264 if got := len(sig1); got != params.SignatureSize() {
265 t.Errorf("len(sig) = %d, want %d", got, params.SignatureSize())
266 }
267 if err := Verify(pk, msg, sig1, nil); err != nil {
268 t.Errorf("Verify of nil-opts signature with nil opts: %v", err)
269 }
270 if err := Verify(pk, msg, sig1, &Options{}); err != nil {
271 t.Errorf("Verify of nil-opts signature with empty Options: %v", err)
272 }
273
274 sig2, err := sk.Sign(nil, msg, &Options{})
275 if err != nil {
276 t.Fatalf("Sign(&Options{}): %v", err)
277 }
278 if err := Verify(pk, msg, sig2, nil); err != nil {
279 t.Errorf("Verify of empty-Options signature with nil opts: %v", err)
280 }
281
282
283
284 sig3, err := sk.Sign(nil, msg, fakeSignerOpts{h: 0})
285 if err != nil {
286 t.Fatalf("Sign(fakeSignerOpts{0}): %v", err)
287 }
288 if err := Verify(pk, msg, sig3, nil); err != nil {
289 t.Errorf("Verify of fake-opts signature: %v", err)
290 }
291
292
293 sig4, err := sk.Sign(nil, msg, crypto.Hash(0))
294 if err != nil {
295 t.Fatalf("Sign(crypto.Hash(0)): %v", err)
296 }
297 if err := Verify(pk, msg, sig4, nil); err != nil {
298 t.Errorf("Verify of Hash(0)-opts signature: %v", err)
299 }
300
301
302 if _, err := sk.Sign(nil, msg, crypto.SHA256); err == nil {
303 t.Errorf("Sign with crypto.SHA256 opts: want error, got nil")
304 }
305 if _, err := sk.SignDeterministic(msg, crypto.SHA256); err == nil {
306 t.Errorf("SignDeterministic with crypto.SHA256 opts: want error, got nil")
307 }
308
309
310 detA, err := sk.SignDeterministic(msg, nil)
311 if err != nil {
312 t.Fatalf("SignDeterministic(nil): %v", err)
313 }
314 detB, err := sk.SignDeterministic(msg, &Options{})
315 if err != nil {
316 t.Fatalf("SignDeterministic(&Options{}): %v", err)
317 }
318 if !bytes.Equal(detA, detB) {
319 t.Errorf("SignDeterministic with nil and &Options{} differ")
320 }
321
322
323
324 detCtx, err := sk.SignDeterministic(msg, &Options{Context: "ctx"})
325 if err != nil {
326 t.Fatalf("SignDeterministic(ctx): %v", err)
327 }
328 if string(detCtx) == string(detA) {
329 t.Errorf("SignDeterministic with empty and non-empty context match")
330 }
331 if err := Verify(pk, msg, detCtx, nil); err == nil {
332 t.Errorf("Verify of context signature with empty context: want error, got nil")
333 }
334 if err := Verify(pk, msg, detCtx, &Options{Context: "ctx"}); err != nil {
335 t.Errorf("Verify with matching context: %v", err)
336 }
337
338
339 longCtx := strings.Repeat("x", 256)
340 if _, err := sk.Sign(nil, msg, &Options{Context: longCtx}); err == nil {
341 t.Errorf("Sign with 256-byte context: want error, got nil")
342 }
343 if _, err := sk.SignDeterministic(msg, &Options{Context: longCtx}); err == nil {
344 t.Errorf("SignDeterministic with 256-byte context: want error, got nil")
345 }
346 if err := Verify(pk, msg, detA, &Options{Context: longCtx}); err == nil {
347 t.Errorf("Verify with 256-byte context: want error, got nil")
348 }
349
350
351 sigTampered := bytes.Clone(sig1)
352 sigTampered[len(sigTampered)/2] ^= 0x01
353 if err := Verify(pk, msg, sigTampered, nil); err == nil {
354 t.Errorf("Verify of tampered signature: want error, got nil")
355 }
356
357
358 msgTampered := bytes.Clone(msg)
359 msgTampered[0] ^= 0x01
360 if err := Verify(pk, msgTampered, sig1, nil); err == nil {
361 t.Errorf("Verify of modified message: want error, got nil")
362 }
363
364
365 skOther, err := GenerateKey(params)
366 if err != nil {
367 t.Fatalf("GenerateKey: %v", err)
368 }
369 sigOther, err := skOther.SignDeterministic(msg, nil)
370 if err != nil {
371 t.Fatalf("SignDeterministic: %v", err)
372 }
373 if err := Verify(pk, msg, sigOther, nil); err == nil {
374 t.Errorf("Verify of signature from a different key: want error, got nil")
375 }
376 })
377 }
378
379 func TestExternalMu(t *testing.T) {
380 testAllParameters(t, func(t *testing.T, params Parameters) {
381 sk, err := GenerateKey(params)
382 if err != nil {
383 t.Fatalf("GenerateKey: %v", err)
384 }
385 pk := sk.PublicKey()
386 pkBytes := pk.Bytes()
387 msg := []byte("hello mu")
388
389 for _, ctx := range []string{"", "ctx"} {
390 μ := computeMu(pkBytes, []byte(ctx), msg)
391 sig, err := sk.Sign(nil, μ, crypto.MLDSAMu)
392 if err != nil {
393 t.Fatalf("Sign(MLDSAMu, ctx=%q): %v", ctx, err)
394 }
395 if err := Verify(pk, msg, sig, &Options{Context: ctx}); err != nil {
396 t.Errorf("Verify of MLDSAMu signature, ctx=%q: %v", ctx, err)
397 }
398
399 detSig, err := sk.SignDeterministic(μ, crypto.MLDSAMu)
400 if err != nil {
401 t.Fatalf("SignDeterministic(MLDSAMu, ctx=%q): %v", ctx, err)
402 }
403 if err := Verify(pk, msg, detSig, &Options{Context: ctx}); err != nil {
404 t.Errorf("Verify of deterministic MLDSAMu signature, ctx=%q: %v", ctx, err)
405 }
406 detSig2, err := sk.SignDeterministic(μ, crypto.MLDSAMu)
407 if err != nil {
408 t.Fatalf("SignDeterministic(MLDSAMu) second call: %v", err)
409 }
410 if string(detSig) != string(detSig2) {
411 t.Errorf("SignDeterministic(MLDSAMu) is not deterministic")
412 }
413 }
414
415
416 μA := computeMu(pkBytes, []byte("a"), msg)
417 sigA, err := sk.Sign(nil, μA, crypto.MLDSAMu)
418 if err != nil {
419 t.Fatalf("Sign(MLDSAMu, ctx=a): %v", err)
420 }
421 if err := Verify(pk, msg, sigA, &Options{Context: "b"}); err == nil {
422 t.Errorf("Verify of MLDSAMu(ctx=a) signature with ctx=b: want error, got nil")
423 }
424
425
426 sigTampered := bytes.Clone(sigA)
427 sigTampered[len(sigTampered)/2] ^= 0x01
428 if err := Verify(pk, msg, sigTampered, &Options{Context: "a"}); err == nil {
429 t.Errorf("Verify of tampered MLDSAMu signature: want error, got nil")
430 }
431
432
433 if _, err := sk.Sign(nil, make([]byte, 32), crypto.MLDSAMu); err == nil {
434 t.Errorf("Sign(MLDSAMu) with 32-byte input: want error, got nil")
435 }
436 if _, err := sk.SignDeterministic(make([]byte, 32), crypto.MLDSAMu); err == nil {
437 t.Errorf("SignDeterministic(MLDSAMu) with 32-byte input: want error, got nil")
438 }
439 })
440 }
441
442 func TestPublicKey(t *testing.T) {
443 cases := []struct {
444 params Parameters
445 name string
446 pkSize int
447 sigSize int
448 }{
449 {MLDSA44(), "ML-DSA-44", MLDSA44PublicKeySize, MLDSA44SignatureSize},
450 {MLDSA65(), "ML-DSA-65", MLDSA65PublicKeySize, MLDSA65SignatureSize},
451 {MLDSA87(), "ML-DSA-87", MLDSA87PublicKeySize, MLDSA87SignatureSize},
452 }
453 for _, tc := range cases {
454 t.Run(tc.name, func(t *testing.T) {
455 if got := tc.params.String(); got != tc.name {
456 t.Errorf("Parameters.String() = %q, want %q", got, tc.name)
457 }
458 if got := tc.params.PublicKeySize(); got != tc.pkSize {
459 t.Errorf("Parameters.PublicKeySize() = %d, want %d", got, tc.pkSize)
460 }
461 if got := tc.params.SignatureSize(); got != tc.sigSize {
462 t.Errorf("Parameters.SignatureSize() = %d, want %d", got, tc.sigSize)
463 }
464
465 sk, err := GenerateKey(tc.params)
466 if err != nil {
467 t.Fatalf("GenerateKey: %v", err)
468 }
469 pk := sk.PublicKey()
470 if got := pk.Parameters(); got != tc.params {
471 t.Errorf("PublicKey.Parameters() = %v, want %v", got, tc.params)
472 }
473 if got := len(pk.Bytes()); got != tc.params.PublicKeySize() {
474 t.Errorf("len(PublicKey.Bytes()) = %d, want %d", got, tc.params.PublicKeySize())
475 }
476 if got := len(sk.Bytes()); got != PrivateKeySize {
477 t.Errorf("len(PrivateKey.Bytes()) = %d, want %d", got, PrivateKeySize)
478 }
479
480
481 anyPub := sk.Public()
482 pub2, ok := anyPub.(*PublicKey)
483 if !ok {
484 t.Fatalf("PrivateKey.Public() = %T, want *PublicKey", anyPub)
485 }
486 if !pk.Equal(pub2) {
487 t.Errorf("PrivateKey.Public() does not equal PublicKey()")
488 }
489
490
491 sk2, err := NewPrivateKey(tc.params, sk.Bytes())
492 if err != nil {
493 t.Fatalf("NewPrivateKey round-trip: %v", err)
494 }
495 if !sk.Equal(sk2) {
496 t.Errorf("PrivateKey round-trip not equal")
497 }
498 pk2, err := NewPublicKey(tc.params, pk.Bytes())
499 if err != nil {
500 t.Fatalf("NewPublicKey round-trip: %v", err)
501 }
502 if !pk.Equal(pk2) {
503 t.Errorf("PublicKey round-trip not equal")
504 }
505 })
506 }
507 }
508
509 func TestEqualWrongType(t *testing.T) {
510 sk, err := GenerateKey(MLDSA44())
511 if err != nil {
512 t.Fatalf("GenerateKey: %v", err)
513 }
514 if sk.Equal("not a key") {
515 t.Errorf("PrivateKey.Equal(string) = true, want false")
516 }
517 if sk.Equal((*PublicKey)(nil)) {
518 t.Errorf("PrivateKey.Equal(*PublicKey) = true, want false")
519 }
520 if sk.PublicKey().Equal("not a key") {
521 t.Errorf("PublicKey.Equal(string) = true, want false")
522 }
523 if sk.PublicKey().Equal((*PrivateKey)(nil)) {
524 t.Errorf("PublicKey.Equal(*PrivateKey) = true, want false")
525 }
526
527
528 sk2, err := GenerateKey(MLDSA44())
529 if err != nil {
530 t.Fatalf("GenerateKey: %v", err)
531 }
532 if sk.Equal(sk2) {
533 t.Errorf("two random PrivateKeys are Equal")
534 }
535 if sk.PublicKey().Equal(sk2.PublicKey()) {
536 t.Errorf("two random PublicKeys are Equal")
537 }
538 }
539
540 func TestInvalidParameters(t *testing.T) {
541 var zero Parameters
542 if _, err := GenerateKey(zero); err == nil {
543 t.Errorf("GenerateKey(zero Parameters): want error, got nil")
544 }
545 if _, err := NewPrivateKey(zero, make([]byte, PrivateKeySize)); err == nil {
546 t.Errorf("NewPrivateKey(zero Parameters): want error, got nil")
547 }
548 if _, err := NewPublicKey(zero, make([]byte, MLDSA44PublicKeySize)); err == nil {
549 t.Errorf("NewPublicKey(zero Parameters): want error, got nil")
550 }
551 }
552
553 func TestInvalidSize(t *testing.T) {
554 testAllParameters(t, func(t *testing.T, params Parameters) {
555 if _, err := NewPrivateKey(params, make([]byte, PrivateKeySize-1)); err == nil {
556 t.Errorf("NewPrivateKey with short seed: want error, got nil")
557 }
558 if _, err := NewPrivateKey(params, make([]byte, PrivateKeySize+1)); err == nil {
559 t.Errorf("NewPrivateKey with long seed: want error, got nil")
560 }
561 if _, err := NewPublicKey(params, make([]byte, params.PublicKeySize()-1)); err == nil {
562 t.Errorf("NewPublicKey with short encoding: want error, got nil")
563 }
564 if _, err := NewPublicKey(params, make([]byte, params.PublicKeySize()+1)); err == nil {
565 t.Errorf("NewPublicKey with long encoding: want error, got nil")
566 }
567
568 sk, err := GenerateKey(params)
569 if err != nil {
570 t.Fatalf("GenerateKey: %v", err)
571 }
572 msg := []byte("test message")
573 sig, err := sk.SignDeterministic(msg, nil)
574 if err != nil {
575 t.Fatalf("SignDeterministic: %v", err)
576 }
577 if err := Verify(sk.PublicKey(), msg, sig[:len(sig)-1], nil); err == nil {
578 t.Errorf("Verify with short signature: want error, got nil")
579 }
580 if err := Verify(sk.PublicKey(), msg, append(sig, 0), nil); err == nil {
581 t.Errorf("Verify with long signature: want error, got nil")
582 }
583 })
584
585
586
587 sk65, err := GenerateKey(MLDSA65())
588 if err != nil {
589 t.Fatalf("GenerateKey(MLDSA65): %v", err)
590 }
591 if _, err := NewPublicKey(MLDSA44(), sk65.PublicKey().Bytes()); err == nil {
592 t.Errorf("NewPublicKey(MLDSA44, MLDSA65 encoding): want error, got nil")
593 }
594 }
595
596 func BenchmarkSign(b *testing.B) {
597
598
599
600
601
602 b.Run("ML-DSA-44", func(b *testing.B) {
603 benchmarkSign(b, MLDSA44(), benchmarkMessagesMLDSA44)
604 })
605 b.Run("ML-DSA-65", func(b *testing.B) {
606 benchmarkSign(b, MLDSA65(), benchmarkMessagesMLDSA65)
607 })
608 b.Run("ML-DSA-87", func(b *testing.B) {
609 benchmarkSign(b, MLDSA87(), benchmarkMessagesMLDSA87)
610 })
611 }
612
613 func benchmarkSign(b *testing.B, params Parameters, messages []string) {
614 seed := make([]byte, 32)
615 priv, err := NewPrivateKey(params, seed)
616 if err != nil {
617 b.Fatalf("NewPrivateKey: %v", err)
618 }
619 rand.Shuffle(len(messages), func(i, j int) {
620 messages[i], messages[j] = messages[j], messages[i]
621 })
622 i := 0
623 for b.Loop() {
624 msg := messages[i]
625 if i++; i >= len(messages) {
626 i = 0
627 }
628 priv.SignDeterministic([]byte(msg), nil)
629 }
630 }
631
632 func BenchmarkVerify(b *testing.B) {
633 b.Run("ML-DSA-44", func(b *testing.B) {
634 benchmarkVerify(b, MLDSA44())
635 })
636 b.Run("ML-DSA-65", func(b *testing.B) {
637 benchmarkVerify(b, MLDSA65())
638 })
639 b.Run("ML-DSA-87", func(b *testing.B) {
640 benchmarkVerify(b, MLDSA87())
641 })
642 }
643
644 func benchmarkVerify(b *testing.B, params Parameters) {
645 priv, err := GenerateKey(params)
646 if err != nil {
647 b.Fatalf("GenerateKey: %v", err)
648 }
649 msg := make([]byte, 128)
650 sig, err := priv.SignDeterministic(msg, &Options{Context: "context"})
651 if err != nil {
652 b.Fatalf("SignDeterministic: %v", err)
653 }
654 pub := priv.PublicKey().Bytes()
655
656
657
658
659 b.Run("Whole", func(b *testing.B) {
660 for b.Loop() {
661 pk, err := NewPublicKey(params, pub)
662 if err != nil {
663 b.Fatalf("NewPublicKey: %v", err)
664 }
665 if err := Verify(pk, msg, sig, &Options{Context: "context"}); err != nil {
666 b.Fatalf("Verify: %v", err)
667 }
668 }
669 })
670
671
672 b.Run("Precomputed", func(b *testing.B) {
673 pk, err := NewPublicKey(params, pub)
674 if err != nil {
675 b.Fatalf("NewPublicKey: %v", err)
676 }
677 for b.Loop() {
678 if err := Verify(pk, msg, sig, &Options{Context: "context"}); err != nil {
679 b.Fatalf("Verify: %v", err)
680 }
681 }
682 })
683 }
684
685 func BenchmarkKeygen(b *testing.B) {
686 b.Run("ML-DSA-44", func(b *testing.B) {
687 for b.Loop() {
688 NewPrivateKey(MLDSA44(), make([]byte, 32))
689 }
690 })
691 b.Run("ML-DSA-65", func(b *testing.B) {
692 for b.Loop() {
693 NewPrivateKey(MLDSA65(), make([]byte, 32))
694 }
695 })
696 b.Run("ML-DSA-87", func(b *testing.B) {
697 for b.Loop() {
698 NewPrivateKey(MLDSA87(), make([]byte, 32))
699 }
700 })
701 }
702
703 var benchmarkMessagesMLDSA44 = []string{
704 "BUS7IAZWYOZ4JHJQYDWRTJL4V7",
705 "MK5HFFNP4TB5S6FM4KUFZSIXPD",
706 "DBFETUV4O56J57FXTXTIVCDIAR",
707 "I4FCMZ7UNLYAE2VVPKTE5ETXKL",
708 "56U76XRPOVFX3AU7MB2JHAP6JX",
709 "3ER6UPKIIDGCXLGLPU7KI3ODTN",
710 "JPQDX2IL3W5CYAFRZ4XUJOHQ3G",
711 "6AJOEI33Z3MLEBVC2Q67AYWK5L",
712 "WE3U36HYOPJ72RN3C74F6IOTTJ",
713 "NMPF5I3B2BKQG5RK26LMPQECCX",
714 "JRGAN2FA6IY7ESFGZ7PVI2RGWA",
715 "UIKLF6KNSIUHIIVNRKNUFRNR4W",
716 "HA252APFYUWHSZZFKP7CWGIBRY",
717 "JFY774TXRITQ6CIR56P2ZOTOL6",
718 "ZASYLW5Y3RAOC5NDZ2NCH5A4UY",
719 "42X4JXNPXMFRCFAE5AKR7XTFO7",
720 "YAHQUWUH534MUI2TYEKQR7VR3A",
721 "HBP7FGEXGSOZ5HNOVRGXZJU2KG",
722 "HG4O7DCRMYMQXASFLMYQ6NMIXK",
723 "2KPQMDZKS65CLJU4DHTMVV5WI3",
724 "G6YSUTEX4HHL44ISK2JVVK45BV",
725 "PUJGPEQUBQM3IK2EXDQFJ2WGBG",
726 "PNS6HMQAWA3RORSMSNEUAINMIR",
727 "L35MZS4XYIJK453OFXCZG4WHIK",
728 "CRY54YZMFRF6JTB3FPNNBWPUOG",
729 "Y25TSZBWGU4HJCRMWZHAWXQ2DN",
730 "23W64TW3AKZPKCM4HMKEHFI6VQ",
731 "PWQAOZ24B4VLNEQR4XKN7LZHDI",
732 "YINPDR3ZSAKPPXP6J6VAXHIPYO",
733 "JDBB52ZRAB3PYBPNE7P4COY5PJ",
734 "4DYU52LQLVG3LTREOTLBCJK3XC",
735 "AB45MV6RKUGPCW4EUK7DX23MJX",
736 "HEJSITE5K7J6YJ74OEATVTCERV",
737 "ZKI5QCFCGM26UK7F5KYTENXKD2",
738 "VH5G3ZLF5XC22QAEJ6JDGOBE5Y",
739 "HYGXFHH3JW5SENG26MXLL54IGV",
740 "MJUCRL36JZ757UYHBFPCJBPZRH",
741 "IBH3T6NAVLCJQBYSVHAQFUITYA",
742 "VMWCS7JMIMFQB6TPRAMOUXIKWD",
743 "SXRPGPNNW2MMBKQS3HJURIQ3XV",
744 "YPPYMJZW6WYXPSCZIPI57NTP5L",
745 "N3SH6DUH6UOPU7YMQ6BJJEQSPI",
746 "Q243DGA6VC6CW66FFUAB5V3VLB",
747 "OUUBXEU4NJBRN5XZJ7YQUPIZLA",
748 "H5TWHVGC7FXG6MCKJQURD3RNWG",
749 "OONG2ZZ7H3P5BREEEURNJHBBQG",
750 "HWROSSRTBCQOAIQAY5S4EQG4FX",
751 "AJW6PW62JQNU72VKGIQMPBX64C",
752 "OXECVUVAWBBBXGGQGQBTYVEP4S",
753 "M5XN6V2LQJDEIN3G4Z6WJO6AVT",
754 "NHGJUX3WGRTEIRPFWC2I467ST4",
755 "SEOADTJDKAYYLDSC4VAES2CRDJ",
756 "J5AT674S577ZFGEURNIAGYOHKW",
757 "VJQVNMGHG4ITFX2XSPSDEWVZWD",
758 "ZWY3KJPXTAVWWVHNAJDUXZ52TG",
759 "HY46PBUGP4EMH34C6Q56MO7CJP",
760 "MQTUO7CF6R6CRJPVV6F673M6VW",
761 "35Z2Z5KV2RBJPQ7OZ24ZJE6BKR",
762 "OVUEVXBLCU2BBY25QP5WJACDIX",
763 "LNJX7PCLYL35WYJBW6CTXENPUU",
764 "IH7E766LCENOQ5ZKZVCMLEPACU",
765 "T2HZFGDDSFQ6YADB52NIFLBFEV",
766 "RHQUJMN4MB5SYY4FP4ARZH52QJ",
767 "W7GZC5ZM63UF2EJ7OC4WJM3OTH",
768 "T2NHNFVOMICY33AQZSR53HXFQ6",
769 "7ZVB4Y4K4Y2VAM5NC7HHAJNZIB",
770 "UX2I4VF62XJGP2XTNN6LDKXTOH",
771 "HJAMJR5RQTQW7JMW7ZLPRBZE7E",
772 "HKWSKX7MB5346PHYNWNBAYDSYK",
773 "BVWSB75HFLLE45MWA6EPHPTCFR",
774 "YDH2J6NMM7UINHGUOPIUI7PSSR",
775 "SYQPZLK52HMUAQFMVHGRJYKBEY",
776 "7AA6UQFGSPBGNUDPLWXSGNKKPP",
777 "AYXRJGRWZ5S3QOEDVWYHHCICHV",
778 "KFJYAWO7IATSBCSTDUAA5EPFAN",
779 "3JABTLB6T2ICHGVT3HXZZ3OAIT",
780 "WCM3IBOCQJ36WSG627CCNK3QA7",
781 "5FB5H3BZN2J4RGR2DUW7M37NKZ",
782 "VKDDAD3BVOMPSNEDGIRHKX5S6R",
783 "LFH5HVUR726OSFD3YVYM3ZHEIH",
784 "Y4ETQB2KZVFB4M7SALLCTHX2FB",
785 "E6SAU3C25MO2WBBVBKCKP2N4ZE",
786 "3JA54Q3NEKURB5EAPL2FOFIESD",
787 "FZPBW7BIQIW3FTKQD4TLKNWLMD",
788 "LY5W6XFA2ZRI53FTUJYGWZ5RX6",
789 "QID236JY3ICR55O5YRED33O7YT",
790 "HDRU3L6MFEBCBQFNLF5IRPMOAL",
791 "232ANKJBDBG4TSKQ7GJMWTHT23",
792 "CDWE3CELZM5AOJGYEFHMUNSP5O",
793 "7LNJRBOKN6W7RXUU34MDJ2SNKL",
794 "S3IZOADTW2A6E5IGRO5WKX7FVH",
795 "ZAISTLXC55EBMTN6KZ6QX5S7OS",
796 "4Z5ZIVCMFR2PY2PY4Z47T4YPYA",
797 "NE36L53Z6AMYQU7Q5REFUF76MK",
798 "WND5UP5M6KWPBRFP5WIWTOWV3I",
799 "7OC54DLFWMADJEMKEJ3Y2FMMZS",
800 "BWJVZHGEN43ULNIOZCPZOB64HG",
801 "VDFPQSR7RE54A75GT4JDZY5JK2",
802 "HFCD5EPBZBSVMXIDA47DZ6MRD6",
803 "RNBVFIUUJUM7EHRE3VNWSTORGO",
804 "VO5NLQJBR22CRRYUETGTU6JLMR",
805 "RZOMNFHBTL6HMGWH4PEEDASK7U",
806 "QL73UBTOLK5O2TW43YWAIKS6T3",
807 "NE3QVSMWS5G3W5C3BMKTJNMI2L",
808 "YHI6EYQ4GZMB2QPGHPUG2ZUOEL",
809 "6MBATW7MFNRUQBFD3GM35B7YPM",
810 "AIYRY6P5T4XU44CGVPEV6W43FR",
811 "MIAQ2FHXMAPY5NXSS45VRDPRMG",
812 "2SNLHQYKK2K6NSWOF6KPGZ3CPC",
813 "RVBHIQO5LH77ZWEAO3SVL72M2V",
814 "XXTGJCJNRSNLE7ARAH2UU6LVKR",
815 "DQMGILY5IDMWN5OYQYYXH26ZGR",
816 "627VTXXMM455KMTFNUUTKNFXPY",
817 "HC7IBFGLZCWGUR4K7REPMPW6W4",
818 "CHL6JRQUS7D4NML3PFT37PPZAA",
819 "Y767HXJAGJ75KE3JLO4DTLQIXC",
820 "NTIODXI5I7TF2KXXWXOAYGT7G4",
821 "PKZYEK2WAI4D4HEYYZH6H5IOMP",
822 "FG6J6G7HZDEDF4JQBQOTC7RQGZ",
823 "3VHM2VZU77Y25E3UUYZJLB2QLA",
824 "WRZQJQW7ARH4DXYHVLCJ4HRTTB",
825 "LQXKV5HD2AZHENSJ2VFLJ5YU5L",
826 "MF6Q4OA2EN6TG6BUDK7RWCQNPU",
827 "3USKYKPC5CB3EC4ZRMZVE3R2UO",
828 "3WICO2GVS3IRBFUHNDLNKWVP7N",
829 "P6ZR2UZZOVUZKT4KUS5WICW5XE",
830 "PYPZUU76RYVOUZGUUX33HLDKYA",
831 "2FTSURHV34VYTVIUU7W6V5C3NK",
832 "YABDYMGXS2MD2CYF3S4ALG4FLG",
833 "MHIBDH25RRPWV3P4VAWT6SAX3I",
834 "OINSMWJQ2UTOOKZ3X6ICXXBQR7",
835 "PFTQS7JNU2Q3Q6L4CGBXVLOYNE",
836 "A4MZ7CCVYQUDJ2AFHNXBBQ3D24",
837 "CPUB5R3ORTCMSMCLUQURE6AN5O",
838 "NF5E7U3DFTXWFFXXHUXTEP4VZQ",
839 "AWB5WDFERWSSJG53YGJMDORQKR",
840 "U5JQUILKD6SEL6LXAMNFZP6VSW",
841 "M45NLOAFLO74EJKG5EXNET6J5Y",
842 "P2KTEUMZ5DZZMYSPOHDR2WJXAN",
843 "KVO7AXZNFBUBPYLOTZQQ42TFNS",
844 "WGJJ7SAEV6SBBWWYS4BTLD63WM",
845 "Y6GURVDV4ESRBPWSTV25T4PE4K",
846 "ESK7MPFPUZ5ZAQ52RP4SQIYCCC",
847 "623M3CIABZ3RANERQ2IREXAVYO",
848 "OQ4CQCFO42RS4BMMSGSDLUTOQO",
849 "AMFHRDVGM6G2TIR3TKIFGFSDVM",
850 "7VVSGGCVC53PLOYG7YHPFUJM5X",
851 "Z3HMESVL7EZUSZNZ33WXEBHA2N",
852 "AWWVRQD5W7IBSQPS26XOJVDV5H",
853 "OQBZ5ZST3U3NZYHSIWRNROIG6L",
854 "II573BW7DJLBYJSPSYIABQWDZD",
855 "MOKXOQFOCUCLQQH4UKH2DPE7VN",
856 "XR54NGUOU6BBUUTINNWBPJ35HX",
857 "DNK36COZGFXI6DY7WLCNUETIRT",
858 "R5M2PV7E3EHEM3TLGRCL3HSFMC",
859 "ITKENZQYDQMZFCUPOT7VF3BMU7",
860 "5GDCB74PPPHEP5N5G3DVRCYT7R",
861 "ZMKXVRPLI5PY5BDVEPOA3NQZGN",
862 "GBLIALWTHTUDTOMDERQFVB77CS",
863 "VKRTTXUTFOK4PJAQQZCCT7TV3T",
864 "ZJBUJJ4SW62BXOID3XO2W2M2PF",
865 "SKWT5T6QJTCD3FCINIK22KMVBJ",
866 "EHINNU6L33HRLOOJ3A2XFJSYQL",
867 "N4HRQJEFPAT5SU3YPO74WSMQIR",
868 "TGPTZ3ENMFWB5CZKJFR5WHIRI4",
869 "O4HNFTAUJJ2LZPQXPXRAXOVABA",
870 "4JVB5STP2YG5GYOXDWIF4KCKFB",
871 "MY554X3YZHBECLHNNZ7A3SPJTU",
872 "ASCJMAH7VCQAD2QJSWXPSVSM3H",
873 "NBNGL5DZ623KCG2JNZFGZMZ7KD",
874 "KGMZSW35AEQOJ6FA7IR7BHZI52",
875 "Q7QUHHS4OJFMJ4I3FY6TDKSMZQ",
876 "MZAE7TOEXAS76T7KIC73FEYRU4",
877 "2BVESR3REAWADCGYOYM7T646RG",
878 "EK3L2ORP4LT3HU3EMXDSQWFOKJ",
879 "3X4A6VMGMIDLVK72FZSDHSERWY",
880 "I3UHWI6M6HQFRBSQ6W2SABUNUP",
881 "REKPXW4DIB4MTKMPHN3RBVHVME",
882 "W37FNFZE35NX65Z7CVQ7L5U4L5",
883 "4AGYK6U2KP6RAOADCBUDDCBECV",
884 "IXM4SFQUDW2NOTXZIPWTNGET3F",
885 "6YE4G3VELF27MN3Z5B4VIQ3XYK",
886 "LPOZCPZAG3MD47MIWGR4FIOCDH",
887 "WGREKUL2LD7C7SYGKH7APIY2A6",
888 "WWW277FKTKUXQMP4BECSRHLWJI",
889 "UYE4IQPMSTXVQG7EJALKWWEGDN",
890 "TIV2L5Z6K7SNGNUVWSNKTAF4UE",
891 "I3FQOAW3PINUK26P62HCX657FO",
892 }
893
894 var benchmarkMessagesMLDSA65 = []string{
895 "NDGEUBUDWGRJJ3A4UNZZQOEKNL",
896 "ACGYQUXN4POOFUENCLNCIPHFAZ",
897 "Z3XETEYKROVJH7SIHOIAYCTO42",
898 "DXWCVCEFULV7XHRWHJWSEXWES7",
899 "BCR2D5PNLGFYX6B3QFQFV23JZP",
900 "2DVP5HNG54ES64QK4D37PWUYTJ",
901 "UJM4ADPJLURAIQH4XA6QYUGNJ6",
902 "B5WRCIPK5IVZW52R6TJOKNPKZH",
903 "7QNL6JTSP62IGX6RCM2NHRMTKK",
904 "EJSZQYLM7G7AJCGIEVBV2UW7NN",
905 "UFNA2NKJ3QFWNHHL5CXZ4R5H46",
906 "QZAXRTT3E4DOGVTJCOTBG3WXQV",
907 "KH2ETOYZO5UHIHIKATWJMUVG27",
908 "V5HVVQTOWRXZ2PB4XWXSEKXUN5",
909 "5LA7NAFI2LESMH533XY45QVCQW",
910 "SMF4TWPTMJA2Z4F4OVETTLVRAY",
911 "FWZ5OJAFMLTQRREPYF4VDRPPGI",
912 "OK3QMNO3OZSKSR6Q4BFVOVRWTH",
913 "NQOVN6F6AOBOEGMJTVMF67KTIJ",
914 "CCLC4Y6YT3AQ3HGT2QNSYAUGNV",
915 "CAZJHCHBUYQ6OKZ7DMWMDDLIZQ",
916 "LVW5XDTHPKOW5D452SYD7AFO6Q",
917 "EYA6O6FTYPC6TRKZPRPX5N2KQ4",
918 "Z6SGAEZ2SAAZHPQO7GL7CUMBAG",
919 "FKUCKW6JQVF4WQYXUSXYZQMAVY",
920 "LN2KDF4DANPE4SC4GKJ4BES3IZ",
921 "AVCRTWB6ALOQHY34XI7NTMP2JH",
922 "A5WHIS6CBWPCYIEC6N2MBAOEZ6",
923 "JC2BH476BXUQFIDA6UCR5V4G4F",
924 "NU6XH6VLSSFHVSRZCYXPFYKYCD",
925 "GSUXVZBDDYSZYFGXNP6AZW3PTC",
926 "XJPRNJ26XP4MIYH2Q7M7MPZ73M",
927 "INUTUP3IRFWIIT23DNFTIYKCFY",
928 "T4KH7HKLEYGXHBIRFGFCRUZCC4",
929 "GGQX4JFVWZHE5Y73YTLMSSOXNS",
930 "BUA4Q3TQZGLVHMMJU62GQOSHLV",
931 "WXW3SJXLSZO2MYF4YFIMXL2IQP",
932 "Q32XBVVGFQTSXAIDJE6XSEPRZG",
933 "6TEXT6SA7INRCTDSCSVZJEQ2YG",
934 "ZBN4UL43C3SJIG4HYR236PXCVS",
935 "TVWPLLC7NROBREWOM75VA3XCR3",
936 "CCDGL2FURLBABQ4IJBYCB75JFR",
937 "XBZGCOVTZHCPAARBTMAKPIE6GJ",
938 "TPRAENJ7I54XRIVH6LL6FDIA3I",
939 "RKOM3PHFILPIIQZL4ILQWGRYWI",
940 "CEEZIZ2WUXHQQFATYYGQ3ZDBTI",
941 "SLKOVAP6WLIVJBVU7VZG3ZGEOW",
942 "TWMCLJJSWEEQQPQGGDKEJ5SU2R",
943 "IFMUXXCD2LC7IGQLZ2QEK5UOQ2",
944 "C7IWFEBHW2CXN4XBJS7VLWH3VK",
945 "7KJYUEW3F264727TM4LE6RMGDO",
946 "BPG2XAPBMBTA4VMPUM7IZVZPK3",
947 "Y5X577BWRZNPLNUHJVSKGMUXYB",
948 "ZCKMKM23E4IUPTNQDFN2LTLZVX",
949 "4RKK223JNBDAP4G5DOAHHZ3VNO",
950 "5UZ3TQZHZT22ISTB4WJEVO6MC4",
951 "YMVS4HFSJ32CRZRL23PXZUEJFJ",
952 "UQEUJUTPSZLZARNBXWMCTMHPFF",
953 "CZAAZ5WK7EIPMW7NA3EZNNBF45",
954 "227PBHH23WM7F2QLEZSPFYXVW4",
955 "YUYS2J5CRFXZ4J4KJT2ZKIZVW3",
956 "MFLHZJOZV44SN4AH6OJ3QZWM2O",
957 "H2B3CRBCXYN7QWDGYUPHQZP23A",
958 "T4L6YWQUQ3CTACENAJ5WUXZWFH",
959 "N723H6MUGPZSRZ72C635OD4BP7",
960 "NI4TUMVA6LQPQV2TXPN4QOIGBZ",
961 "CQI3S4LSTQASSJJVZXEFPOVW7K",
962 "ANPY4HJ64LLSB3GK2R4C6WDBS3",
963 "RGWQCZKQLMT5FZRDE4B3VMASVK",
964 "Q3WCCF2HA3CA4WWRJBMGBW7WI7",
965 "2AKJRXFHXLUQPOXPTLSZN5PW4A",
966 "IJWOOTI4N7RWXJIHAPXN6KEWEN",
967 "4D53T6N6ATOVTD4LKSTAAWBJMU",
968 "B4G5HDD6RITG6NIH6FXCRZDYZM",
969 "TJCDFKMRUY2OG6KRSMNVCGQFUP",
970 "PB33IHQKALAY6H6GVBVLI6ZRXK",
971 "SCCWGW2J5S4WL4FTTMQ435F6DB",
972 "ZVJH2HSMTLHGXMGPMXLJCKCLLE",
973 "62LG37U6JXR77YRZQQCDSBHVCS",
974 "BU4CBWOXQ352TEOKIXO245ID4O",
975 "UEZOH7KEIODSEVRUF6GMWGA2RB",
976 "IPJWROME4GM66CGLUWP5BJ4SX6",
977 "355GDC7TG64AZJ7IJX6K62KZCZ",
978 "AHTFKX3V7XUB3EWOMQVCGZYGUE",
979 "N4RV2GKXJ4SPHHJ52Z7K5EGLER",
980 "ZY7V7NE5F66XHDHWM6YNFEWZA6",
981 "DIKFO5KAVT4WAP7BOEFM56ZUSR",
982 "4TDFOFKDAPIOM3MU5GD7NPXNWQ",
983 "AD7YZO756HDK6YWFILAKW3JWA7",
984 "NUA53JS2ZK2BGHH3A7BJTJZYW7",
985 "QLCNC3AQNKLRMSYR62WQSQP5VI",
986 "SJ7OBS7ZYXSGXOYXPE5KW2XKN6",
987 "44HBMOGMIMJS63CEXQU7FCXE2E",
988 "KCK3J7ZL6QF4SLHHSWTJURK7PG",
989 "HLH4CLUGBSOOBSS3BPO62N5MC3",
990 "3FNS4GITO6OEUBAVDDXK4WOBTD",
991 "IAC3K3I4AQGY3G6UHG7PL2N6TE",
992 "KUKLNH74POJI5DYAEWUD7RABTQ",
993 "ETM6N7VU3GBSQ7P5MCD6UF3E3S",
994 "IZITM5NYBGJZLSI3BI4VEMW43U",
995 "46OPQU4LL6N3Z2U7KYPKUMBAGI",
996 "EV7YZ5DMAV7VKYJQUFSRD37GPP",
997 "AV7W2PGYDJIAKLFVEBL6BXQSGC",
998 "M2FOX5QZEZKV4QXKPI5XUZDHEM",
999 "R4IFPLVMOVYCHRTR6LXAUGP3LL",
1000 "JGH6XJUMP4DRVAM27P2JNOKXVO",
1001 "D2XN3ZLLU6VFPMDYM7NBHSQEOI",
1002 "2PO3BYENOMQK6SHQDCFSRPJQI3",
1003 "IBVQ7U3QEUC6PQRE4PV53JTZTK",
1004 "ZBCOX4P7NG2IXXFB2R43MG2SLV",
1005 "5NJDPQVVDO7ADNZ2CV7L6QBNGZ",
1006 "V7ASFIIYUMXFGW4B7ZM6LOGUTE",
1007 "PX5IJZ7W2LUPKM6YN4PMZ43ZLM",
1008 "AYK7SZ23DHC7Q56MWAJXBG76LB",
1009 "UYCAPXJM4HNGKLIDSZ4NCEDJLN",
1010 "UWMDZ3C2ODLACKGJPGETNQ3TA4",
1011 "Q6OI6R3WYYJ4CCZCDJBQMCRCZR",
1012 "LCMJHLP7354APCEGPKE7HHWTWB",
1013 "N7T7ZKOYPAMEYTTDOWZNCN6PRD",
1014 "UZADPU4UNHAF7L7LQDMTKA2EQH",
1015 "DC2OEPQDECVLRVNNCS6BMH4CRA",
1016 "37IZ427XHUMZ66EJ62U2YEZDAC",
1017 "6BCZDQZDPZLS5OGESKNUBPSSFV",
1018 "ST2LEMJ4OLQ32TJTLH2WCWT4WA",
1019 "GA2TL4SFLEW4G2B5PQMIKJT5XG",
1020 "L7PPBIET26EH7LQTLEFC4I4EIA",
1021 "6YSM7MC2W4DEV6ULAHMX27LH56",
1022 "QL26Z5KZ4YRRG2BXXGDRRLV357",
1023 "677TWRAJ5NSNHCE243POQPEG7K",
1024 "66MEBQJLGAGVXDX3KZ2YFTTVJM",
1025 "6D4VUWAQD6R65ICSDLFAATC67V",
1026 "7GXLD5CNU3TDUQSSW42SHL7B5D",
1027 "RQETUMEBG2ZM2NF2EZAQHGHWWE",
1028 "DCRX5ANWDMXZFIDVAXYLQZYMRN",
1029 "5SDWT7YAF7L4WWANAGYINZAYXH",
1030 "PZILRV7I2S6WKUSHKYRLA2JQY3",
1031 "2G66TK2PZ5MOTAZDN7BFS3LAIH",
1032 "QOLJ3WGJ6JS3FMMXBNTNAIKXVK",
1033 "FMAL67YTHDCCYVZ5CRMN2XJPDN",
1034 "UOTZDXTJKQ3YAIRKHTYNX6G55P",
1035 "X3DLNPJ3V62LRHGEY4DTT35H3R",
1036 "DKU7CHNXPB5QRZVGIQZW46XCKC",
1037 "RAKBD4LQKEDTVDSK3DVTRWG23B",
1038 "INTRA7BWHLVQMBRKBJNUSMF7MU",
1039 "AUYRBNVCOYYHOHUYOOFIZ2FWMD",
1040 "22EJVDEQ7PASLBAMTVKXOQP5RJ",
1041 "3S6NATWA57SFTZEW7UZUOUYAEU",
1042 }
1043
1044 var benchmarkMessagesMLDSA87 = []string{
1045 "LQQPGPNUME6QDNDTQTS4BA7I7M",
1046 "PTYEEJ7RMI6MXNN6PZH222Y6QI",
1047 "R6DTHAADKNMEADDK5ECPNOTOAT",
1048 "S2QM7VDC6UKRQNRETZMNAZ6SJT",
1049 "EYULPTSJORQJCNYNYVHDFN4N3F",
1050 "YETZNHZ75SXFU672VQ5WXYEPV2",
1051 "KTSND3JGA4AN3PCMG4455JEXGR",
1052 "JGE6HK37O6XMWZQZCHFUPNUEXP",
1053 "CRYB2FZD2BYNANBFFO2HRZEHGZ",
1054 "7MLNDZJ7OIEPBJZOMULOMQH2BA",
1055 "4WQCNTIFVSX2DNALMWUKZRA6CI",
1056 "Y5NK4OBDSDWC5WLL27CEEXYYOT",
1057 "C4SSWSPBVCDAWJXH2CDMXR36LH",
1058 "THDBKXRTKWJUGJMAAYTWTFMX7Z",
1059 "NWXPUD4DAA6QOREW4AFFYQYQNG",
1060 "3RQIJXMO7WYHBEBL3G6EOLNZNQ",
1061 "R7JEOHFP2C7O4AVPRPRELXWOMM",
1062 "LU6MWR7SZXVIKS54BY62X67NPA",
1063 "FG2FFM4F2ECKHCSJ75KXK632JP",
1064 "BF76ZDSVVUSYS5KK4FFD22YPS7",
1065 "HCLBWZRLHEMYZLFWHLAN2BKCZ7",
1066 "HGFVS4QC7AWXYPVRSWAK77KTQF",
1067 "LUZ3C53PUUHBWCDJ7WAHK2UT3K",
1068 "Y3WR6SMDUBW34N3MUT7EQYIJCV",
1069 "F2X35AQTXVZBMPXTWNAAH4ZX2W",
1070 "6MKFFDYWD6ZAKS3C6GRCRLZLRF",
1071 "AFMZYYFRHKMQRNKU5UTSKQ74H6",
1072 "TDTN7J3O367OVPWLESRNPLN4M2",
1073 "WYMLD2X6N4CZ2RDOKF5CFTSYTG",
1074 "UNPTSBLJ6HZRNR72T2VEEHCFX2",
1075 "SNCM4R2P27AJOXBS67RMCARS3U",
1076 "OU7QBE5QOXO7CIYTBJR3KOW2WK",
1077 "2NNQOBQKZ2OD4ZAXI3SNEURYUP",
1078 "YQTUPOYBT67XPCHIGKSGSKC3BZ",
1079 "HGB4ZM3G76IXYWWCMVT3HONRIS",
1080 "WZC6QUKRZZ2TOVA277JYKQITEW",
1081 "XO2WT46A5HYL6CUJF7SGJ6YWOG",
1082 "4QJA35PMYQIDRZ7ZHG7RLZJVGF",
1083 "BMJZELWZ4I2UWXESU3NR6ATC4M",
1084 "XWLFB7FN6D5PRY6YUXC5JUIBFM",
1085 "WRAFFF27AVTIOYIBYA2IPTXI3R",
1086 "VOXUTYTN2XZ362OJFO2R53UCUF",
1087 "UHN73ARJ737WUJ6QYEI7U46OPO",
1088 "3Y3K5E2A4ML3VYVNAFWEEIXTSN",
1089 "QMU4322NKPRLE7JBGYFGS36H2S",
1090 "NJAQTNCXPVDICTDVUKTPRCD2AX",
1091 "OC373ZFBNV2H46T6OY3XRPSUHG",
1092 "UBLAS6CDWE3A662MLKP7QDEOCC",
1093 "BKFDLAL2RTPMERYVW3B7UJ5W3H",
1094 "QFKFGXKGW5SAKLBAWQXUWW77OS",
1095 "EJNUQHTLLOVB4ARETOGLY4WUTJ",
1096 "N243OCMVLLAO6I2XLCYOIMQYGY",
1097 "YRRFLWK7ZASUKYX7ZLQMW2PJ6X",
1098 "3DGVPBWD2BIK6KQE65K72DNJNM",
1099 "TJRYMNOAIW33VIHKLJG4GXAVUK",
1100 "6DSRINAYXL34U54U355U7IVFGS",
1101 "6CHA4MX7LVS77XKRWG7IYC3XVL",
1102 "GM2CEGBEPBOHAPIOBUWJ4MJNTG",
1103 "VJKHGBY33VUIJFEQLX3JVUNQBD",
1104 "DTOHAD5M2KL46IZHE4TPLJWHTI",
1105 "IYFG3UDN7ROOY2ZFSLM2BU2LMQ",
1106 "A5OGJHPOE4PW6QSZYHZ5TKPGIC",
1107 "FX4BCN67AEGCLUTLFPNDL3SQU5",
1108 "MWIZQVOZOHTTBUXC3BEX62MNI5",
1109 "BYHVJHBLK4O6LFSKEIQ3CAAKU7",
1110 "QJU7P6KWSSKAA5GVA6RH4OV7MX",
1111 "I3T3XM5Z5TAJHAYDQHFA2ZV7PU",
1112 "L46MQCHV3TJ6FYIQQ2FCJXES74",
1113 "QXZRQIYAJMXYR6PU3VDYGCIT5W",
1114 "MFS53RR2XEYS22NYOJLGTHVTTM",
1115 "FRWIWJRP4AQMXWX4WJ4WYVKM3E",
1116 "X6GK6IGVLJWYSHLKHGXSW3TJDP",
1117 "L5LPJ2HIWA4UY6G6FMZXGDEDAM",
1118 "GD6FYOYUGDHXEQ5S2KLJEGNSN7",
1119 "ODAL7ZRKXSPAAN5DVRBWJQCFQX",
1120 "CV3QFBDXBPT3SCPJGUYSMDN6ZS",
1121 "IGSLSACRZ6XID466KQIB4YNGYO",
1122 "WZ2EACBN26RAML2S52YXRYP2OF",
1123 "LB76VEVNOBYFMKFZ7SDFCBCHQE",
1124 "TLFA7EU3JJFAP6EMUKNV2ZXRBM",
1125 "SIIJF6OXAKRP25CBUYFBRCDDVP",
1126 "TEPNI7TJ7HASJWIQMBS4VFLRQC",
1127 "VK2JINYWEDV7IQFWH4OTAD4W5O",
1128 "GILUH5AMVE4TM7EKPXJBZGT6EJ",
1129 "DV7ALFRAW3TI4WMQQLDTO6RNHN",
1130 "CAIB5G3NXC5ASPLFIWAFPVHS5B",
1131 "MLFJXZUOAGN7EGPMXOOVTB2CL4",
1132 "6MZYT3ANWHBOS67WGHZI3QPEAP",
1133 "LVJDQB52C2PERSSQJRMRCJ4UBF",
1134 "QY4VKAZAYQIZOX2L2VO2QHAQVC",
1135 "UAA5SST2XA76JPKM3XOZ5RUHFI",
1136 "VLZWF53JSQ6SCRUFDKVPXWAS4L",
1137 "NX2DZIKMJIYXUNSAHFP23FHTBU",
1138 "F5OAKDDDA34A2RPIKDPM5CYPMZ",
1139 "E5PEP3ANIK2L4VLOST4NIYNKBD",
1140 "IPBGFLHSMP4UFXF6XJX42T6CAL",
1141 "XHPU7DBFTZB2TX5K34AD6DJTK3",
1142 "2ZU7EJN2DG2UMT6HX5KGS2RFT6",
1143 "SD5S7U34WSE4GBPKVDUDZLBIEH",
1144 "WZFFL3BTQAV4VQMSAGCS45SGG3",
1145 "QE7ZT2LI4CA5DLSVMHV6CP3E3V",
1146 "YIWMS6AS72Z5N2ALZNFGCYC5QL",
1147 "A4QJ5FNY54THAKBOB65K2JBIV7",
1148 "6LORQGA3QO7TNADHEIINQZEE26",
1149 "5V45M6RAKOZDMONYY4DIH3ZBL2",
1150 "SVP7UYIZ5RTLWRKFLCWHAQV3Y2",
1151 "C2UYQL2BBE4VLUJ3IFNFMHAN7O",
1152 "P4DS44LGP2ERZB3OB7JISQKBXA",
1153 "A6B4O5MWALOEHLILSVDOIXHQ4Z",
1154 "DKQJTW5QF7KDZA3IR4X5R5F3CG",
1155 "H6QFQX2C2QTH3YKEOO57SQS23J",
1156 "DIF373ML2RWZMEOIVUHFXKUG7O",
1157 "Z5PPIA3GJ74QXFFCOSUAQMN5YN",
1158 "PM6XIDECSS5S77UXMB55VZHZSE",
1159 }
1160
View as plain text