upstream: https://github.com/mirage/mirage-crypto
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

refactor(crypto): merge ec_wycheproof into wycheproof library

Fold EC test vector logic into the wycheproof library, removing the
separate ec_wycheproof library. Reference changes from
Ec_wycheproof.suite to Wycheproof.suite.

+325 -318
+1 -2
test/dune
··· 9 9 ohex 10 10 fmt 11 11 test_common 12 - ec_wycheproof 13 - digestif) 12 + wycheproof) 14 13 (deps 15 14 ecdh_secp256r1_test.json 16 15 ecdsa_secp256r1_sha256_test.json
-4
test/ec/ec_wycheproof/dune
··· 1 - (library 2 - (name ec_wycheproof) 3 - (libraries alcotest wycheproof crypto-ec asn1-combinators digestif fmt) 4 - (optional))
-310
test/ec/ec_wycheproof/ec_wycheproof.ml
··· 1 - open Wycheproof 2 - open Crypto_ec 3 - open Result.Syntax 4 - 5 - let hex = Alcotest.testable Wycheproof.pp_hex Wycheproof.equal_hex 6 - 7 - module Asn = struct 8 - let parse_point curve s = 9 - let seq2 a b = Asn.S.(sequence2 (required a) (required b)) in 10 - let term = Asn.S.(seq2 (seq2 oid oid) bit_string_octets) in 11 - let ec_public_key = Asn.OID.(base 1 2 <|| [ 840; 10045; 2; 1 ]) in 12 - let prime_oid = 13 - match curve with 14 - | "secp256r1" -> Asn.OID.(base 1 2 <|| [ 840; 10045; 3; 1; 7 ]) 15 - | "secp384r1" -> Asn.OID.(base 1 3 <|| [ 132; 0; 34 ]) 16 - | "secp521r1" -> Asn.OID.(base 1 3 <|| [ 132; 0; 35 ]) 17 - | _ -> assert false 18 - in 19 - match Asn.decode (Asn.codec Asn.ber term) s with 20 - | Error _ -> Error "ASN1 parse error" 21 - | Ok (((oid1, oid2), data), rest) -> 22 - if String.length rest <> 0 then Error "ASN1 leftover" 23 - else if not (Asn.OID.equal oid1 ec_public_key) then 24 - Error "ASN1: wrong oid 1" 25 - else if not (Asn.OID.equal oid2 prime_oid) then 26 - Error "ASN1: wrong oid 2" 27 - else Ok data 28 - 29 - let parse_signature cs = 30 - let asn = 31 - Asn.S.(sequence2 (required unsigned_integer) (required unsigned_integer)) 32 - in 33 - match Asn.(decode (codec der asn) cs) with 34 - | Error _ -> Error "ASN1 parse error" 35 - | Ok (r_s, rest) -> 36 - if String.length rest <> 0 then Error "ASN1 leftover" else Ok r_s 37 - end 38 - 39 - let to_string_result ~pp_error = function 40 - | Ok _ as ok -> ok 41 - | Error e -> 42 - let msg = Format.asprintf "%a" pp_error e in 43 - Error msg 44 - 45 - let pad ~total_len buf = 46 - match total_len - String.length buf with 47 - | 0 -> Ok buf 48 - | n when n < 0 -> 49 - let is_zero = ref true in 50 - for i = 0 to abs n - 1 do 51 - if Bytes.(get_uint8 (Bytes.unsafe_of_string buf) i) <> 0 then 52 - is_zero := false 53 - done; 54 - if !is_zero then Ok (String.sub buf (abs n) total_len) 55 - else Error "input is too long" 56 - | pad_len -> Ok (String.make pad_len '\000' ^ buf) 57 - 58 - let len = function 59 - | "secp256r1" -> 32 60 - | "secp384r1" -> 48 61 - | "secp521r1" -> 66 62 - | _ -> assert false 63 - 64 - let parse_secret curve s = 65 - let total_len = len curve in 66 - pad ~total_len s 67 - 68 - type test = { public_key : string; raw_private_key : string; expected : string } 69 - 70 - let perform_key_exchange curve ~public_key ~raw_private_key = 71 - to_string_result ~pp_error 72 - (match curve with 73 - | "secp256r1" -> begin 74 - match P256.Dh.secret_of_octets raw_private_key with 75 - | Ok (p, _) -> P256.Dh.key_exchange p public_key 76 - | Error _ -> assert false 77 - end 78 - | "secp384r1" -> begin 79 - match P384.Dh.secret_of_octets raw_private_key with 80 - | Ok (p, _) -> P384.Dh.key_exchange p public_key 81 - | Error _ -> assert false 82 - end 83 - | "secp521r1" -> begin 84 - match P521.Dh.secret_of_octets raw_private_key with 85 - | Ok (p, _) -> P521.Dh.key_exchange p public_key 86 - | Error _ -> assert false 87 - end 88 - | _ -> assert false) 89 - 90 - let interpret_test ~tc_id curve { public_key; raw_private_key; expected } () = 91 - match perform_key_exchange curve ~public_key ~raw_private_key with 92 - | Ok got -> Alcotest.check hex __LOC__ expected got 93 - | Error err -> 94 - Printf.ksprintf 95 - (fun s -> Alcotest.fail s) 96 - "While parsing %d: %s" tc_id err 97 - 98 - type invalid_test = { public : string; private_ : string } 99 - 100 - let is_ok = function Ok _ -> true | Error _ -> false 101 - 102 - let interpret_invalid_test curve { public; private_ } () = 103 - let result = 104 - let* public_key = Asn.parse_point curve public in 105 - let* raw_private_key = parse_secret curve private_ in 106 - perform_key_exchange curve ~public_key ~raw_private_key 107 - in 108 - Alcotest.check Alcotest.bool __LOC__ false (is_ok result) 109 - 110 - type strategy = Test of test | Invalid_test of invalid_test | Skip 111 - 112 - let ecdh_test curve (test : ecdh_test) = 113 - let ignored_flags = [ "UnnamedCurve" ] in 114 - let curve_compression_test curve = 115 - let curves = [ "secp256r1"; "secp384r1"; "secp521r1" ] in 116 - test.tc_id = 2 && List.exists (fun x -> String.equal x curve) curves 117 - in 118 - match test.result with 119 - | _ when has_ignored_flag test ~ignored_flags -> Ok Skip 120 - | Invalid -> 121 - Ok (Invalid_test { public = test.public; private_ = test.private_ }) 122 - | Acceptable when curve_compression_test curve -> 123 - let* public_key = Asn.parse_point curve test.public in 124 - let* raw_private_key = parse_secret curve test.private_ in 125 - Ok (Test { public_key; raw_private_key; expected = test.shared }) 126 - | Acceptable -> Ok Skip 127 - | Valid -> 128 - let* public_key = Asn.parse_point curve test.public in 129 - let* raw_private_key = parse_secret curve test.private_ in 130 - Ok (Test { public_key; raw_private_key; expected = test.shared }) 131 - 132 - let to_ecdh_tests curve (x : ecdh_test) = 133 - let name = Printf.sprintf "%d - %s" x.tc_id x.comment in 134 - match ecdh_test curve x with 135 - | Ok (Test t) -> [ (name, `Quick, interpret_test ~tc_id:x.tc_id curve t) ] 136 - | Ok (Invalid_test t) -> [ (name, `Quick, interpret_invalid_test curve t) ] 137 - | Ok Skip -> [] 138 - | Error e -> Printf.ksprintf failwith "While parsing %d: %s" x.tc_id e 139 - 140 - let ecdh_tests file = 141 - let data = load_file_exn file in 142 - let groups : ecdh_test_group list = 143 - List.map ecdh_test_group_exn data.test_groups 144 - in 145 - List.concat_map 146 - (fun (group : ecdh_test_group) -> 147 - List.concat_map (to_ecdh_tests group.curve) group.tests) 148 - groups 149 - 150 - let ecdsa_test curve key hash (tst : dsa_test) = 151 - let name = Printf.sprintf "%d - %s" tst.tc_id tst.comment in 152 - let size = len curve in 153 - let msg = 154 - let dgst = 155 - match hash with 156 - | "SHA-256" -> Digestif.SHA256.(digest_string tst.msg |> to_raw_string) 157 - | "SHA-384" -> Digestif.SHA384.(digest_string tst.msg |> to_raw_string) 158 - | "SHA-512" -> Digestif.SHA512.(digest_string tst.msg |> to_raw_string) 159 - | "SHA-224" -> Digestif.SHA224.(digest_string tst.msg |> to_raw_string) 160 - | _ -> assert false 161 - in 162 - String.sub dgst 0 (min size (String.length dgst)) 163 - in 164 - let verified (r, s) = 165 - match curve with 166 - | "secp256r1" -> begin 167 - match P256.Dsa.pub_of_octets key with 168 - | Ok key -> P256.Dsa.verify ~key (r, s) msg 169 - | Error _ -> assert false 170 - end 171 - | "secp384r1" -> begin 172 - match P384.Dsa.pub_of_octets key with 173 - | Ok key -> P384.Dsa.verify ~key (r, s) msg 174 - | Error _ -> assert false 175 - end 176 - | "secp521r1" -> begin 177 - match P521.Dsa.pub_of_octets key with 178 - | Ok key -> P521.Dsa.verify ~key (r, s) msg 179 - | Error _ -> assert false 180 - end 181 - | _ -> assert false 182 - in 183 - match tst.result with 184 - | Acceptable | Invalid -> 185 - let f () = 186 - match Asn.parse_signature tst.sig_ with 187 - | Ok (r, s) -> Alcotest.(check bool __LOC__ false (verified (r, s))) 188 - | Error _s -> () 189 - in 190 - (name, `Quick, f) 191 - | Valid -> 192 - let f () = 193 - match Asn.parse_signature tst.sig_ with 194 - | Ok (r, s) -> Alcotest.(check bool __LOC__ true (verified (r, s))) 195 - | Error s -> Alcotest.fail s 196 - in 197 - (name, `Quick, f) 198 - 199 - let to_ecdsa_tests (x : ecdsa_test_group) = 200 - List.map (ecdsa_test x.key.curve x.key.uncompressed x.sha) x.tests 201 - 202 - let ecdsa_tests file = 203 - let data = load_file_exn file in 204 - let groups : ecdsa_test_group list = 205 - List.map ecdsa_test_group_exn data.test_groups 206 - in 207 - List.concat_map to_ecdsa_tests groups 208 - 209 - let to_x25519_test (x : ecdh_test) = 210 - let name = Printf.sprintf "%d - %s" x.tc_id x.comment 211 - and priv = 212 - match X25519.secret_of_octets x.private_ with 213 - | Ok (p, _) -> p 214 - | Error _ -> assert false 215 - in 216 - match x.result with 217 - | Acceptable -> 218 - let f () = 219 - match 220 - ( X25519.key_exchange priv x.public, 221 - has_ignored_flag x ~ignored_flags:[ "LowOrderPublic" ] ) 222 - with 223 - | Ok _, true -> Alcotest.fail "acceptable should have errored" 224 - | Ok r, false -> 225 - Alcotest.(check bool __LOC__ true (String.equal r x.shared)) 226 - | Error _, true -> () 227 - | Error e, false -> Alcotest.failf "acceptable errored %a" pp_error e 228 - in 229 - (name, `Quick, f) 230 - | Invalid -> 231 - let f () = 232 - match X25519.key_exchange priv x.public with 233 - | Ok r -> Alcotest.(check bool __LOC__ false (String.equal r x.shared)) 234 - | Error e -> Alcotest.failf "invalid errored %a" pp_error e 235 - in 236 - (name, `Quick, f) 237 - | Valid -> 238 - let f () = 239 - match X25519.key_exchange priv x.public with 240 - | Ok r -> Alcotest.(check bool __LOC__ true (String.equal r x.shared)) 241 - | Error e -> Alcotest.failf "valid errored %a" pp_error e 242 - in 243 - (name, `Quick, f) 244 - 245 - let x25519_tests = 246 - let data = load_file_exn "x25519_test.json" in 247 - let groups : ecdh_test_group list = 248 - List.map ecdh_test_group_exn data.test_groups 249 - in 250 - List.concat_map 251 - (fun (group : ecdh_test_group) -> List.map to_x25519_test group.tests) 252 - groups 253 - 254 - let to_ed25519_test (priv, pub) (x : dsa_test) = 255 - let name = Printf.sprintf "%d - %s" x.tc_id x.comment in 256 - match x.result with 257 - | Invalid -> 258 - let f () = 259 - Alcotest.( 260 - check bool __LOC__ false (Ed25519.verify ~key:pub x.sig_ ~msg:x.msg)); 261 - let s = Ed25519.sign ~key:priv x.msg in 262 - Alcotest.(check bool __LOC__ false (String.equal s x.sig_)) 263 - in 264 - (name, `Quick, f) 265 - | Valid -> 266 - let f () = 267 - Alcotest.( 268 - check bool __LOC__ true (Ed25519.verify ~key:pub x.sig_ ~msg:x.msg)); 269 - let s = Ed25519.sign ~key:priv x.msg in 270 - Alcotest.(check bool __LOC__ true (String.equal s x.sig_)) 271 - in 272 - (name, `Quick, f) 273 - | Acceptable -> assert false 274 - 275 - let to_ed25519_keys (key : eddsa_key) = 276 - match (Ed25519.priv_of_octets key.sk, Ed25519.pub_of_octets key.pk) with 277 - | Ok priv, Ok pub -> 278 - assert (String.equal Ed25519.(pub_to_octets (pub_of_priv priv)) key.pk); 279 - (priv, pub) 280 - | _ -> assert false 281 - 282 - let ed25519_tests = 283 - let data = load_file_exn "eddsa_test.json" in 284 - let groups : eddsa_test_group list = 285 - List.map eddsa_test_group_exn data.test_groups 286 - in 287 - List.concat_map 288 - (fun (group : eddsa_test_group) -> 289 - let keys = to_ed25519_keys group.key in 290 - List.map (to_ed25519_test keys) group.tests) 291 - groups 292 - 293 - let suite = 294 - [ 295 - ("ECDH P256 test vectors", ecdh_tests "ecdh_secp256r1_test.json"); 296 - ( "ECDSA P256 test vectors (SHA256)", 297 - ecdsa_tests "ecdsa_secp256r1_sha256_test.json" ); 298 - ( "ECDSA P256 test vectors (SHA512)", 299 - ecdsa_tests "ecdsa_secp256r1_sha512_test.json" ); 300 - ("ECDH P384 test vectors", ecdh_tests "ecdh_secp384r1_test.json"); 301 - ( "ECDSA P384 test vectors (SHA384)", 302 - ecdsa_tests "ecdsa_secp384r1_sha384_test.json" ); 303 - ( "ECDSA P384 test vectors (SHA512)", 304 - ecdsa_tests "ecdsa_secp384r1_sha512_test.json" ); 305 - ("ECDH P521 test vectors", ecdh_tests "ecdh_secp521r1_test.json"); 306 - ( "ECDSA P521 test vectors (SHA512)", 307 - ecdsa_tests "ecdsa_secp521r1_sha512_test.json" ); 308 - ("X25519 test vectors", x25519_tests); 309 - ("ED25519 test vectors", ed25519_tests); 310 - ]
+8 -1
test/ec/wycheproof/dune
··· 1 1 (library 2 2 (name wycheproof) 3 - (libraries fmt jsont jsont.bytesrw) 3 + (libraries 4 + alcotest 5 + fmt 6 + jsont 7 + jsont.bytesrw 8 + crypto-ec 9 + asn1-combinators 10 + digestif) 4 11 (optional))
+312
test/ec/wycheproof/wycheproof.ml
··· 385 385 match Jsont_bytesrw.encode_string Jsont.json json with 386 386 | Error _ -> failwith "eddsa_test_group_exn: encode failed" 387 387 | Ok s -> Jsont_bytesrw.decode_string eddsa_test_group_jsont s |> result 388 + 389 + (* -- EC test vectors ---------------------------------------------------- *) 390 + 391 + open Crypto_ec 392 + open Result.Syntax 393 + 394 + let hex = Alcotest.testable pp_hex equal_hex 395 + 396 + module Asn = struct 397 + let parse_point curve s = 398 + let seq2 a b = Asn.S.(sequence2 (required a) (required b)) in 399 + let term = Asn.S.(seq2 (seq2 oid oid) bit_string_octets) in 400 + let ec_public_key = Asn.OID.(base 1 2 <|| [ 840; 10045; 2; 1 ]) in 401 + let prime_oid = 402 + match curve with 403 + | "secp256r1" -> Asn.OID.(base 1 2 <|| [ 840; 10045; 3; 1; 7 ]) 404 + | "secp384r1" -> Asn.OID.(base 1 3 <|| [ 132; 0; 34 ]) 405 + | "secp521r1" -> Asn.OID.(base 1 3 <|| [ 132; 0; 35 ]) 406 + | _ -> assert false 407 + in 408 + match Asn.decode (Asn.codec Asn.ber term) s with 409 + | Error _ -> Error "ASN1 parse error" 410 + | Ok (((oid1, oid2), data), rest) -> 411 + if String.length rest <> 0 then Error "ASN1 leftover" 412 + else if not (Asn.OID.equal oid1 ec_public_key) then 413 + Error "ASN1: wrong oid 1" 414 + else if not (Asn.OID.equal oid2 prime_oid) then 415 + Error "ASN1: wrong oid 2" 416 + else Ok data 417 + 418 + let parse_signature cs = 419 + let asn = 420 + Asn.S.(sequence2 (required unsigned_integer) (required unsigned_integer)) 421 + in 422 + match Asn.(decode (codec der asn) cs) with 423 + | Error _ -> Error "ASN1 parse error" 424 + | Ok (r_s, rest) -> 425 + if String.length rest <> 0 then Error "ASN1 leftover" else Ok r_s 426 + end 427 + 428 + let to_string_result ~pp_error = function 429 + | Ok _ as ok -> ok 430 + | Error e -> 431 + let msg = Format.asprintf "%a" pp_error e in 432 + Error msg 433 + 434 + let pad ~total_len buf = 435 + match total_len - String.length buf with 436 + | 0 -> Ok buf 437 + | n when n < 0 -> 438 + let is_zero = ref true in 439 + for i = 0 to abs n - 1 do 440 + if Bytes.(get_uint8 (Bytes.unsafe_of_string buf) i) <> 0 then 441 + is_zero := false 442 + done; 443 + if !is_zero then Ok (String.sub buf (abs n) total_len) 444 + else Error "input is too long" 445 + | pad_len -> Ok (String.make pad_len '\000' ^ buf) 446 + 447 + let len = function 448 + | "secp256r1" -> 32 449 + | "secp384r1" -> 48 450 + | "secp521r1" -> 66 451 + | _ -> assert false 452 + 453 + let parse_secret curve s = 454 + let total_len = len curve in 455 + pad ~total_len s 456 + 457 + type test = { public_key : string; raw_private_key : string; expected : string } 458 + 459 + let perform_key_exchange curve ~public_key ~raw_private_key = 460 + to_string_result ~pp_error 461 + (match curve with 462 + | "secp256r1" -> begin 463 + match P256.Dh.secret_of_octets raw_private_key with 464 + | Ok (p, _) -> P256.Dh.key_exchange p public_key 465 + | Error _ -> assert false 466 + end 467 + | "secp384r1" -> begin 468 + match P384.Dh.secret_of_octets raw_private_key with 469 + | Ok (p, _) -> P384.Dh.key_exchange p public_key 470 + | Error _ -> assert false 471 + end 472 + | "secp521r1" -> begin 473 + match P521.Dh.secret_of_octets raw_private_key with 474 + | Ok (p, _) -> P521.Dh.key_exchange p public_key 475 + | Error _ -> assert false 476 + end 477 + | _ -> assert false) 478 + 479 + let interpret_test ~tc_id curve { public_key; raw_private_key; expected } () = 480 + match perform_key_exchange curve ~public_key ~raw_private_key with 481 + | Ok got -> Alcotest.check hex __LOC__ expected got 482 + | Error err -> 483 + Printf.ksprintf 484 + (fun s -> Alcotest.fail s) 485 + "While parsing %d: %s" tc_id err 486 + 487 + type invalid_test = { public : string; private_ : string } 488 + 489 + let is_ok = function Ok _ -> true | Error _ -> false 490 + 491 + let interpret_invalid_test curve { public; private_ } () = 492 + let result = 493 + let* public_key = Asn.parse_point curve public in 494 + let* raw_private_key = parse_secret curve private_ in 495 + perform_key_exchange curve ~public_key ~raw_private_key 496 + in 497 + Alcotest.check Alcotest.bool __LOC__ false (is_ok result) 498 + 499 + type strategy = Test of test | Invalid_test of invalid_test | Skip 500 + 501 + let ecdh_test curve (test : ecdh_test) = 502 + let ignored_flags = [ "UnnamedCurve" ] in 503 + let curve_compression_test curve = 504 + let curves = [ "secp256r1"; "secp384r1"; "secp521r1" ] in 505 + test.tc_id = 2 && List.exists (fun x -> String.equal x curve) curves 506 + in 507 + match test.result with 508 + | _ when has_ignored_flag test ~ignored_flags -> Ok Skip 509 + | Invalid -> 510 + Ok (Invalid_test { public = test.public; private_ = test.private_ }) 511 + | Acceptable when curve_compression_test curve -> 512 + let* public_key = Asn.parse_point curve test.public in 513 + let* raw_private_key = parse_secret curve test.private_ in 514 + Ok (Test { public_key; raw_private_key; expected = test.shared }) 515 + | Acceptable -> Ok Skip 516 + | Valid -> 517 + let* public_key = Asn.parse_point curve test.public in 518 + let* raw_private_key = parse_secret curve test.private_ in 519 + Ok (Test { public_key; raw_private_key; expected = test.shared }) 520 + 521 + let to_ecdh_tests curve (x : ecdh_test) = 522 + let name = Printf.sprintf "%d - %s" x.tc_id x.comment in 523 + match ecdh_test curve x with 524 + | Ok (Test t) -> [ (name, `Quick, interpret_test ~tc_id:x.tc_id curve t) ] 525 + | Ok (Invalid_test t) -> [ (name, `Quick, interpret_invalid_test curve t) ] 526 + | Ok Skip -> [] 527 + | Error e -> Printf.ksprintf failwith "While parsing %d: %s" x.tc_id e 528 + 529 + let ecdh_tests file = 530 + let data = load_file_exn file in 531 + let groups : ecdh_test_group list = 532 + List.map ecdh_test_group_exn data.test_groups 533 + in 534 + List.concat_map 535 + (fun (group : ecdh_test_group) -> 536 + List.concat_map (to_ecdh_tests group.curve) group.tests) 537 + groups 538 + 539 + let ecdsa_test curve key hash (tst : dsa_test) = 540 + let name = Printf.sprintf "%d - %s" tst.tc_id tst.comment in 541 + let size = len curve in 542 + let msg = 543 + let dgst = 544 + match hash with 545 + | "SHA-256" -> Digestif.SHA256.(digest_string tst.msg |> to_raw_string) 546 + | "SHA-384" -> Digestif.SHA384.(digest_string tst.msg |> to_raw_string) 547 + | "SHA-512" -> Digestif.SHA512.(digest_string tst.msg |> to_raw_string) 548 + | "SHA-224" -> Digestif.SHA224.(digest_string tst.msg |> to_raw_string) 549 + | _ -> assert false 550 + in 551 + String.sub dgst 0 (min size (String.length dgst)) 552 + in 553 + let verified (r, s) = 554 + match curve with 555 + | "secp256r1" -> begin 556 + match P256.Dsa.pub_of_octets key with 557 + | Ok key -> P256.Dsa.verify ~key (r, s) msg 558 + | Error _ -> assert false 559 + end 560 + | "secp384r1" -> begin 561 + match P384.Dsa.pub_of_octets key with 562 + | Ok key -> P384.Dsa.verify ~key (r, s) msg 563 + | Error _ -> assert false 564 + end 565 + | "secp521r1" -> begin 566 + match P521.Dsa.pub_of_octets key with 567 + | Ok key -> P521.Dsa.verify ~key (r, s) msg 568 + | Error _ -> assert false 569 + end 570 + | _ -> assert false 571 + in 572 + match tst.result with 573 + | Acceptable | Invalid -> 574 + let f () = 575 + match Asn.parse_signature tst.sig_ with 576 + | Ok (r, s) -> Alcotest.(check bool __LOC__ false (verified (r, s))) 577 + | Error _s -> () 578 + in 579 + (name, `Quick, f) 580 + | Valid -> 581 + let f () = 582 + match Asn.parse_signature tst.sig_ with 583 + | Ok (r, s) -> Alcotest.(check bool __LOC__ true (verified (r, s))) 584 + | Error s -> Alcotest.fail s 585 + in 586 + (name, `Quick, f) 587 + 588 + let to_ecdsa_tests (x : ecdsa_test_group) = 589 + List.map (ecdsa_test x.key.curve x.key.uncompressed x.sha) x.tests 590 + 591 + let ecdsa_tests file = 592 + let data = load_file_exn file in 593 + let groups : ecdsa_test_group list = 594 + List.map ecdsa_test_group_exn data.test_groups 595 + in 596 + List.concat_map to_ecdsa_tests groups 597 + 598 + let to_x25519_test (x : ecdh_test) = 599 + let name = Printf.sprintf "%d - %s" x.tc_id x.comment 600 + and priv = 601 + match X25519.secret_of_octets x.private_ with 602 + | Ok (p, _) -> p 603 + | Error _ -> assert false 604 + in 605 + match x.result with 606 + | Acceptable -> 607 + let f () = 608 + match 609 + ( X25519.key_exchange priv x.public, 610 + has_ignored_flag x ~ignored_flags:[ "LowOrderPublic" ] ) 611 + with 612 + | Ok _, true -> Alcotest.fail "acceptable should have errored" 613 + | Ok r, false -> 614 + Alcotest.(check bool __LOC__ true (String.equal r x.shared)) 615 + | Error _, true -> () 616 + | Error e, false -> Alcotest.failf "acceptable errored %a" pp_error e 617 + in 618 + (name, `Quick, f) 619 + | Invalid -> 620 + let f () = 621 + match X25519.key_exchange priv x.public with 622 + | Ok r -> Alcotest.(check bool __LOC__ false (String.equal r x.shared)) 623 + | Error e -> Alcotest.failf "invalid errored %a" pp_error e 624 + in 625 + (name, `Quick, f) 626 + | Valid -> 627 + let f () = 628 + match X25519.key_exchange priv x.public with 629 + | Ok r -> Alcotest.(check bool __LOC__ true (String.equal r x.shared)) 630 + | Error e -> Alcotest.failf "valid errored %a" pp_error e 631 + in 632 + (name, `Quick, f) 633 + 634 + let x25519_tests = 635 + let data = load_file_exn "x25519_test.json" in 636 + let groups : ecdh_test_group list = 637 + List.map ecdh_test_group_exn data.test_groups 638 + in 639 + List.concat_map 640 + (fun (group : ecdh_test_group) -> List.map to_x25519_test group.tests) 641 + groups 642 + 643 + let to_ed25519_test (priv, pub) (x : dsa_test) = 644 + let name = Printf.sprintf "%d - %s" x.tc_id x.comment in 645 + match x.result with 646 + | Invalid -> 647 + let f () = 648 + Alcotest.( 649 + check bool __LOC__ false (Ed25519.verify ~key:pub x.sig_ ~msg:x.msg)); 650 + let s = Ed25519.sign ~key:priv x.msg in 651 + Alcotest.(check bool __LOC__ false (String.equal s x.sig_)) 652 + in 653 + (name, `Quick, f) 654 + | Valid -> 655 + let f () = 656 + Alcotest.( 657 + check bool __LOC__ true (Ed25519.verify ~key:pub x.sig_ ~msg:x.msg)); 658 + let s = Ed25519.sign ~key:priv x.msg in 659 + Alcotest.(check bool __LOC__ true (String.equal s x.sig_)) 660 + in 661 + (name, `Quick, f) 662 + | Acceptable -> assert false 663 + 664 + let to_ed25519_keys (key : eddsa_key) = 665 + match (Ed25519.priv_of_octets key.sk, Ed25519.pub_of_octets key.pk) with 666 + | Ok priv, Ok pub -> 667 + assert (String.equal Ed25519.(pub_to_octets (pub_of_priv priv)) key.pk); 668 + (priv, pub) 669 + | _ -> assert false 670 + 671 + let ed25519_tests = 672 + let data = load_file_exn "eddsa_test.json" in 673 + let groups : eddsa_test_group list = 674 + List.map eddsa_test_group_exn data.test_groups 675 + in 676 + List.concat_map 677 + (fun (group : eddsa_test_group) -> 678 + let keys = to_ed25519_keys group.key in 679 + List.map (to_ed25519_test keys) group.tests) 680 + groups 681 + 682 + let suite = 683 + [ 684 + ("ECDH P256 test vectors", ecdh_tests "ecdh_secp256r1_test.json"); 685 + ( "ECDSA P256 test vectors (SHA256)", 686 + ecdsa_tests "ecdsa_secp256r1_sha256_test.json" ); 687 + ( "ECDSA P256 test vectors (SHA512)", 688 + ecdsa_tests "ecdsa_secp256r1_sha512_test.json" ); 689 + ("ECDH P384 test vectors", ecdh_tests "ecdh_secp384r1_test.json"); 690 + ( "ECDSA P384 test vectors (SHA384)", 691 + ecdsa_tests "ecdsa_secp384r1_sha384_test.json" ); 692 + ( "ECDSA P384 test vectors (SHA512)", 693 + ecdsa_tests "ecdsa_secp384r1_sha512_test.json" ); 694 + ("ECDH P521 test vectors", ecdh_tests "ecdh_secp521r1_test.json"); 695 + ( "ECDSA P521 test vectors (SHA512)", 696 + ecdsa_tests "ecdsa_secp521r1_sha512_test.json" ); 697 + ("X25519 test vectors", x25519_tests); 698 + ("ED25519 test vectors", ed25519_tests); 699 + ]
+3
test/ec/wycheproof/wycheproof.mli
··· 162 162 163 163 val eddsa_test_group_exn : json -> eddsa_test_group 164 164 (** [eddsa_test_group_exn json] extracts an EdDSA test group from [json]. *) 165 + 166 + val suite : (string * unit Alcotest.test_case list) list 167 + (** Wycheproof EC test vector suites. *)
+1 -1
test/test_crypto_ec.ml
··· 1150 1150 point_module_tests (module P256) "P256"; 1151 1151 point_module_tests (module P384) "P384"; 1152 1152 point_module_tests (module P521) "P521"; 1153 - List.concat_map snd Ec_wycheproof.suite; 1153 + List.concat_map snd Wycheproof.suite; 1154 1154 ] )