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

Merge pull request #268 from ansiwen/fix-compression

mirage-crypto-ec: fix ECDSA public key compression

authored by

Hannes Mehnert and committed by
GitHub
755bc2fb eeafba3b

+21 -43
+2 -2
ec/mirage_crypto_ec.ml
··· 317 317 if compress then 318 318 let out = Bytes.create (P.byte_length + 1) in 319 319 let ident = 320 - 2 + (String.get_uint8 buf ((P.byte_length * 2) - 1)) land 1 320 + 2 + (String.get_uint8 buf (P.byte_length * 2)) land 1 321 321 in 322 322 Bytes.unsafe_blit_string buf 1 out 1 P.byte_length; 323 323 Bytes.set_uint8 out 0 ident; ··· 388 388 let y_struct2 = rev_string y_struct2 in 389 389 let ident = String.get_uint8 pk 0 in 390 390 let signY = 391 - 2 + (String.get_uint8 y_struct (P.byte_length - 2)) land 1 391 + 2 + (String.get_uint8 y_struct (P.byte_length - 1)) land 1 392 392 in 393 393 let res = if Int.equal signY ident then y_struct else y_struct2 in 394 394 let out = Bytes.create ((P.byte_length * 2) + 1) in
+19 -41
tests/test_ec.ml
··· 216 216 "ECDSA verify", `Quick, ecdsa_verify ; 217 217 ] 218 218 219 + let pub_key_compression (module Dsa:Mirage_crypto_ec.Dsa) () = 220 + for _ = 1 to 20 do 221 + let _, pub = Dsa.generate () in 222 + let compressed = Dsa.pub_to_octets ~compress:true pub in 223 + let decompressed = Dsa.pub_of_octets compressed in 224 + match decompressed with 225 + | Ok decompressed -> 226 + let p1 = Dsa.pub_to_octets pub in 227 + let p2 = Dsa.pub_to_octets decompressed in 228 + Alcotest.(check string __LOC__ p1 p2); 229 + let prefix = String.get_uint8 compressed 0 in 230 + let expected = 2 + String.(get_uint8 p1 (length p1 - 1)) land 1 in 231 + Alcotest.(check int __LOC__ expected prefix); 232 + | Error e -> Alcotest.failf "%a" pp_error e 233 + done 234 + 219 235 let ecdsa_rfc6979_p256 = 220 236 (* A.2.5 - P 256 *) 221 237 let priv, pub = ··· 236 252 in 237 253 Alcotest.(check bool __LOC__ true pub_eq) 238 254 | Error _ -> Alcotest.fail "bad public key" 239 - in 240 - let pub_key_compression () = 241 - let _, pub = P256.Dsa.generate () in 242 - let compressed = P256.Dsa.pub_to_octets ~compress:true pub in 243 - let decompressed = P256.Dsa.pub_of_octets compressed in 244 - let comparison = match decompressed with 245 - | Ok decompressed -> 246 - let p1 = P256.Dsa.pub_to_octets pub in 247 - let p2 = P256.Dsa.pub_to_octets decompressed in 248 - String.equal p1 p2 249 - | Error _ -> false in 250 - Alcotest.(check bool __LOC__ true comparison) 251 255 in 252 256 let case (type a) (hash : a Digestif.hash) ~message ~k ~r ~s () = 253 257 let msg = ··· 310 314 ~s:"39AF9F15DE0DB8D97E72719C74820D304CE5226E32DEDAE67519E840D1194E55" ; 311 315 ] in 312 316 ("public key matches", `Quick, pub_rfc) :: 313 - ("public key compression and decompression", `Quick, pub_key_compression) :: 317 + ("public key compression and decompression", `Quick, (pub_key_compression (module P256.Dsa))) :: 314 318 List.mapi (fun i c -> "RFC 6979 A.2.5 " ^ string_of_int i, `Quick, c) cases 315 319 316 320 let ecdsa_rfc6979_p384 = ··· 334 338 Alcotest.(check bool __LOC__ true pub_eq) 335 339 | Error _ -> Alcotest.fail "bad public key" 336 340 in 337 - let pub_key_compression () = 338 - let _, pub = P384.Dsa.generate () in 339 - let compressed = P384.Dsa.pub_to_octets ~compress:true pub in 340 - let decompressed = P384.Dsa.pub_of_octets compressed in 341 - let comparison = match decompressed with 342 - | Ok decompressed -> 343 - let p1 = P384.Dsa.pub_to_octets pub in 344 - let p2 = P384.Dsa.pub_to_octets decompressed in 345 - String.equal p1 p2 346 - | Error _ -> false 347 - in 348 - Alcotest.(check bool __LOC__ true comparison) 349 - in 350 341 let case (type a) (hash : a Digestif.hash) ~message ~k ~r ~s () = 351 342 let msg = 352 343 let h = Digestif.(digest_string hash message |> to_raw_string hash) in ··· 447 438 4A2092CD3792E0159AD9CEE37659C736" 448 439 ] in 449 440 ("public key matches", `Quick, pub_rfc) :: 450 - ("public key compression and decompression", `Quick, pub_key_compression) :: 441 + ("public key compression and decompression", `Quick, pub_key_compression (module P384.Dsa)) :: 451 442 List.mapi (fun i c -> "RFC 6979 A.2.6 " ^ string_of_int i, `Quick, c) cases 452 443 453 444 let ecdsa_rfc6979_p521 = ··· 482 473 Alcotest.(check bool __LOC__ true pub_eq) 483 474 | Error _ -> Alcotest.fail "bad public key" 484 475 in 485 - let pub_key_compression () = 486 - let _, pub = P521.Dsa.generate () in 487 - let compressed = P521.Dsa.pub_to_octets ~compress:true pub in 488 - let decompressed = P521.Dsa.pub_of_octets compressed in 489 - let comparison = match decompressed with 490 - | Ok decompressed -> 491 - let p1 = P521.Dsa.pub_to_octets pub in 492 - let p2 = P521.Dsa.pub_to_octets decompressed in 493 - String.equal p1 p2 494 - | Error _ -> false 495 - in 496 - Alcotest.(check bool __LOC__ true comparison) 497 - in 498 476 let case (type a) (hash : a Digestif.hash) ~message ~k ~r ~s () = 499 477 let msg = Digestif.(digest_string hash message |> to_raw_string hash) 500 478 and k = of_h k ··· 625 603 626 604 ] in 627 605 ("public key matches", `Quick, pub_rfc) :: 628 - ("public key compression and decompression", `Quick, pub_key_compression) :: 606 + ("public key compression and decompression", `Quick, pub_key_compression (module P521.Dsa)) :: 629 607 List.mapi (fun i c -> "RFC 6979 A.2.7 " ^ string_of_int i, `Quick, c) cases 630 608 631 609 let x25519 () =