github.com/klaytn/klaytn@v1.12.1/crypto/bls/blst/vector_test.go (about) 1 package blst 2 3 import ( 4 "archive/tar" 5 "compress/gzip" 6 "encoding/json" 7 "io" 8 "os" 9 "path" 10 "testing" 11 12 "github.com/klaytn/klaytn/common" 13 "github.com/stretchr/testify/assert" 14 ) 15 16 // Use the file downloaded according to https://github.com/ethereum/bls12-381-tests 17 // TESTS_VERSION=v0.1.2 18 // wget https://github.com/ethereum/bls12-381-tests/releases/download/${TESTS_VERSION}/bls_tests_json.tar.gz 19 20 type testVectorChecker func(t *testing.T, name string, vectorJson []byte) 21 22 func TestVectors(t *testing.T) { 23 checkers := map[string]testVectorChecker{ 24 "aggregate/": checkAggregate, 25 "batch_verify/": checkBatchVerify, 26 "deserialization_G1/": checkDeserializationG1, 27 "deserialization_G2/": checkDeserializationG2, 28 "fast_aggregate_verify/": checkFastAggregateVerify, 29 "sign/": checkSign, 30 "verify/": checkVerify, 31 } 32 33 // If some test vectors cannot pass, list below with a reason. 34 exemptions := map[string]bool{ 35 // PublicKeyFromBytes rejects inifinity point via KeyValidate() 36 "deserialization_G1/deserialization_succeeds_infinity_with_true_b_flag.json": true, 37 // AggregateVerify(asig, msgs, pks) not implemented 38 "aggregate_verify/aggregate_verify_infinity_pubkey.json": true, 39 "aggregate_verify/aggregate_verify_na_pubkeys_and_infinity_signature.json": true, 40 "aggregate_verify/aggregate_verify_na_pubkeys_and_na_signature.json": true, 41 "aggregate_verify/aggregate_verify_tampered_signature.json": true, 42 "aggregate_verify/aggregate_verify_valid.json": true, 43 // Low-level HashToG2 not implemented 44 "hash_to_G2/hash_to_G2__2782afaa8406d038.json": true, 45 "hash_to_G2/hash_to_G2__7590bd067999bbfb.json": true, 46 "hash_to_G2/hash_to_G2__a54942c8e365f378.json": true, 47 "hash_to_G2/hash_to_G2__c938b486cf69e8f7.json": true, 48 } 49 50 f, err := os.Open("./bls_tests_json.tar.gz") 51 if err != nil { 52 t.Fatal(err) 53 } 54 defer f.Close() 55 56 stream, err := gzip.NewReader(f) 57 reader := tar.NewReader(stream) 58 59 for { 60 header, err := reader.Next() 61 if err == io.EOF { 62 break 63 } else if err != nil { 64 t.Fatal(err) 65 } 66 67 switch header.Typeflag { 68 case tar.TypeReg: 69 name := path.Clean(header.Name) 70 dir, _ := path.Split(name) 71 if exemptions[name] { 72 t.Logf("skip %s", name) 73 continue 74 } 75 76 checker := checkers[dir] 77 if checker == nil { 78 t.Fatalf("unrecognized vector file: %s", header.Name) 79 // continue 80 } 81 82 data, err := io.ReadAll(reader) 83 if err != nil { 84 t.Fatal(err) 85 } 86 87 t.Logf("check %s", name) 88 checker(t, name, data) 89 } 90 } 91 } 92 93 func checkAggregate(t *testing.T, name string, vectorJson []byte) { 94 vector := struct { 95 Input []string 96 Output *string 97 }{} 98 if err := json.Unmarshal(vectorJson, &vector); err != nil { 99 t.Fatal(err) 100 } 101 102 sigbs := fromHexBatch(vector.Input) 103 asig, err := AggregateSignaturesFromBytes(sigbs) 104 if vector.Output != nil { 105 asigb := common.FromHex(*vector.Output) 106 assert.Nil(t, err) 107 assert.Equal(t, asigb, asig.Marshal()) 108 } else { 109 assert.NotNil(t, err) 110 } 111 } 112 113 func checkBatchVerify(t *testing.T, name string, vectorJson []byte) { 114 vector := struct { 115 Input struct { 116 Pubkeys []string 117 Messages []string 118 Signatures []string 119 } 120 Output bool 121 }{} 122 if err := json.Unmarshal(vectorJson, &vector); err != nil { 123 t.Fatal(err) 124 } 125 126 var ( 127 pkbs = fromHexBatch(vector.Input.Pubkeys) 128 msgs = fromHexBatch32(vector.Input.Messages) 129 sigbs = fromHexBatch(vector.Input.Signatures) 130 pks, err1 = MultiplePublicKeysFromBytes(pkbs) 131 ok, err2 = VerifyMultipleSignatures(sigbs, msgs, pks) 132 ) 133 if vector.Output == true { 134 assert.Nil(t, err1, name) 135 assert.Nil(t, err2, name) 136 assert.True(t, ok, name) 137 } else { 138 // At least an error or verify false. 139 assert.True(t, (err1 != nil || err2 != nil || !ok), name) 140 } 141 } 142 143 func checkFastAggregateVerify(t *testing.T, name string, vectorJson []byte) { 144 vector := struct { 145 Input struct { 146 Pubkeys []string 147 Message string 148 Signature string 149 } 150 Output bool 151 }{} 152 if err := json.Unmarshal(vectorJson, &vector); err != nil { 153 t.Fatal(err) 154 } 155 156 var ( 157 pkbs = fromHexBatch(vector.Input.Pubkeys) 158 msg = common.FromHex(vector.Input.Message) 159 sigb = common.FromHex(vector.Input.Signature) 160 apk, err1 = AggregatePublicKeysFromBytes(pkbs) 161 sig, err2 = SignatureFromBytes(sigb) 162 ok = false 163 ) 164 if err1 == nil && err2 == nil { 165 ok = Verify(sig, msg, apk) 166 } 167 168 if vector.Output == true { 169 assert.Nil(t, err1, name) 170 assert.Nil(t, err2, name) 171 assert.True(t, ok, name) 172 } else { 173 // At least an error or verify false. 174 assert.True(t, (err1 != nil || err2 != nil || !ok), name) 175 } 176 } 177 178 func checkDeserializationG1(t *testing.T, name string, vectorJson []byte) { 179 vector := struct { 180 Input struct{ Pubkey string } 181 Output bool 182 }{} 183 if err := json.Unmarshal(vectorJson, &vector); err != nil { 184 t.Fatal(err) 185 } 186 187 b := common.FromHex(vector.Input.Pubkey) 188 pk, err := PublicKeyFromBytes(b) 189 if vector.Output == true { 190 assert.Nil(t, err, name) 191 assert.Equal(t, b, pk.Marshal(), name) 192 } else { 193 assert.NotNil(t, err, name) 194 } 195 } 196 197 func checkDeserializationG2(t *testing.T, name string, vectorJson []byte) { 198 vector := struct { 199 Input struct{ Signature string } 200 Output bool 201 }{} 202 if err := json.Unmarshal(vectorJson, &vector); err != nil { 203 t.Fatal(err) 204 } 205 206 b := common.FromHex(vector.Input.Signature) 207 sig, err := SignatureFromBytes(b) 208 if vector.Output == true { 209 assert.Nil(t, err, name) 210 assert.Equal(t, b, sig.Marshal(), name) 211 } else { 212 assert.NotNil(t, err, name) 213 } 214 } 215 216 func checkSign(t *testing.T, name string, vectorJson []byte) { 217 vector := struct { 218 Input struct { 219 Privkey string 220 Message string 221 } 222 Output *string 223 }{} 224 if err := json.Unmarshal(vectorJson, &vector); err != nil { 225 t.Fatal(err) 226 } 227 228 skb := common.FromHex(vector.Input.Privkey) 229 msg := common.FromHex(vector.Input.Message) 230 231 sk, err := SecretKeyFromBytes(skb) 232 if vector.Output != nil { 233 sigb := common.FromHex(*vector.Output) 234 assert.Nil(t, err, name) 235 assert.Equal(t, sigb, Sign(sk, msg).Marshal(), name) 236 } else { 237 assert.NotNil(t, err, name) 238 } 239 } 240 241 func checkVerify(t *testing.T, name string, vectorJson []byte) { 242 vector := struct { 243 Input struct { 244 Pubkey string 245 Message string 246 Signature string 247 } 248 Output bool 249 }{} 250 if err := json.Unmarshal(vectorJson, &vector); err != nil { 251 t.Fatal(err) 252 } 253 254 var ( 255 pkb = common.FromHex(vector.Input.Pubkey) 256 msg = common.FromHex(vector.Input.Message) 257 sigb = common.FromHex(vector.Input.Signature) 258 pk, err1 = PublicKeyFromBytes(pkb) 259 sig, err2 = SignatureFromBytes(sigb) 260 ok = false 261 ) 262 if err1 == nil && err2 == nil { 263 ok = Verify(sig, msg, pk) 264 } 265 266 if vector.Output == true { 267 assert.Nil(t, err1, name) 268 assert.Nil(t, err2, name) 269 assert.True(t, ok, name) 270 } else { 271 // At least an error or verify false. 272 assert.True(t, (err1 != nil || err2 != nil || !ok), name) 273 } 274 } 275 276 func fromHexBatch(sArr []string) [][]byte { 277 bArr := make([][]byte, len(sArr)) 278 for i, s := range sArr { 279 bArr[i] = common.FromHex(s) 280 } 281 return bArr 282 } 283 284 func fromHexBatch32(sArr []string) [][32]byte { 285 bArr := make([][32]byte, len(sArr)) 286 for i, s := range sArr { 287 copy(bArr[i][:], common.FromHex(s)) 288 } 289 return bArr 290 }