github.com/cloudflare/circl@v1.5.0/sign/dilithium/kat_test.go (about) 1 package dilithium 2 3 // Code to generate the NIST "PQCsignKAT" test vectors. 4 // See PQCsignKAT_sign.c and randombytes.c in the reference implementation. 5 6 import ( 7 "crypto/sha256" 8 "fmt" 9 "strings" 10 "testing" 11 12 "github.com/cloudflare/circl/internal/nist" 13 "github.com/cloudflare/circl/sign/schemes" 14 ) 15 16 func TestPQCgenKATSign(t *testing.T) { 17 for _, tc := range []struct { 18 name string 19 want string 20 }{ 21 // Generated from reference implementation commit 61b51a71701b8ae9f546a1e5, 22 // which can be found at https://github.com/pq-crystals/dilithium 23 {"Dilithium2", "38ed991c5ca11e39ab23945ca37af89e059d16c5474bf8ba96b15cb4e948af2a"}, 24 {"Dilithium3", "8196b32212753f525346201ffec1c7a0a852596fa0b57bd4e2746231dab44d55"}, 25 {"Dilithium5", "7ded97a6e6c809b43b54c248171d7504fa6a0cab651bf288bb00034782667481"}, 26 27 // Generated from reference implementation commit cbcd8753a43402885c90343c 28 // which can be found at https://github.com/pq-crystals/dilithium 29 // with the DILITHIUM_RANDOMIZED_SIGNING macro unset in ref/config.h 30 // to disable randomized signing. 31 {"ML-DSA-44", "14f92c48abc0d63ea263cce3c83183c8360c6ede7cbd5b65bd7c6f31e38f0ea5"}, 32 {"ML-DSA-65", "595a8eff6988159c94eb5398294458c5d27d21c994fb64cadbee339173abcf63"}, 33 {"ML-DSA-87", "35e2ce3d88b3311517bf8d41aa2cd24aa0fbda2bb8052ca8af4ad8d7c7344074"}, 34 } { 35 t.Run(tc.name, func(t *testing.T) { 36 mode := schemes.ByName(tc.name) 37 if mode == nil { 38 t.Fatal() 39 } 40 41 var seed [48]byte 42 var eseed [32]byte 43 for i := 0; i < 48; i++ { 44 seed[i] = byte(i) 45 } 46 f := sha256.New() 47 g := nist.NewDRBG(&seed) 48 nameInKat := tc.name 49 if !strings.HasPrefix(tc.name, "Dilithium") { 50 switch tc.name { 51 case "ML-DSA-44": 52 nameInKat = "Dilithium2" 53 case "ML-DSA-65": 54 nameInKat = "Dilithium3" 55 case "ML-DSA-87": 56 nameInKat = "Dilithium5" 57 } 58 } 59 fmt.Fprintf(f, "# %s\n\n", nameInKat) 60 for i := 0; i < 100; i++ { 61 mlen := 33 * (i + 1) 62 g.Fill(seed[:]) 63 msg := make([]byte, mlen) 64 g.Fill(msg[:]) 65 66 fmt.Fprintf(f, "count = %d\n", i) 67 fmt.Fprintf(f, "seed = %X\n", seed) 68 fmt.Fprintf(f, "mlen = %d\n", mlen) 69 fmt.Fprintf(f, "msg = %X\n", msg) 70 71 g2 := nist.NewDRBG(&seed) 72 g2.Fill(eseed[:]) 73 pk, sk := mode.DeriveKey(eseed[:]) 74 75 ppk, err := pk.MarshalBinary() 76 if err != nil { 77 t.Fatal(err) 78 } 79 psk, err := sk.MarshalBinary() 80 if err != nil { 81 t.Fatal(err) 82 } 83 84 fmt.Fprintf(f, "pk = %X\n", ppk) 85 fmt.Fprintf(f, "sk = %X\n", psk) 86 fmt.Fprintf(f, "smlen = %d\n", mlen+mode.SignatureSize()) 87 88 sig := mode.Sign(sk, msg[:], nil) 89 90 fmt.Fprintf(f, "sm = %X%X\n\n", sig, msg) 91 92 if !mode.Verify(pk, msg[:], sig, nil) { 93 t.Fatal() 94 } 95 } 96 if fmt.Sprintf("%x", f.Sum(nil)) != tc.want { 97 t.Fatal() 98 } 99 }) 100 } 101 }