github.com/cloudflare/circl@v1.5.0/sign/mldsa/mldsa87/acvp_test.go (about) 1 // Code generated from acvp.templ.go. DO NOT EDIT. 2 3 package mldsa87 4 5 import ( 6 "bytes" 7 "compress/gzip" 8 "encoding/hex" 9 "encoding/json" 10 "io" 11 "os" 12 "testing" 13 ) 14 15 // []byte but is encoded in hex for JSON 16 type HexBytes []byte 17 18 func (b HexBytes) MarshalJSON() ([]byte, error) { 19 return json.Marshal(hex.EncodeToString(b)) 20 } 21 22 func (b *HexBytes) UnmarshalJSON(data []byte) (err error) { 23 var s string 24 if err = json.Unmarshal(data, &s); err != nil { 25 return err 26 } 27 *b, err = hex.DecodeString(s) 28 return err 29 } 30 31 func gunzip(in []byte) ([]byte, error) { 32 buf := bytes.NewBuffer(in) 33 r, err := gzip.NewReader(buf) 34 if err != nil { 35 return nil, err 36 } 37 return io.ReadAll(r) 38 } 39 40 func readGzip(path string) ([]byte, error) { 41 buf, err := os.ReadFile(path) 42 if err != nil { 43 return nil, err 44 } 45 return gunzip(buf) 46 } 47 48 func TestACVP(t *testing.T) { 49 for _, sub := range []string{ 50 "keyGen", 51 "sigGen", 52 "sigVer", 53 } { 54 t.Run(sub, func(t *testing.T) { 55 testACVP(t, sub) 56 }) 57 } 58 } 59 60 // nolint:funlen,gocyclo 61 func testACVP(t *testing.T, sub string) { 62 buf, err := readGzip("../testdata/ML-DSA-" + sub + "-FIPS204/prompt.json.gz") 63 if err != nil { 64 t.Fatal(err) 65 } 66 67 var prompt struct { 68 TestGroups []json.RawMessage `json:"testGroups"` 69 } 70 71 if err = json.Unmarshal(buf, &prompt); err != nil { 72 t.Fatal(err) 73 } 74 75 buf, err = readGzip("../testdata/ML-DSA-" + sub + "-FIPS204/expectedResults.json.gz") 76 if err != nil { 77 t.Fatal(err) 78 } 79 80 var results struct { 81 TestGroups []json.RawMessage `json:"testGroups"` 82 } 83 84 if err := json.Unmarshal(buf, &results); err != nil { 85 t.Fatal(err) 86 } 87 88 rawResults := make(map[int]json.RawMessage) 89 90 for _, rawGroup := range results.TestGroups { 91 var abstractGroup struct { 92 Tests []json.RawMessage `json:"tests"` 93 } 94 if err := json.Unmarshal(rawGroup, &abstractGroup); err != nil { 95 t.Fatal(err) 96 } 97 for _, rawTest := range abstractGroup.Tests { 98 var abstractTest struct { 99 TcID int `json:"tcId"` 100 } 101 if err := json.Unmarshal(rawTest, &abstractTest); err != nil { 102 t.Fatal(err) 103 } 104 if _, exists := rawResults[abstractTest.TcID]; exists { 105 t.Fatalf("Duplicate test id: %d", abstractTest.TcID) 106 } 107 rawResults[abstractTest.TcID] = rawTest 108 } 109 } 110 111 scheme := Scheme() 112 113 for _, rawGroup := range prompt.TestGroups { 114 var abstractGroup struct { 115 TestType string `json:"testType"` 116 } 117 if err := json.Unmarshal(rawGroup, &abstractGroup); err != nil { 118 t.Fatal(err) 119 } 120 switch { 121 case abstractGroup.TestType == "AFT" && sub == "keyGen": 122 var group struct { 123 TgID int `json:"tgId"` 124 ParameterSet string `json:"parameterSet"` 125 Tests []struct { 126 TcID int `json:"tcId"` 127 Seed HexBytes `json:"seed"` 128 } 129 } 130 if err := json.Unmarshal(rawGroup, &group); err != nil { 131 t.Fatal(err) 132 } 133 134 if group.ParameterSet != scheme.Name() { 135 continue 136 } 137 138 for _, test := range group.Tests { 139 var result struct { 140 Pk HexBytes `json:"pk"` 141 Sk HexBytes `json:"sk"` 142 } 143 rawResult, ok := rawResults[test.TcID] 144 if !ok { 145 t.Fatalf("Missing result: %d", test.TcID) 146 } 147 if err := json.Unmarshal(rawResult, &result); err != nil { 148 t.Fatal(err) 149 } 150 151 pk, sk := scheme.DeriveKey(test.Seed) 152 153 pk2, err := scheme.UnmarshalBinaryPublicKey(result.Pk) 154 if err != nil { 155 t.Fatalf("tc=%d: %v", test.TcID, err) 156 } 157 sk2, err := scheme.UnmarshalBinaryPrivateKey(result.Sk) 158 if err != nil { 159 t.Fatal(err) 160 } 161 162 if !pk.Equal(pk2) { 163 t.Fatal("pk does not match") 164 } 165 if !sk.Equal(sk2) { 166 t.Fatal("sk does not match") 167 } 168 } 169 case abstractGroup.TestType == "AFT" && sub == "sigGen": 170 var group struct { 171 TgID int `json:"tgId"` 172 ParameterSet string `json:"parameterSet"` 173 Deterministic bool `json:"deterministic"` 174 Tests []struct { 175 TcID int `json:"tcId"` 176 Sk HexBytes `json:"sk"` 177 Message HexBytes `json:"message"` 178 Rnd HexBytes `json:"rnd"` 179 } 180 } 181 if err := json.Unmarshal(rawGroup, &group); err != nil { 182 t.Fatal(err) 183 } 184 185 if group.ParameterSet != scheme.Name() { 186 continue 187 } 188 189 for _, test := range group.Tests { 190 var result struct { 191 Signature HexBytes `json:"signature"` 192 } 193 rawResult, ok := rawResults[test.TcID] 194 if !ok { 195 t.Fatalf("Missing result: %d", test.TcID) 196 } 197 if err := json.Unmarshal(rawResult, &result); err != nil { 198 t.Fatal(err) 199 } 200 201 sk, err := scheme.UnmarshalBinaryPrivateKey(test.Sk) 202 if err != nil { 203 t.Fatal(err) 204 } 205 206 var rnd [32]byte 207 if !group.Deterministic { 208 copy(rnd[:], test.Rnd) 209 } 210 211 sig2 := sk.(*PrivateKey).unsafeSignInternal(test.Message, rnd) 212 213 if !bytes.Equal(sig2, result.Signature) { 214 t.Fatalf("signature doesn't match: %x ≠ %x", 215 sig2, result.Signature) 216 } 217 } 218 case abstractGroup.TestType == "AFT" && sub == "sigVer": 219 var group struct { 220 TgID int `json:"tgId"` 221 ParameterSet string `json:"parameterSet"` 222 Pk HexBytes `json:"pk"` 223 Tests []struct { 224 TcID int `json:"tcId"` 225 Message HexBytes `json:"message"` 226 Signature HexBytes `json:"signature"` 227 } 228 } 229 if err := json.Unmarshal(rawGroup, &group); err != nil { 230 t.Fatal(err) 231 } 232 233 if group.ParameterSet != scheme.Name() { 234 continue 235 } 236 237 pk, err := scheme.UnmarshalBinaryPublicKey(group.Pk) 238 if err != nil { 239 t.Fatal(err) 240 } 241 242 for _, test := range group.Tests { 243 var result struct { 244 TestPassed bool `json:"testPassed"` 245 } 246 rawResult, ok := rawResults[test.TcID] 247 if !ok { 248 t.Fatalf("Missing result: %d", test.TcID) 249 } 250 if err := json.Unmarshal(rawResult, &result); err != nil { 251 t.Fatal(err) 252 } 253 254 passed2 := unsafeVerifyInternal(pk.(*PublicKey), test.Message, test.Signature) 255 if passed2 != result.TestPassed { 256 t.Fatalf("verification %v ≠ %v", passed2, result.TestPassed) 257 } 258 } 259 default: 260 t.Fatalf("unknown type %s for %s", abstractGroup.TestType, sub) 261 } 262 } 263 }