// Copyright 2025 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. //go:build !fips140v1.0 package fipstest import ( "crypto/internal/cryptotest" "crypto/internal/fips140" . "crypto/internal/fips140/mldsa" "crypto/internal/fips140/sha3" "encoding/hex" "flag" "math/rand" "testing" ) var sixtyMillionFlag = flag.Bool("60million", false, "run 60M-iterations accumulated test") // TestMLDSAAccumulated accumulates 10k (or 100, or 60M) random vectors and checks // the hash of the result, to avoid checking in megabytes of test vectors. // // 60M in particular is enough to give a 99.9% chance of hitting every value in // the base field. // // 1-((q-1)/q)^60000000 ~= 0.9992 // // If setting -60million, remember to also set -timeout 0. func TestMLDSAAccumulated(t *testing.T) { t.Run("ML-DSA-44/100", func(t *testing.T) { testMLDSAAccumulated(t, NewPrivateKey44, NewPublicKey44, 100, "d51148e1f9f4fa1a723a6cf42e25f2a99eb5c1b378b3d2dbbd561b1203beeae4") }) t.Run("ML-DSA-65/100", func(t *testing.T) { testMLDSAAccumulated(t, NewPrivateKey65, NewPublicKey65, 100, "8358a1843220194417cadbc2651295cd8fc65125b5a5c1a239a16dc8b57ca199") }) t.Run("ML-DSA-87/100", func(t *testing.T) { testMLDSAAccumulated(t, NewPrivateKey87, NewPublicKey87, 100, "8c3ad714777622b8f21ce31bb35f71394f23bc0fcf3c78ace5d608990f3b061b") }) if !testing.Short() { t.Run("ML-DSA-44/10k", func(t *testing.T) { t.Parallel() testMLDSAAccumulated(t, NewPrivateKey44, NewPublicKey44, 10000, "e7fd21f6a59bcba60d65adc44404bb29a7c00e5d8d3ec06a732c00a306a7d143") }) t.Run("ML-DSA-65/10k", func(t *testing.T) { t.Parallel() testMLDSAAccumulated(t, NewPrivateKey65, NewPublicKey65, 10000, "5ff5e196f0b830c3b10a9eb5358e7c98a3a20136cb677f3ae3b90175c3ace329") }) t.Run("ML-DSA-87/10k", func(t *testing.T) { t.Parallel() testMLDSAAccumulated(t, NewPrivateKey87, NewPublicKey87, 10000, "80a8cf39317f7d0be0e24972c51ac152bd2a3e09bc0c32ce29dd82c4e7385e60") }) } if *sixtyMillionFlag { t.Run("ML-DSA-44/60M", func(t *testing.T) { t.Parallel() testMLDSAAccumulated(t, NewPrivateKey44, NewPublicKey44, 60000000, "080b48049257f5cd30dee17d6aa393d6c42fe52a29099df84a460ebaf4b02330") }) t.Run("ML-DSA-65/60M", func(t *testing.T) { t.Parallel() testMLDSAAccumulated(t, NewPrivateKey65, NewPublicKey65, 60000000, "0af0165db2b180f7a83dbecad1ccb758b9c2d834b7f801fc49dd572a9d4b1e83") }) t.Run("ML-DSA-87/60M", func(t *testing.T) { t.Parallel() testMLDSAAccumulated(t, NewPrivateKey87, NewPublicKey87, 60000000, "011166e9d5032c9bdc5c9bbb5dbb6c86df1c3d9bf3570b65ebae942dd9830057") }) } } func testMLDSAAccumulated(t *testing.T, newPrivateKey func([]byte) (*PrivateKey, error), newPublicKey func([]byte) (*PublicKey, error), n int, expected string) { s := sha3.NewShake128() o := sha3.NewShake128() seed := make([]byte, PrivateKeySize) msg := make([]byte, 0) for i := 0; i < n; i++ { s.Read(seed) dk, err := newPrivateKey(seed) if err != nil { t.Fatalf("NewPrivateKey: %v", err) } pk := dk.PublicKey().Bytes() o.Write(pk) sig, err := SignDeterministic(dk, msg, "") if err != nil { t.Fatalf("SignDeterministic: %v", err) } o.Write(sig) pub, err := newPublicKey(pk) if err != nil { t.Fatalf("NewPublicKey: %v", err) } if *pub != *dk.PublicKey() { t.Fatalf("public key mismatch") } if err := Verify(dk.PublicKey(), msg, sig, ""); err != nil { t.Fatalf("Verify: %v", err) } } got := hex.EncodeToString(o.Sum(nil)) if got != expected { t.Errorf("got %s, expected %s", got, expected) } } func TestMLDSAGenerateKey(t *testing.T) { t.Run("ML-DSA-44", func(t *testing.T) { testMLDSAGenerateKey(t, GenerateKey44, NewPrivateKey44) }) t.Run("ML-DSA-65", func(t *testing.T) { testMLDSAGenerateKey(t, GenerateKey65, NewPrivateKey65) }) t.Run("ML-DSA-87", func(t *testing.T) { testMLDSAGenerateKey(t, GenerateKey87, NewPrivateKey87) }) } func testMLDSAGenerateKey(t *testing.T, generateKey func() *PrivateKey, newPrivateKey func([]byte) (*PrivateKey, error)) { k1 := generateKey() k2 := generateKey() if k1.Equal(k2) { t.Errorf("two generated keys are equal") } k1x, err := newPrivateKey(k1.Bytes()) if err != nil { t.Fatalf("NewPrivateKey: %v", err) } if !k1.Equal(k1x) { t.Errorf("generated key and re-parsed key are not equal") } } func TestMLDSAAllocations(t *testing.T) { // We allocate the PrivateKey (k and kk) and PublicKey (pk) structs and the // public key (pkBytes) and signature (sig) byte slices on the heap. They // are all large and for the byte slices variable-length. Still, check we // are not slipping more allocations in. var expected float64 = 5 if fips140.Enabled { // The PCT does a sign/verify cycle, which allocates a signature slice. expected += 1 } cryptotest.SkipTestAllocations(t) if allocs := testing.AllocsPerRun(100, func() { k := GenerateKey44() seed := k.Bytes() kk, err := NewPrivateKey44(seed) if err != nil { t.Fatalf("NewPrivateKey44: %v", err) } if !k.Equal(kk) { t.Fatalf("keys not equal") } pkBytes := k.PublicKey().Bytes() pk, err := NewPublicKey44(pkBytes) if err != nil { t.Fatalf("NewPublicKey44: %v", err) } message := []byte("Hello, world!") context := "test" sig, err := Sign(k, message, context) if err != nil { t.Fatalf("Sign: %v", err) } if err := Verify(pk, message, sig, context); err != nil { t.Fatalf("Verify: %v", err) } }); allocs > expected { t.Errorf("expected %0.0f allocations, got %0.1f", expected, allocs) } } func BenchmarkMLDSASign(b *testing.B) { // Signing works by rejection sampling, which introduces massive variance in // individual signing times. To get stable but correct results, we benchmark // a series of representative operations, engineered to have the same // distribution of rejection counts and reasons as the average case. See also // https://words.filippo.io/rsa-keygen-bench/ for a similar approach. b.Run("ML-DSA-44", func(b *testing.B) { benchmarkMLDSASign(b, NewPrivateKey44, benchmarkMessagesMLDSA44) }) b.Run("ML-DSA-65", func(b *testing.B) { benchmarkMLDSASign(b, NewPrivateKey65, benchmarkMessagesMLDSA65) }) b.Run("ML-DSA-87", func(b *testing.B) { benchmarkMLDSASign(b, NewPrivateKey87, benchmarkMessagesMLDSA87) }) } func benchmarkMLDSASign(b *testing.B, newPrivateKey func([]byte) (*PrivateKey, error), messages []string) { seed := make([]byte, 32) priv, err := newPrivateKey(seed) if err != nil { b.Fatalf("NewPrivateKey: %v", err) } rand.Shuffle(len(messages), func(i, j int) { messages[i], messages[j] = messages[j], messages[i] }) i := 0 for b.Loop() { msg := messages[i] if i++; i >= len(messages) { i = 0 } SignDeterministic(priv, []byte(msg), "") } } // BenchmarkMLDSAVerify runs both public key parsing and signature verification, // since pre-computation can be easily moved between the two, but in practice // most uses of verification are for fresh public keys (unlike signing). func BenchmarkMLDSAVerify(b *testing.B) { b.Run("ML-DSA-44", func(b *testing.B) { benchmarkMLDSAVerify(b, GenerateKey44, NewPublicKey44) }) b.Run("ML-DSA-65", func(b *testing.B) { benchmarkMLDSAVerify(b, GenerateKey65, NewPublicKey65) }) b.Run("ML-DSA-87", func(b *testing.B) { benchmarkMLDSAVerify(b, GenerateKey87, NewPublicKey87) }) } func benchmarkMLDSAVerify(b *testing.B, generateKey func() *PrivateKey, newPublicKey func([]byte) (*PublicKey, error)) { priv := generateKey() msg := make([]byte, 128) sig, err := SignDeterministic(priv, msg, "context") if err != nil { b.Fatalf("SignDeterministic: %v", err) } pub := priv.PublicKey().Bytes() for b.Loop() { pk, err := newPublicKey(pub) if err != nil { b.Fatalf("NewPublicKey: %v", err) } if err := Verify(pk, msg, sig, "context"); err != nil { b.Fatalf("Verify: %v", err) } } } func BenchmarkMLDSAKeygen(b *testing.B) { b.Run("ML-DSA-44", func(b *testing.B) { for b.Loop() { NewPrivateKey44(make([]byte, 32)) } }) b.Run("ML-DSA-65", func(b *testing.B) { for b.Loop() { NewPrivateKey65(make([]byte, 32)) } }) b.Run("ML-DSA-87", func(b *testing.B) { for b.Loop() { NewPrivateKey87(make([]byte, 32)) } }) } var benchmarkMessagesMLDSA44 = []string{ "BUS7IAZWYOZ4JHJQYDWRTJL4V7", "MK5HFFNP4TB5S6FM4KUFZSIXPD", "DBFETUV4O56J57FXTXTIVCDIAR", "I4FCMZ7UNLYAE2VVPKTE5ETXKL", "56U76XRPOVFX3AU7MB2JHAP6JX", "3ER6UPKIIDGCXLGLPU7KI3ODTN", "JPQDX2IL3W5CYAFRZ4XUJOHQ3G", "6AJOEI33Z3MLEBVC2Q67AYWK5L", "WE3U36HYOPJ72RN3C74F6IOTTJ", "NMPF5I3B2BKQG5RK26LMPQECCX", "JRGAN2FA6IY7ESFGZ7PVI2RGWA", "UIKLF6KNSIUHIIVNRKNUFRNR4W", "HA252APFYUWHSZZFKP7CWGIBRY", "JFY774TXRITQ6CIR56P2ZOTOL6", "ZASYLW5Y3RAOC5NDZ2NCH5A4UY", "42X4JXNPXMFRCFAE5AKR7XTFO7", "YAHQUWUH534MUI2TYEKQR7VR3A", "HBP7FGEXGSOZ5HNOVRGXZJU2KG", "HG4O7DCRMYMQXASFLMYQ6NMIXK", "2KPQMDZKS65CLJU4DHTMVV5WI3", "G6YSUTEX4HHL44ISK2JVVK45BV", "PUJGPEQUBQM3IK2EXDQFJ2WGBG", "PNS6HMQAWA3RORSMSNEUAINMIR", "L35MZS4XYIJK453OFXCZG4WHIK", "CRY54YZMFRF6JTB3FPNNBWPUOG", "Y25TSZBWGU4HJCRMWZHAWXQ2DN", "23W64TW3AKZPKCM4HMKEHFI6VQ", "PWQAOZ24B4VLNEQR4XKN7LZHDI", "YINPDR3ZSAKPPXP6J6VAXHIPYO", "JDBB52ZRAB3PYBPNE7P4COY5PJ", "4DYU52LQLVG3LTREOTLBCJK3XC", "AB45MV6RKUGPCW4EUK7DX23MJX", "HEJSITE5K7J6YJ74OEATVTCERV", "ZKI5QCFCGM26UK7F5KYTENXKD2", "VH5G3ZLF5XC22QAEJ6JDGOBE5Y", "HYGXFHH3JW5SENG26MXLL54IGV", "MJUCRL36JZ757UYHBFPCJBPZRH", "IBH3T6NAVLCJQBYSVHAQFUITYA", "VMWCS7JMIMFQB6TPRAMOUXIKWD", "SXRPGPNNW2MMBKQS3HJURIQ3XV", "YPPYMJZW6WYXPSCZIPI57NTP5L", "N3SH6DUH6UOPU7YMQ6BJJEQSPI", "Q243DGA6VC6CW66FFUAB5V3VLB", "OUUBXEU4NJBRN5XZJ7YQUPIZLA", "H5TWHVGC7FXG6MCKJQURD3RNWG", "OONG2ZZ7H3P5BREEEURNJHBBQG", "HWROSSRTBCQOAIQAY5S4EQG4FX", "AJW6PW62JQNU72VKGIQMPBX64C", "OXECVUVAWBBBXGGQGQBTYVEP4S", "M5XN6V2LQJDEIN3G4Z6WJO6AVT", "NHGJUX3WGRTEIRPFWC2I467ST4", "SEOADTJDKAYYLDSC4VAES2CRDJ", "J5AT674S577ZFGEURNIAGYOHKW", "VJQVNMGHG4ITFX2XSPSDEWVZWD", "ZWY3KJPXTAVWWVHNAJDUXZ52TG", "HY46PBUGP4EMH34C6Q56MO7CJP", "MQTUO7CF6R6CRJPVV6F673M6VW", "35Z2Z5KV2RBJPQ7OZ24ZJE6BKR", "OVUEVXBLCU2BBY25QP5WJACDIX", "LNJX7PCLYL35WYJBW6CTXENPUU", "IH7E766LCENOQ5ZKZVCMLEPACU", "T2HZFGDDSFQ6YADB52NIFLBFEV", "RHQUJMN4MB5SYY4FP4ARZH52QJ", "W7GZC5ZM63UF2EJ7OC4WJM3OTH", "T2NHNFVOMICY33AQZSR53HXFQ6", "7ZVB4Y4K4Y2VAM5NC7HHAJNZIB", "UX2I4VF62XJGP2XTNN6LDKXTOH", "HJAMJR5RQTQW7JMW7ZLPRBZE7E", "HKWSKX7MB5346PHYNWNBAYDSYK", "BVWSB75HFLLE45MWA6EPHPTCFR", "YDH2J6NMM7UINHGUOPIUI7PSSR", "SYQPZLK52HMUAQFMVHGRJYKBEY", "7AA6UQFGSPBGNUDPLWXSGNKKPP", "AYXRJGRWZ5S3QOEDVWYHHCICHV", "KFJYAWO7IATSBCSTDUAA5EPFAN", "3JABTLB6T2ICHGVT3HXZZ3OAIT", "WCM3IBOCQJ36WSG627CCNK3QA7", "5FB5H3BZN2J4RGR2DUW7M37NKZ", "VKDDAD3BVOMPSNEDGIRHKX5S6R", "LFH5HVUR726OSFD3YVYM3ZHEIH", "Y4ETQB2KZVFB4M7SALLCTHX2FB", "E6SAU3C25MO2WBBVBKCKP2N4ZE", "3JA54Q3NEKURB5EAPL2FOFIESD", "FZPBW7BIQIW3FTKQD4TLKNWLMD", "LY5W6XFA2ZRI53FTUJYGWZ5RX6", "QID236JY3ICR55O5YRED33O7YT", "HDRU3L6MFEBCBQFNLF5IRPMOAL", "232ANKJBDBG4TSKQ7GJMWTHT23", "CDWE3CELZM5AOJGYEFHMUNSP5O", "7LNJRBOKN6W7RXUU34MDJ2SNKL", "S3IZOADTW2A6E5IGRO5WKX7FVH", "ZAISTLXC55EBMTN6KZ6QX5S7OS", "4Z5ZIVCMFR2PY2PY4Z47T4YPYA", "NE36L53Z6AMYQU7Q5REFUF76MK", "WND5UP5M6KWPBRFP5WIWTOWV3I", "7OC54DLFWMADJEMKEJ3Y2FMMZS", "BWJVZHGEN43ULNIOZCPZOB64HG", "VDFPQSR7RE54A75GT4JDZY5JK2", "HFCD5EPBZBSVMXIDA47DZ6MRD6", "RNBVFIUUJUM7EHRE3VNWSTORGO", "VO5NLQJBR22CRRYUETGTU6JLMR", "RZOMNFHBTL6HMGWH4PEEDASK7U", "QL73UBTOLK5O2TW43YWAIKS6T3", "NE3QVSMWS5G3W5C3BMKTJNMI2L", "YHI6EYQ4GZMB2QPGHPUG2ZUOEL", "6MBATW7MFNRUQBFD3GM35B7YPM", "AIYRY6P5T4XU44CGVPEV6W43FR", "MIAQ2FHXMAPY5NXSS45VRDPRMG", "2SNLHQYKK2K6NSWOF6KPGZ3CPC", "RVBHIQO5LH77ZWEAO3SVL72M2V", "XXTGJCJNRSNLE7ARAH2UU6LVKR", "DQMGILY5IDMWN5OYQYYXH26ZGR", "627VTXXMM455KMTFNUUTKNFXPY", "HC7IBFGLZCWGUR4K7REPMPW6W4", "CHL6JRQUS7D4NML3PFT37PPZAA", "Y767HXJAGJ75KE3JLO4DTLQIXC", "NTIODXI5I7TF2KXXWXOAYGT7G4", "PKZYEK2WAI4D4HEYYZH6H5IOMP", "FG6J6G7HZDEDF4JQBQOTC7RQGZ", "3VHM2VZU77Y25E3UUYZJLB2QLA", "WRZQJQW7ARH4DXYHVLCJ4HRTTB", "LQXKV5HD2AZHENSJ2VFLJ5YU5L", "MF6Q4OA2EN6TG6BUDK7RWCQNPU", "3USKYKPC5CB3EC4ZRMZVE3R2UO", "3WICO2GVS3IRBFUHNDLNKWVP7N", "P6ZR2UZZOVUZKT4KUS5WICW5XE", "PYPZUU76RYVOUZGUUX33HLDKYA", "2FTSURHV34VYTVIUU7W6V5C3NK", "YABDYMGXS2MD2CYF3S4ALG4FLG", "MHIBDH25RRPWV3P4VAWT6SAX3I", "OINSMWJQ2UTOOKZ3X6ICXXBQR7", "PFTQS7JNU2Q3Q6L4CGBXVLOYNE", "A4MZ7CCVYQUDJ2AFHNXBBQ3D24", "CPUB5R3ORTCMSMCLUQURE6AN5O", "NF5E7U3DFTXWFFXXHUXTEP4VZQ", "AWB5WDFERWSSJG53YGJMDORQKR", "U5JQUILKD6SEL6LXAMNFZP6VSW", "M45NLOAFLO74EJKG5EXNET6J5Y", "P2KTEUMZ5DZZMYSPOHDR2WJXAN", "KVO7AXZNFBUBPYLOTZQQ42TFNS", "WGJJ7SAEV6SBBWWYS4BTLD63WM", "Y6GURVDV4ESRBPWSTV25T4PE4K", "ESK7MPFPUZ5ZAQ52RP4SQIYCCC", "623M3CIABZ3RANERQ2IREXAVYO", "OQ4CQCFO42RS4BMMSGSDLUTOQO", "AMFHRDVGM6G2TIR3TKIFGFSDVM", "7VVSGGCVC53PLOYG7YHPFUJM5X", "Z3HMESVL7EZUSZNZ33WXEBHA2N", "AWWVRQD5W7IBSQPS26XOJVDV5H", "OQBZ5ZST3U3NZYHSIWRNROIG6L", "II573BW7DJLBYJSPSYIABQWDZD", "MOKXOQFOCUCLQQH4UKH2DPE7VN", "XR54NGUOU6BBUUTINNWBPJ35HX", "DNK36COZGFXI6DY7WLCNUETIRT", "R5M2PV7E3EHEM3TLGRCL3HSFMC", "ITKENZQYDQMZFCUPOT7VF3BMU7", "5GDCB74PPPHEP5N5G3DVRCYT7R", "ZMKXVRPLI5PY5BDVEPOA3NQZGN", "GBLIALWTHTUDTOMDERQFVB77CS", "VKRTTXUTFOK4PJAQQZCCT7TV3T", "ZJBUJJ4SW62BXOID3XO2W2M2PF", "SKWT5T6QJTCD3FCINIK22KMVBJ", "EHINNU6L33HRLOOJ3A2XFJSYQL", "N4HRQJEFPAT5SU3YPO74WSMQIR", "TGPTZ3ENMFWB5CZKJFR5WHIRI4", "O4HNFTAUJJ2LZPQXPXRAXOVABA", "4JVB5STP2YG5GYOXDWIF4KCKFB", "MY554X3YZHBECLHNNZ7A3SPJTU", "ASCJMAH7VCQAD2QJSWXPSVSM3H", "NBNGL5DZ623KCG2JNZFGZMZ7KD", "KGMZSW35AEQOJ6FA7IR7BHZI52", "Q7QUHHS4OJFMJ4I3FY6TDKSMZQ", "MZAE7TOEXAS76T7KIC73FEYRU4", "2BVESR3REAWADCGYOYM7T646RG", "EK3L2ORP4LT3HU3EMXDSQWFOKJ", "3X4A6VMGMIDLVK72FZSDHSERWY", "I3UHWI6M6HQFRBSQ6W2SABUNUP", "REKPXW4DIB4MTKMPHN3RBVHVME", "W37FNFZE35NX65Z7CVQ7L5U4L5", "4AGYK6U2KP6RAOADCBUDDCBECV", "IXM4SFQUDW2NOTXZIPWTNGET3F", "6YE4G3VELF27MN3Z5B4VIQ3XYK", "LPOZCPZAG3MD47MIWGR4FIOCDH", "WGREKUL2LD7C7SYGKH7APIY2A6", "WWW277FKTKUXQMP4BECSRHLWJI", "UYE4IQPMSTXVQG7EJALKWWEGDN", "TIV2L5Z6K7SNGNUVWSNKTAF4UE", "I3FQOAW3PINUK26P62HCX657FO", } var benchmarkMessagesMLDSA65 = []string{ "NDGEUBUDWGRJJ3A4UNZZQOEKNL", "ACGYQUXN4POOFUENCLNCIPHFAZ", "Z3XETEYKROVJH7SIHOIAYCTO42", "DXWCVCEFULV7XHRWHJWSEXWES7", "BCR2D5PNLGFYX6B3QFQFV23JZP", "2DVP5HNG54ES64QK4D37PWUYTJ", "UJM4ADPJLURAIQH4XA6QYUGNJ6", "B5WRCIPK5IVZW52R6TJOKNPKZH", "7QNL6JTSP62IGX6RCM2NHRMTKK", "EJSZQYLM7G7AJCGIEVBV2UW7NN", "UFNA2NKJ3QFWNHHL5CXZ4R5H46", "QZAXRTT3E4DOGVTJCOTBG3WXQV", "KH2ETOYZO5UHIHIKATWJMUVG27", "V5HVVQTOWRXZ2PB4XWXSEKXUN5", "5LA7NAFI2LESMH533XY45QVCQW", "SMF4TWPTMJA2Z4F4OVETTLVRAY", "FWZ5OJAFMLTQRREPYF4VDRPPGI", "OK3QMNO3OZSKSR6Q4BFVOVRWTH", "NQOVN6F6AOBOEGMJTVMF67KTIJ", "CCLC4Y6YT3AQ3HGT2QNSYAUGNV", "CAZJHCHBUYQ6OKZ7DMWMDDLIZQ", "LVW5XDTHPKOW5D452SYD7AFO6Q", "EYA6O6FTYPC6TRKZPRPX5N2KQ4", "Z6SGAEZ2SAAZHPQO7GL7CUMBAG", "FKUCKW6JQVF4WQYXUSXYZQMAVY", "LN2KDF4DANPE4SC4GKJ4BES3IZ", "AVCRTWB6ALOQHY34XI7NTMP2JH", "A5WHIS6CBWPCYIEC6N2MBAOEZ6", "JC2BH476BXUQFIDA6UCR5V4G4F", "NU6XH6VLSSFHVSRZCYXPFYKYCD", "GSUXVZBDDYSZYFGXNP6AZW3PTC", "XJPRNJ26XP4MIYH2Q7M7MPZ73M", "INUTUP3IRFWIIT23DNFTIYKCFY", "T4KH7HKLEYGXHBIRFGFCRUZCC4", "GGQX4JFVWZHE5Y73YTLMSSOXNS", "BUA4Q3TQZGLVHMMJU62GQOSHLV", "WXW3SJXLSZO2MYF4YFIMXL2IQP", "Q32XBVVGFQTSXAIDJE6XSEPRZG", "6TEXT6SA7INRCTDSCSVZJEQ2YG", "ZBN4UL43C3SJIG4HYR236PXCVS", "TVWPLLC7NROBREWOM75VA3XCR3", "CCDGL2FURLBABQ4IJBYCB75JFR", "XBZGCOVTZHCPAARBTMAKPIE6GJ", "TPRAENJ7I54XRIVH6LL6FDIA3I", "RKOM3PHFILPIIQZL4ILQWGRYWI", "CEEZIZ2WUXHQQFATYYGQ3ZDBTI", "SLKOVAP6WLIVJBVU7VZG3ZGEOW", "TWMCLJJSWEEQQPQGGDKEJ5SU2R", "IFMUXXCD2LC7IGQLZ2QEK5UOQ2", "C7IWFEBHW2CXN4XBJS7VLWH3VK", "7KJYUEW3F264727TM4LE6RMGDO", "BPG2XAPBMBTA4VMPUM7IZVZPK3", "Y5X577BWRZNPLNUHJVSKGMUXYB", "ZCKMKM23E4IUPTNQDFN2LTLZVX", "4RKK223JNBDAP4G5DOAHHZ3VNO", "5UZ3TQZHZT22ISTB4WJEVO6MC4", "YMVS4HFSJ32CRZRL23PXZUEJFJ", "UQEUJUTPSZLZARNBXWMCTMHPFF", "CZAAZ5WK7EIPMW7NA3EZNNBF45", "227PBHH23WM7F2QLEZSPFYXVW4", "YUYS2J5CRFXZ4J4KJT2ZKIZVW3", "MFLHZJOZV44SN4AH6OJ3QZWM2O", "H2B3CRBCXYN7QWDGYUPHQZP23A", "T4L6YWQUQ3CTACENAJ5WUXZWFH", "N723H6MUGPZSRZ72C635OD4BP7", "NI4TUMVA6LQPQV2TXPN4QOIGBZ", "CQI3S4LSTQASSJJVZXEFPOVW7K", "ANPY4HJ64LLSB3GK2R4C6WDBS3", "RGWQCZKQLMT5FZRDE4B3VMASVK", "Q3WCCF2HA3CA4WWRJBMGBW7WI7", "2AKJRXFHXLUQPOXPTLSZN5PW4A", "IJWOOTI4N7RWXJIHAPXN6KEWEN", "4D53T6N6ATOVTD4LKSTAAWBJMU", "B4G5HDD6RITG6NIH6FXCRZDYZM", "TJCDFKMRUY2OG6KRSMNVCGQFUP", "PB33IHQKALAY6H6GVBVLI6ZRXK", "SCCWGW2J5S4WL4FTTMQ435F6DB", "ZVJH2HSMTLHGXMGPMXLJCKCLLE", "62LG37U6JXR77YRZQQCDSBHVCS", "BU4CBWOXQ352TEOKIXO245ID4O", "UEZOH7KEIODSEVRUF6GMWGA2RB", "IPJWROME4GM66CGLUWP5BJ4SX6", "355GDC7TG64AZJ7IJX6K62KZCZ", "AHTFKX3V7XUB3EWOMQVCGZYGUE", "N4RV2GKXJ4SPHHJ52Z7K5EGLER", "ZY7V7NE5F66XHDHWM6YNFEWZA6", "DIKFO5KAVT4WAP7BOEFM56ZUSR", "4TDFOFKDAPIOM3MU5GD7NPXNWQ", "AD7YZO756HDK6YWFILAKW3JWA7", "NUA53JS2ZK2BGHH3A7BJTJZYW7", "QLCNC3AQNKLRMSYR62WQSQP5VI", "SJ7OBS7ZYXSGXOYXPE5KW2XKN6", "44HBMOGMIMJS63CEXQU7FCXE2E", "KCK3J7ZL6QF4SLHHSWTJURK7PG", "HLH4CLUGBSOOBSS3BPO62N5MC3", "3FNS4GITO6OEUBAVDDXK4WOBTD", "IAC3K3I4AQGY3G6UHG7PL2N6TE", "KUKLNH74POJI5DYAEWUD7RABTQ", "ETM6N7VU3GBSQ7P5MCD6UF3E3S", "IZITM5NYBGJZLSI3BI4VEMW43U", "46OPQU4LL6N3Z2U7KYPKUMBAGI", "EV7YZ5DMAV7VKYJQUFSRD37GPP", "AV7W2PGYDJIAKLFVEBL6BXQSGC", "M2FOX5QZEZKV4QXKPI5XUZDHEM", "R4IFPLVMOVYCHRTR6LXAUGP3LL", "JGH6XJUMP4DRVAM27P2JNOKXVO", "D2XN3ZLLU6VFPMDYM7NBHSQEOI", "2PO3BYENOMQK6SHQDCFSRPJQI3", "IBVQ7U3QEUC6PQRE4PV53JTZTK", "ZBCOX4P7NG2IXXFB2R43MG2SLV", "5NJDPQVVDO7ADNZ2CV7L6QBNGZ", "V7ASFIIYUMXFGW4B7ZM6LOGUTE", "PX5IJZ7W2LUPKM6YN4PMZ43ZLM", "AYK7SZ23DHC7Q56MWAJXBG76LB", "UYCAPXJM4HNGKLIDSZ4NCEDJLN", "UWMDZ3C2ODLACKGJPGETNQ3TA4", "Q6OI6R3WYYJ4CCZCDJBQMCRCZR", "LCMJHLP7354APCEGPKE7HHWTWB", "N7T7ZKOYPAMEYTTDOWZNCN6PRD", "UZADPU4UNHAF7L7LQDMTKA2EQH", "DC2OEPQDECVLRVNNCS6BMH4CRA", "37IZ427XHUMZ66EJ62U2YEZDAC", "6BCZDQZDPZLS5OGESKNUBPSSFV", "ST2LEMJ4OLQ32TJTLH2WCWT4WA", "GA2TL4SFLEW4G2B5PQMIKJT5XG", "L7PPBIET26EH7LQTLEFC4I4EIA", "6YSM7MC2W4DEV6ULAHMX27LH56", "QL26Z5KZ4YRRG2BXXGDRRLV357", "677TWRAJ5NSNHCE243POQPEG7K", "66MEBQJLGAGVXDX3KZ2YFTTVJM", "6D4VUWAQD6R65ICSDLFAATC67V", "7GXLD5CNU3TDUQSSW42SHL7B5D", "RQETUMEBG2ZM2NF2EZAQHGHWWE", "DCRX5ANWDMXZFIDVAXYLQZYMRN", "5SDWT7YAF7L4WWANAGYINZAYXH", "PZILRV7I2S6WKUSHKYRLA2JQY3", "2G66TK2PZ5MOTAZDN7BFS3LAIH", "QOLJ3WGJ6JS3FMMXBNTNAIKXVK", "FMAL67YTHDCCYVZ5CRMN2XJPDN", "UOTZDXTJKQ3YAIRKHTYNX6G55P", "X3DLNPJ3V62LRHGEY4DTT35H3R", "DKU7CHNXPB5QRZVGIQZW46XCKC", "RAKBD4LQKEDTVDSK3DVTRWG23B", "INTRA7BWHLVQMBRKBJNUSMF7MU", "AUYRBNVCOYYHOHUYOOFIZ2FWMD", "22EJVDEQ7PASLBAMTVKXOQP5RJ", "3S6NATWA57SFTZEW7UZUOUYAEU", } var benchmarkMessagesMLDSA87 = []string{ "LQQPGPNUME6QDNDTQTS4BA7I7M", "PTYEEJ7RMI6MXNN6PZH222Y6QI", "R6DTHAADKNMEADDK5ECPNOTOAT", "S2QM7VDC6UKRQNRETZMNAZ6SJT", "EYULPTSJORQJCNYNYVHDFN4N3F", "YETZNHZ75SXFU672VQ5WXYEPV2", "KTSND3JGA4AN3PCMG4455JEXGR", "JGE6HK37O6XMWZQZCHFUPNUEXP", "CRYB2FZD2BYNANBFFO2HRZEHGZ", "7MLNDZJ7OIEPBJZOMULOMQH2BA", "4WQCNTIFVSX2DNALMWUKZRA6CI", "Y5NK4OBDSDWC5WLL27CEEXYYOT", "C4SSWSPBVCDAWJXH2CDMXR36LH", "THDBKXRTKWJUGJMAAYTWTFMX7Z", "NWXPUD4DAA6QOREW4AFFYQYQNG", "3RQIJXMO7WYHBEBL3G6EOLNZNQ", "R7JEOHFP2C7O4AVPRPRELXWOMM", "LU6MWR7SZXVIKS54BY62X67NPA", "FG2FFM4F2ECKHCSJ75KXK632JP", "BF76ZDSVVUSYS5KK4FFD22YPS7", "HCLBWZRLHEMYZLFWHLAN2BKCZ7", "HGFVS4QC7AWXYPVRSWAK77KTQF", "LUZ3C53PUUHBWCDJ7WAHK2UT3K", "Y3WR6SMDUBW34N3MUT7EQYIJCV", "F2X35AQTXVZBMPXTWNAAH4ZX2W", "6MKFFDYWD6ZAKS3C6GRCRLZLRF", "AFMZYYFRHKMQRNKU5UTSKQ74H6", "TDTN7J3O367OVPWLESRNPLN4M2", "WYMLD2X6N4CZ2RDOKF5CFTSYTG", "UNPTSBLJ6HZRNR72T2VEEHCFX2", "SNCM4R2P27AJOXBS67RMCARS3U", "OU7QBE5QOXO7CIYTBJR3KOW2WK", "2NNQOBQKZ2OD4ZAXI3SNEURYUP", "YQTUPOYBT67XPCHIGKSGSKC3BZ", "HGB4ZM3G76IXYWWCMVT3HONRIS", "WZC6QUKRZZ2TOVA277JYKQITEW", "XO2WT46A5HYL6CUJF7SGJ6YWOG", "4QJA35PMYQIDRZ7ZHG7RLZJVGF", "BMJZELWZ4I2UWXESU3NR6ATC4M", "XWLFB7FN6D5PRY6YUXC5JUIBFM", "WRAFFF27AVTIOYIBYA2IPTXI3R", "VOXUTYTN2XZ362OJFO2R53UCUF", "UHN73ARJ737WUJ6QYEI7U46OPO", "3Y3K5E2A4ML3VYVNAFWEEIXTSN", "QMU4322NKPRLE7JBGYFGS36H2S", "NJAQTNCXPVDICTDVUKTPRCD2AX", "OC373ZFBNV2H46T6OY3XRPSUHG", "UBLAS6CDWE3A662MLKP7QDEOCC", "BKFDLAL2RTPMERYVW3B7UJ5W3H", "QFKFGXKGW5SAKLBAWQXUWW77OS", "EJNUQHTLLOVB4ARETOGLY4WUTJ", "N243OCMVLLAO6I2XLCYOIMQYGY", "YRRFLWK7ZASUKYX7ZLQMW2PJ6X", "3DGVPBWD2BIK6KQE65K72DNJNM", "TJRYMNOAIW33VIHKLJG4GXAVUK", "6DSRINAYXL34U54U355U7IVFGS", "6CHA4MX7LVS77XKRWG7IYC3XVL", "GM2CEGBEPBOHAPIOBUWJ4MJNTG", "VJKHGBY33VUIJFEQLX3JVUNQBD", "DTOHAD5M2KL46IZHE4TPLJWHTI", "IYFG3UDN7ROOY2ZFSLM2BU2LMQ", "A5OGJHPOE4PW6QSZYHZ5TKPGIC", "FX4BCN67AEGCLUTLFPNDL3SQU5", "MWIZQVOZOHTTBUXC3BEX62MNI5", "BYHVJHBLK4O6LFSKEIQ3CAAKU7", "QJU7P6KWSSKAA5GVA6RH4OV7MX", "I3T3XM5Z5TAJHAYDQHFA2ZV7PU", "L46MQCHV3TJ6FYIQQ2FCJXES74", "QXZRQIYAJMXYR6PU3VDYGCIT5W", "MFS53RR2XEYS22NYOJLGTHVTTM", "FRWIWJRP4AQMXWX4WJ4WYVKM3E", "X6GK6IGVLJWYSHLKHGXSW3TJDP", "L5LPJ2HIWA4UY6G6FMZXGDEDAM", "GD6FYOYUGDHXEQ5S2KLJEGNSN7", "ODAL7ZRKXSPAAN5DVRBWJQCFQX", "CV3QFBDXBPT3SCPJGUYSMDN6ZS", "IGSLSACRZ6XID466KQIB4YNGYO", "WZ2EACBN26RAML2S52YXRYP2OF", "LB76VEVNOBYFMKFZ7SDFCBCHQE", "TLFA7EU3JJFAP6EMUKNV2ZXRBM", "SIIJF6OXAKRP25CBUYFBRCDDVP", "TEPNI7TJ7HASJWIQMBS4VFLRQC", "VK2JINYWEDV7IQFWH4OTAD4W5O", "GILUH5AMVE4TM7EKPXJBZGT6EJ", "DV7ALFRAW3TI4WMQQLDTO6RNHN", "CAIB5G3NXC5ASPLFIWAFPVHS5B", "MLFJXZUOAGN7EGPMXOOVTB2CL4", "6MZYT3ANWHBOS67WGHZI3QPEAP", "LVJDQB52C2PERSSQJRMRCJ4UBF", "QY4VKAZAYQIZOX2L2VO2QHAQVC", "UAA5SST2XA76JPKM3XOZ5RUHFI", "VLZWF53JSQ6SCRUFDKVPXWAS4L", "NX2DZIKMJIYXUNSAHFP23FHTBU", "F5OAKDDDA34A2RPIKDPM5CYPMZ", "E5PEP3ANIK2L4VLOST4NIYNKBD", "IPBGFLHSMP4UFXF6XJX42T6CAL", "XHPU7DBFTZB2TX5K34AD6DJTK3", "2ZU7EJN2DG2UMT6HX5KGS2RFT6", "SD5S7U34WSE4GBPKVDUDZLBIEH", "WZFFL3BTQAV4VQMSAGCS45SGG3", "QE7ZT2LI4CA5DLSVMHV6CP3E3V", "YIWMS6AS72Z5N2ALZNFGCYC5QL", "A4QJ5FNY54THAKBOB65K2JBIV7", "6LORQGA3QO7TNADHEIINQZEE26", "5V45M6RAKOZDMONYY4DIH3ZBL2", "SVP7UYIZ5RTLWRKFLCWHAQV3Y2", "C2UYQL2BBE4VLUJ3IFNFMHAN7O", "P4DS44LGP2ERZB3OB7JISQKBXA", "A6B4O5MWALOEHLILSVDOIXHQ4Z", "DKQJTW5QF7KDZA3IR4X5R5F3CG", "H6QFQX2C2QTH3YKEOO57SQS23J", "DIF373ML2RWZMEOIVUHFXKUG7O", "Z5PPIA3GJ74QXFFCOSUAQMN5YN", "PM6XIDECSS5S77UXMB55VZHZSE", }