This commit is contained in:
parent
aa2ff7b2f0
commit
2f3113f55d
11742 changed files with 1223940 additions and 0 deletions
63
unikernel/duniverse/mirage-crypto/tests/dune
Normal file
63
unikernel/duniverse/mirage-crypto/tests/dune
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
(library
|
||||
(name test_common)
|
||||
(libraries mirage-crypto ounit2 ohex)
|
||||
(modules test_common)
|
||||
(optional))
|
||||
|
||||
(test
|
||||
(name test_symmetric_runner)
|
||||
(libraries test_common mirage-crypto ounit2)
|
||||
(package mirage-crypto)
|
||||
(modules test_base test_cipher test_symmetric_runner))
|
||||
|
||||
(test
|
||||
(name test_random_runner)
|
||||
(libraries test_common mirage-crypto mirage-crypto-rng mirage-crypto-rng.unix
|
||||
randomconv ounit2)
|
||||
(package mirage-crypto-rng)
|
||||
(modules test_random_runner))
|
||||
|
||||
(test
|
||||
(name test_pk_runner)
|
||||
(libraries test_common mirage-crypto-pk mirage-crypto-rng.unix randomconv
|
||||
ounit2)
|
||||
(package mirage-crypto-pk)
|
||||
(modules test_numeric test_dh test_dsa test_rsa test_pk_runner))
|
||||
|
||||
(test
|
||||
(name test_entropy_collection)
|
||||
(modules test_entropy_collection)
|
||||
(package mirage-crypto-rng-mirage)
|
||||
(libraries mirage-crypto-rng-mirage mirage-unix duration ohex))
|
||||
|
||||
(test
|
||||
(name test_entropy)
|
||||
(modules test_entropy)
|
||||
(package mirage-crypto-rng)
|
||||
(libraries mirage-crypto-rng ohex)
|
||||
(enabled_if (and (<> %{architecture} "arm64") (<> %{architecture} "riscv64"))))
|
||||
; see https://github.com/mirage/mirage-crypto/issues/216
|
||||
|
||||
(test
|
||||
(name test_ec)
|
||||
(modules test_ec)
|
||||
(libraries test_common alcotest mirage-crypto-ec mirage-crypto-rng.unix)
|
||||
(package mirage-crypto-ec))
|
||||
|
||||
(test
|
||||
(name test_ec_wycheproof)
|
||||
(modules test_ec_wycheproof)
|
||||
(deps ecdh_secp256r1_test.json ecdsa_secp256r1_sha256_test.json
|
||||
ecdsa_secp256r1_sha512_test.json ecdh_secp384r1_test.json
|
||||
ecdsa_secp384r1_sha384_test.json ecdsa_secp384r1_sha512_test.json
|
||||
ecdh_secp521r1_test.json ecdsa_secp521r1_sha512_test.json
|
||||
x25519_test.json eddsa_test.json)
|
||||
(libraries alcotest mirage-crypto-ec wycheproof digestif asn1-combinators)
|
||||
(package mirage-crypto-ec))
|
||||
|
||||
(tests
|
||||
(names test_miou_rng test_miou_entropy_collection)
|
||||
(modules test_miou_rng test_miou_entropy_collection)
|
||||
(libraries mirage-crypto-rng-miou-unix duration ohex)
|
||||
(package mirage-crypto-rng-miou-unix)
|
||||
(enabled_if (<> %{os_type} "Win32")))
|
||||
3581
unikernel/duniverse/mirage-crypto/tests/ecdh_secp224r1_test.json
Normal file
3581
unikernel/duniverse/mirage-crypto/tests/ecdh_secp224r1_test.json
Normal file
File diff suppressed because it is too large
Load diff
4677
unikernel/duniverse/mirage-crypto/tests/ecdh_secp256r1_test.json
Normal file
4677
unikernel/duniverse/mirage-crypto/tests/ecdh_secp256r1_test.json
Normal file
File diff suppressed because it is too large
Load diff
4366
unikernel/duniverse/mirage-crypto/tests/ecdh_secp384r1_test.json
Normal file
4366
unikernel/duniverse/mirage-crypto/tests/ecdh_secp384r1_test.json
Normal file
File diff suppressed because it is too large
Load diff
4868
unikernel/duniverse/mirage-crypto/tests/ecdh_secp521r1_test.json
Normal file
4868
unikernel/duniverse/mirage-crypto/tests/ecdh_secp521r1_test.json
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
2262
unikernel/duniverse/mirage-crypto/tests/eddsa_test.json
Normal file
2262
unikernel/duniverse/mirage-crypto/tests/eddsa_test.json
Normal file
File diff suppressed because it is too large
Load diff
135
unikernel/duniverse/mirage-crypto/tests/misc_pk.ml
Normal file
135
unikernel/duniverse/mirage-crypto/tests/misc_pk.ml
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
|
||||
let mem f =
|
||||
let t = Hashtbl.create 100 in
|
||||
fun x ->
|
||||
try Hashtbl.find t x with
|
||||
| Not_found ->
|
||||
let r = f x in ( Hashtbl.add t x r ; r )
|
||||
|
||||
|
||||
(* An [admittedly primitive] implementation of Pollards p-1 factoring method. *)
|
||||
|
||||
module Pollard = struct
|
||||
|
||||
let primes_to n =
|
||||
let rec scan = function
|
||||
| p when p > n -> []
|
||||
| p -> p :: scan Z.(nextprime p) in
|
||||
scan (Z.of_int 2)
|
||||
|
||||
let max_pow limit x =
|
||||
let rec expand lower upper =
|
||||
if Z.(pow x upper) > limit then (lower, upper)
|
||||
else expand upper (upper * 2)
|
||||
and narrow lower upper =
|
||||
if upper - lower = 1 then lower else
|
||||
let mid = (lower + upper) / 2 in
|
||||
if Z.(pow x mid) > limit then
|
||||
narrow lower mid
|
||||
else narrow mid upper
|
||||
in
|
||||
let (l, u) = expand 1 2 in
|
||||
narrow l u
|
||||
|
||||
let ppowers_to n =
|
||||
let rec scan = function
|
||||
| p when p > n -> []
|
||||
| p ->
|
||||
let pp = Z.pow p (max_pow n p) in
|
||||
pp :: scan Z.(nextprime p) in
|
||||
scan (Z.of_int 2)
|
||||
|
||||
let note ~msg f =
|
||||
Printf.printf "[%s] ->\n%!" msg ;
|
||||
let r = f () in
|
||||
Printf.printf "[%s] <-\n%!" msg ;
|
||||
r
|
||||
|
||||
let prime_pows_to_prod = mem @@ fun n ->
|
||||
let rec scan acc = function
|
||||
| p when p > n -> acc
|
||||
| p -> scan Z.(acc * (pow p (max_pow n p)))
|
||||
Z.(nextprime p) in
|
||||
note ~msg:"powers" @@ fun () ->
|
||||
scan Z.one Z.(of_int 2)
|
||||
|
||||
let split ~limit n =
|
||||
let a = Nums.Z.gen n in
|
||||
match Z.gcd n a with
|
||||
| d when d > Z.one -> a
|
||||
| d ->
|
||||
let rec scan a m =
|
||||
let x = Z.(powm a (m * n) n) in
|
||||
if Z.(x = one) then
|
||||
if Z.(m mod of_int 2 = zero) then
|
||||
scan a Z.(m / of_int 2)
|
||||
else raise Not_found
|
||||
else
|
||||
let d = Z.(gcd (x - one) n) in
|
||||
if Z.(d > one) then d else raise Not_found
|
||||
in
|
||||
scan a (prime_pows_to_prod limit)
|
||||
|
||||
end
|
||||
|
||||
module RSA_misc = struct
|
||||
|
||||
let slack = 8
|
||||
|
||||
(* Rivest's p-minus strong prime generator. *)
|
||||
|
||||
let rec pm_strong_prime ?g ~bits =
|
||||
let a_lim = Z.(pow z_two slack - one)
|
||||
in
|
||||
let rec mul_seq p = function
|
||||
| a when a > a_lim ->
|
||||
Printf.printf "++ mul seq: falling off the cliff.\n%!";
|
||||
None
|
||||
| a ->
|
||||
let p' = Z.(a * p + one) in
|
||||
match Z.probab_prime p' 25 with
|
||||
| 0 ->
|
||||
Printf.printf "+ mul seq: climb.\n%!";
|
||||
mul_seq p Z.(a + z_two)
|
||||
| _ ->
|
||||
Printf.printf "** mul seq: prime with %s\n%!" Z.(to_string a);
|
||||
Some p'
|
||||
in
|
||||
let pmm = prime ?g ~bits in
|
||||
match mul_seq pmm z_two with
|
||||
| None -> pm_strong_prime ?g ~bits
|
||||
| Some pm ->
|
||||
match mul_seq pm z_two with
|
||||
| None -> pm_strong_prime ?g ~bits
|
||||
| Some p -> (pmm, pm, p)
|
||||
|
||||
let slim = Z.(pow z_two 8)
|
||||
|
||||
(* Williams/Schmid strong prime generator. *)
|
||||
|
||||
let rec p_strong_prime1 ?g ~bits =
|
||||
let (bits1, bits2) = (bits / 2, bits - bits / 2)
|
||||
in
|
||||
let pmm = prime ?g ~bits:bits1
|
||||
and pp = prime ?g ~bits:bits2 in
|
||||
let r = Z.(pp - invert pmm pp)
|
||||
in
|
||||
let rec find_a = function
|
||||
| a when a >= slim ->
|
||||
Printf.printf "off the cliff...\n%!" ;
|
||||
p_strong_prime1 ?g ~bits
|
||||
| a ->
|
||||
let pm = Z.(z_two * a * pmm * pp + z_two * r * pmm + one) in
|
||||
match Z.probab_prime pm 25 with
|
||||
| 0 -> find_a Z.(a + one)
|
||||
| _ ->
|
||||
let p = Z.(z_two * pm + one) in
|
||||
match Z.probab_prime p 25 with
|
||||
| 0 -> find_a Z.(a + one)
|
||||
| _ ->
|
||||
Printf.printf "found pm, p with %s\n%!" Z.(to_string a);
|
||||
(pmm, pm, pp, p)
|
||||
in
|
||||
find_a z_two
|
||||
|
||||
end
|
||||
26
unikernel/duniverse/mirage-crypto/tests/test_base.ml
Normal file
26
unikernel/duniverse/mirage-crypto/tests/test_base.ml
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
open OUnit2
|
||||
|
||||
open Mirage_crypto
|
||||
|
||||
open Test_common
|
||||
|
||||
(* Xor *)
|
||||
|
||||
let xor_cases =
|
||||
cases_of (f2_eq ~msg:"xor" Uncommon.xor) [
|
||||
"00 01 02 03 04 05 06 07 08 09 0a 0b 0c" ,
|
||||
"0c 0b 0a 09 08 07 06 05 04 03 02 01 00" ,
|
||||
"0c 0a 08 0a 0c 02 00 02 0c 0a 08 0a 0c" ;
|
||||
|
||||
"00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" ,
|
||||
"0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00" ,
|
||||
"0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f" ;
|
||||
|
||||
"00", "00", "00" ;
|
||||
|
||||
"", "", "" ;
|
||||
]
|
||||
|
||||
let suite = [
|
||||
"XOR" >::: [ "example" >::: xor_cases ];
|
||||
]
|
||||
1007
unikernel/duniverse/mirage-crypto/tests/test_cipher.ml
Normal file
1007
unikernel/duniverse/mirage-crypto/tests/test_cipher.ml
Normal file
File diff suppressed because it is too large
Load diff
68
unikernel/duniverse/mirage-crypto/tests/test_common.ml
Normal file
68
unikernel/duniverse/mirage-crypto/tests/test_common.ml
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
open OUnit2
|
||||
|
||||
let (prf, strf) = Format.(fprintf, asprintf)
|
||||
let pp_map pp f ppf x = pp ppf (f x)
|
||||
let pp_diff pp ppf (a, b) = prf ppf "@[<v>want: %a@,have: %a@]" pp a pp b
|
||||
|
||||
let of_hex ?(skip_ws = true) s =
|
||||
let fold f acc str =
|
||||
let st = ref acc in
|
||||
String.iter (fun c -> st := f !st c) str;
|
||||
!st
|
||||
and digit c =
|
||||
match c with
|
||||
| '0'..'9' -> int_of_char c - 0x30
|
||||
| 'A'..'F' -> int_of_char c - 0x41 + 10
|
||||
| 'a'..'f' -> int_of_char c - 0x61 + 10
|
||||
| _ -> invalid_arg "bad character"
|
||||
and is_space = function
|
||||
| ' ' | '\012' | '\n' | '\r' | '\t' -> true
|
||||
| _ -> false
|
||||
in
|
||||
let chars, leftover =
|
||||
fold (fun (chars, leftover) c ->
|
||||
if skip_ws && is_space c then
|
||||
chars, leftover
|
||||
else
|
||||
let c = digit c in
|
||||
match leftover with
|
||||
| None -> chars, Some (c lsl 4)
|
||||
| Some c' -> (c' lor c) :: chars, None)
|
||||
([], None) s
|
||||
in
|
||||
let chars = List.rev chars in
|
||||
assert (leftover = None);
|
||||
String.init (List.length chars) (fun i -> char_of_int (List.nth chars i))
|
||||
|
||||
let rec range a b =
|
||||
if a > b then [] else a :: range (succ a) b
|
||||
|
||||
let rec times ~n f a =
|
||||
if n > 0 then ( ignore (f a) ; times ~n:(pred n) f a )
|
||||
|
||||
let pp_opt pp ppf = Format.(function
|
||||
| Some x -> fprintf ppf "Some(%a)" pp x
|
||||
| None -> fprintf ppf "None")
|
||||
|
||||
let eq_opt eq a b = match (a, b) with
|
||||
| (Some x, Some y) -> eq x y
|
||||
| _ -> false
|
||||
|
||||
let pp_octets pp = pp (Ohex.pp_hexdump ())
|
||||
|
||||
let assert_oct_equal ?msg =
|
||||
assert_equal ~cmp:String.equal ?msg ~pp_diff:(pp_octets pp_diff)
|
||||
|
||||
let iter_list xs f = List.iter f xs
|
||||
|
||||
let cases_of f =
|
||||
List.map @@ fun params -> test_case (f params)
|
||||
|
||||
let any _ = true
|
||||
|
||||
let vx = Ohex.decode
|
||||
|
||||
let f1_eq ?msg f (a, b) _ =
|
||||
assert_oct_equal ?msg (f (vx a)) (vx b)
|
||||
|
||||
let f2_eq ?msg f (a, b, c) = f1_eq ?msg (f (vx a)) (b, c)
|
||||
73
unikernel/duniverse/mirage-crypto/tests/test_dh.ml
Normal file
73
unikernel/duniverse/mirage-crypto/tests/test_dh.ml
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
open OUnit2
|
||||
|
||||
open Mirage_crypto_pk
|
||||
|
||||
open Test_common
|
||||
|
||||
let dh_selftest ~bits n =
|
||||
"selftest" >:: times ~n @@ fun _ ->
|
||||
let p = Dh.gen_group ~bits () in
|
||||
let (s1, m1) = Dh.gen_key p
|
||||
and (s2, m2) = Dh.gen_key p in
|
||||
let sh1 = Dh.shared s1 m2
|
||||
and sh2 = Dh.shared s2 m1 in
|
||||
assert_equal sh1 sh2
|
||||
~cmp:(eq_opt String.equal)
|
||||
~pp_diff:(pp_diff (fun ppf -> function
|
||||
| None -> Format.fprintf ppf "None"
|
||||
| Some a -> Format.fprintf ppf "Some(%a)" (Ohex.pp_hexdump ()) a))
|
||||
~msg:"shared secret"
|
||||
|
||||
let dh_shared_0 =
|
||||
"shared_0" >:: fun _ ->
|
||||
let gy = vx
|
||||
"14 ac e2 c0 9c c0 0c 25 89 71 b2 d0 1c 94 58 21
|
||||
02 23 b7 23 ec 3e 24 e5 a3 c2 fd 16 cc 49 f0 e2
|
||||
87 62 a5 a0 73 f5 de 5b 9b eb c3 60 0b a4 03 38
|
||||
0f e1 8c f2 80 b3 64 16 f2 af ab 2e ec 25 81 2c
|
||||
84 ae 92 0a 0f 15 9b f3 d9 1f dc 08 7d 8d 27 3a
|
||||
91 7d a5 89 dc 94 d6 bc 3f 9d 6d b3 f8 8e f2 37
|
||||
86 54 ec 85 ea 4c a0 4c b1 f6 49 83 1c 62 a7 79
|
||||
2b 8b 9c e7 fa 47 3e 34 6c c5 ae 12 a3 4e d5 ce
|
||||
4b da ea 72 7a 8d c6 67 ef 7e f2 00 24 d7 21 42
|
||||
a5 23 69 38 7e ec b5 fc 4b 89 42 c4 32 fa e5 58
|
||||
6f 39 5d a7 4e cd b5 da dc 1e 52 fe a4 33 72 c1
|
||||
82 48 8a 5b c1 44 bc 60 9b 38 5b 80 5f 44 14 93"
|
||||
and s = vx
|
||||
"f9 47 87 95 d2 a1 6d d1 7c c8 a9 c0 71 28 a2 82
|
||||
71 95 7e 79 87 0b fc 34 a2 42 ec 42 ac cc 42 81
|
||||
7b f6 c4 f5 80 a9 70 e3 35 93 9b a3 21 81 a4 e3
|
||||
6b 65 3f 1c 5c ab 87 23 86 eb 76 29 66 26 5b e9
|
||||
c4 d0 26 05 3f de 6c 2f a6 14 f6 bf 77 74 a0 e8
|
||||
ef e7 12 62 a3 83 e5 66 d8 6c e5 c6 58 67 2a 61
|
||||
f5 7b 7c 15 15 63 22 55 96 92 9e bd cc b3 bc 2b
|
||||
5e e1 ac 5f 75 23 ca 2f 19 5a f1 18 6e 17 f8 c2
|
||||
f7 11 c7 14 1d 81 bd be 02 31 3f 49 62 7d 02 11
|
||||
29 22 63 6e bb 1a 7f 93 bd 98 db 20 94 f8 f0 2e
|
||||
db ce 9d 79 db b9 a7 41 5f e5 29 a2 31 f8 e2 c3
|
||||
30 6a 09 f2 16 a7 30 8c 2f 36 7b 71 99 1e 28 54"
|
||||
and shared = vx
|
||||
"a7 40 0d eb f0 4b 2b ec cb 90 3c 55 2d 3c 17 63
|
||||
b2 4b 4e 1a ff 1e a0 24 c6 56 e3 5e 44 7b d0 01
|
||||
ef b3 6b 57 20 0e 15 95 b1 53 1a 83 16 3a b1 61
|
||||
06 65 f1 7e 64 63 6f 23 86 22 34 c3 fe a9 60 87
|
||||
3f 18 c6 5d 44 3e ac e3 85 34 86 6f db aa 31 3b
|
||||
4b 4d 68 f7 19 d7 91 a3 12 27 d6 5a ce 29 c8 1b
|
||||
5a 59 74 10 8c ff 98 4e 4f 37 ef 5b 43 e8 e2 ad
|
||||
a8 49 c9 7e c3 c5 3d 35 40 30 8e a4 41 69 1d 16
|
||||
34 ba 9a 7e f3 ab d1 0e bb f2 81 15 e9 04 63 ee
|
||||
1b bf cc 24 6d cb 41 c4 06 b2 f3 01 1b 31 3a 1e
|
||||
dc e3 3b c7 cc 1d 19 95 d9 fe 6a 5c a7 57 46 dd
|
||||
84 69 0c 45 37 2e 1f 52 96 05 d7 e5 01 9a c8"
|
||||
in
|
||||
let grp = Dh.Group.oakley_5 in
|
||||
match Dh.(shared (fst (key_of_secret grp ~s)) gy) with
|
||||
| None -> assert_failure "degenerate shared secret"
|
||||
| Some shared' ->
|
||||
assert_oct_equal ~msg:"shared secret" shared shared'
|
||||
|
||||
let suite = [
|
||||
dh_selftest ~bits:16 1000 ;
|
||||
dh_selftest ~bits:128 100 ;
|
||||
dh_shared_0
|
||||
]
|
||||
2381
unikernel/duniverse/mirage-crypto/tests/test_dsa.ml
Normal file
2381
unikernel/duniverse/mirage-crypto/tests/test_dsa.ml
Normal file
File diff suppressed because it is too large
Load diff
856
unikernel/duniverse/mirage-crypto/tests/test_ec.ml
Normal file
856
unikernel/duniverse/mirage-crypto/tests/test_ec.ml
Normal file
|
|
@ -0,0 +1,856 @@
|
|||
open Mirage_crypto_ec
|
||||
open Test_common
|
||||
|
||||
module Testable = struct
|
||||
let ok_or_error =
|
||||
Alcotest.result Alcotest.unit (Alcotest.testable pp_error ( = ))
|
||||
end
|
||||
|
||||
let pp_hex_le fmt buf =
|
||||
let n = String.length buf in
|
||||
let bbuf = Bytes.unsafe_of_string buf in
|
||||
for i = n - 1 downto 0 do
|
||||
let byte = Bytes.get_uint8 bbuf i in
|
||||
Format.fprintf fmt "%02x" byte
|
||||
done
|
||||
|
||||
let pp_result ppf = function
|
||||
| Ok cs -> pp_hex_le ppf cs
|
||||
| Error e -> Format.fprintf ppf "%a" pp_error e
|
||||
|
||||
let key_exchange =
|
||||
let test ~name d p ~expected =
|
||||
( name,
|
||||
`Quick,
|
||||
fun () ->
|
||||
P256.Dh.key_exchange d p
|
||||
|> Format.asprintf "%a" pp_result
|
||||
|> Alcotest.check Alcotest.string __LOC__ expected )
|
||||
in
|
||||
let kp data =
|
||||
match P256.Dh.secret_of_octets data with
|
||||
| Ok (p, s) -> p, s
|
||||
| Error _ -> assert false
|
||||
in
|
||||
let d_a, p_a =
|
||||
kp (of_hex "200102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f")
|
||||
and d_b, p_b =
|
||||
kp (of_hex "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f")
|
||||
in
|
||||
[
|
||||
test ~name:"b*A" d_b p_a
|
||||
~expected:
|
||||
"2e3e4065a62a7f425aaf8aae3d158f367c733300b5002e0b62f4bc6260789e1b";
|
||||
test ~name:"a*B" d_a p_b
|
||||
~expected:
|
||||
"2e3e4065a62a7f425aaf8aae3d158f367c733300b5002e0b62f4bc6260789e1b";
|
||||
test ~name:"a*A" d_a p_a
|
||||
~expected:
|
||||
"2ea4e810837da217a5bfd05f01d12459eeda830b6e0dec7f8afa425c5b55c507";
|
||||
test ~name:"b*B" d_b p_b
|
||||
~expected:
|
||||
"a7666bcc3818472194460f7df22d80a5886da0e1679eac930175ce1ff733c7ca";
|
||||
]
|
||||
|
||||
let scalar_mult =
|
||||
let test ~n ~scalar ~point ~expected =
|
||||
let scalar =
|
||||
match P256.Dh.secret_of_octets scalar with
|
||||
| Ok (p, _) -> p
|
||||
| Error _ -> assert false
|
||||
in
|
||||
( Printf.sprintf "Scalar mult (#%d)" n,
|
||||
`Quick,
|
||||
fun () ->
|
||||
P256.Dh.key_exchange scalar point
|
||||
|> Format.asprintf "%a" pp_result
|
||||
|> Alcotest.check Alcotest.string __LOC__ expected )
|
||||
in
|
||||
let point =
|
||||
of_hex "046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5"
|
||||
in
|
||||
[
|
||||
test ~n:0
|
||||
~scalar:(of_hex "0000000000000000000000000000000000000000000000000000000000000001")
|
||||
~point
|
||||
~expected:"96c298d84539a1f4a033eb2d817d0377f240a463e5e6bcf847422ce1f2d1176b";
|
||||
test ~n:1
|
||||
~scalar:(of_hex "0000000000000000000000000000000000000000000000000000000000000002")
|
||||
~point
|
||||
~expected:"78996647fc480ba6351bf277e26989c0c31ab5040338528a7e4f038d187bf27c";
|
||||
test ~n:2
|
||||
~scalar:(of_hex "0000000000000000000000000000000000000000000000000000000000000004")
|
||||
~point
|
||||
~expected:"5208036b44029350ef965578dbe21f03d02be69e65de2da0bb8fd032354a53e2";
|
||||
test ~n:3
|
||||
~scalar:(of_hex "0612465c89a023ab17855b0a6bcebfd3febb53aef84138647b5352e02c10c346")
|
||||
~point:(of_hex "0462d5bd3372af75fe85a040715d0f502428e07046868b0bfdfa61d731afe44f26ac333a93a9e70a81cd5a95b5bf8d13990eb741c8c38872b4a07d275a014e30cf")
|
||||
~expected:"854271e19508bc935ab22b95cd2be13a0e78265f528b658b3219028b900d0253";
|
||||
test ~n:4
|
||||
~scalar:(of_hex "0a0d622a47e48f6bc1038ace438c6f528aa00ad2bd1da5f13ee46bf5f633d71a")
|
||||
~point:(of_hex "043cbc1b31b43f17dc200dd70c2944c04c6cb1b082820c234a300b05b7763844c74fde0a4ef93887469793270eb2ff148287da9265b0334f9e2609aac16e8ad503")
|
||||
~expected:"ffffffffffffffffffffffffffffffff3022cfeeffffffffffffffffffffff7f";
|
||||
test ~n:5
|
||||
~scalar:(of_hex "55d55f11bb8da1ea318bca7266f0376662441ea87270aa2077f1b770c4854a48")
|
||||
~point:(of_hex "04000000000000000000000000000000000000000000000000000000000000000066485c780e2f83d72433bd5d84a06bb6541c2af31dae871728bf856a174f93f4")
|
||||
~expected:"48e82c9b82c88cb9fc2a5cff9e7c41bc4255ff6bd3814538c9b130877c07e4cf";
|
||||
]
|
||||
|
||||
let to_ok_or_error = function Ok _ -> Ok () | Error _ as e -> e
|
||||
|
||||
let point_validation =
|
||||
let test ~name ~x ~y ~expected =
|
||||
let scalar =
|
||||
match P256.Dh.secret_of_octets (of_hex "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f") with
|
||||
| Ok (p, _) -> p
|
||||
| _ -> assert false
|
||||
in
|
||||
let point =
|
||||
let s04 = String.make 1 '\004' in
|
||||
s04 ^ x ^ y
|
||||
in
|
||||
( name,
|
||||
`Quick,
|
||||
fun () ->
|
||||
P256.Dh.key_exchange scalar point
|
||||
|> to_ok_or_error
|
||||
|> Alcotest.check Testable.ok_or_error __LOC__ expected )
|
||||
in
|
||||
let zero = String.make 32 '\000' in
|
||||
let sb = of_hex "66485c780e2f83d72433bd5d84a06bb6541c2af31dae871728bf856a174f93f4"
|
||||
in
|
||||
[
|
||||
test ~name:"Ok"
|
||||
~x:(of_hex "62d5bd3372af75fe85a040715d0f502428e07046868b0bfdfa61d731afe44f26")
|
||||
~y:(of_hex "ac333a93a9e70a81cd5a95b5bf8d13990eb741c8c38872b4a07d275a014e30cf")
|
||||
~expected:(Ok ());
|
||||
test ~name:"P=0"
|
||||
~x:(of_hex "0000000000000000000000000000000000000000000000000000000000000000")
|
||||
~y:(of_hex "0000000000000000000000000000000000000000000000000000000000000000")
|
||||
~expected:(Error `Not_on_curve);
|
||||
test ~name:"(0, sqrt(b))" ~x:zero ~y:sb ~expected:(Ok ());
|
||||
test ~name:"out of range"
|
||||
~x:(of_hex "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF")
|
||||
~y:sb
|
||||
~expected:(Error `Invalid_range);
|
||||
]
|
||||
|
||||
let scalar_validation =
|
||||
let ign_sec hex =
|
||||
match P256.Dh.secret_of_octets (of_hex hex) with
|
||||
| Ok _ -> Ok ()
|
||||
| Error _ as e -> e
|
||||
in
|
||||
[ ("0", `Quick, fun () ->
|
||||
Alcotest.check Testable.ok_or_error __LOC__
|
||||
(Error `Invalid_range)
|
||||
(ign_sec "0000000000000000000000000000000000000000000000000000000000000000")) ;
|
||||
("1", `Quick, fun () ->
|
||||
Alcotest.check Testable.ok_or_error __LOC__
|
||||
(Ok ())
|
||||
(ign_sec "0000000000000000000000000000000000000000000000000000000000000001")) ;
|
||||
("n-1", `Quick, fun () ->
|
||||
Alcotest.check Testable.ok_or_error __LOC__
|
||||
(Ok ())
|
||||
(ign_sec "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632550")) ;
|
||||
("n", `Quick, fun () ->
|
||||
Alcotest.check Testable.ok_or_error __LOC__
|
||||
(Error `Invalid_range)
|
||||
(ign_sec "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551")) ;
|
||||
]
|
||||
|
||||
let ecdsa_gen () =
|
||||
let d = of_hex "C477F9F6 5C22CCE2 0657FAA5 B2D1D812 2336F851 A508A1ED 04E479C3 4985BF96" in
|
||||
let p = match
|
||||
P256.Dsa.pub_of_octets
|
||||
(of_hex {|04
|
||||
B7E08AFD FE94BAD3 F1DC8C73 4798BA1C 62B3A0AD 1E9EA2A3 8201CD08 89BC7A19
|
||||
3603F747 959DBF7A 4BB226E4 19287290 63ADC7AE 43529E61 B563BBC6 06CC5E09|})
|
||||
with
|
||||
| Ok a -> a
|
||||
| Error _ -> assert false
|
||||
in
|
||||
let pub = match P256.Dsa.priv_of_octets d with
|
||||
| Ok p -> P256.Dsa.pub_of_priv p
|
||||
| Error _ -> Alcotest.fail "couldn't decode private key"
|
||||
in
|
||||
let pub_eq a b =
|
||||
String.equal (P256.Dsa.pub_to_octets a) (P256.Dsa.pub_to_octets b)
|
||||
in
|
||||
Alcotest.(check bool __LOC__ true (pub_eq pub p))
|
||||
|
||||
let ecdsa_sign () =
|
||||
let d = of_hex "C477F9F6 5C22CCE2 0657FAA5 B2D1D812 2336F851 A508A1ED 04E479C3 4985BF96"
|
||||
and k = of_hex "7A1A7E52 797FC8CA AA435D2A 4DACE391 58504BF2 04FBE19F 14DBB427 FAEE50AE"
|
||||
and e = of_hex "A41A41A1 2A799548 211C410C 65D8133A FDE34D28 BDD542E4 B680CF28 99C8A8C4"
|
||||
in
|
||||
let r = of_hex "2B42F576 D07F4165 FF65D1F3 B1500F81 E44C316F 1F0B3EF5 7325B69A CA46104F"
|
||||
and s = of_hex "DC42C212 2D6392CD 3E3A993A 89502A81 98C1886F E69D262C 4B329BDB 6B63FAF1"
|
||||
in
|
||||
let key = match P256.Dsa.priv_of_octets d with
|
||||
| Ok p -> p
|
||||
| Error _ -> Alcotest.fail "couldn't decode private key"
|
||||
in
|
||||
let (r', s') = P256.Dsa.sign ~key ~k e in
|
||||
Alcotest.(check bool __LOC__ true (String.equal r r' && String.equal s s'))
|
||||
|
||||
let ecdsa_verify () =
|
||||
let key =
|
||||
match P256.Dsa.pub_of_octets
|
||||
(of_hex {|04
|
||||
B7E08AFD FE94BAD3 F1DC8C73 4798BA1C 62B3A0AD 1E9EA2A3 8201CD08 89BC7A19
|
||||
3603F747 959DBF7A 4BB226E4 19287290 63ADC7AE 43529E61 B563BBC6 06CC5E09|})
|
||||
with
|
||||
| Ok a -> a
|
||||
| Error _ -> assert false
|
||||
and e = of_hex "A41A41A1 2A799548 211C410C 65D8133A FDE34D28 BDD542E4 B680CF28 99C8A8C4"
|
||||
and r = of_hex "2B42F576 D07F4165 FF65D1F3 B1500F81 E44C316F 1F0B3EF5 7325B69A CA46104F"
|
||||
and s = of_hex "DC42C212 2D6392CD 3E3A993A 89502A81 98C1886F E69D262C 4B329BDB 6B63FAF1"
|
||||
in
|
||||
Alcotest.(check bool __LOC__ true (P256.Dsa.verify ~key (r, s) e))
|
||||
|
||||
let ecdsa = [
|
||||
(* from https://csrc.nist.rip/groups/ST/toolkit/documents/Examples/ECDSA_Prime.pdf *)
|
||||
"ECDSA gen", `Quick, ecdsa_gen ;
|
||||
"ECDSA sign", `Quick, ecdsa_sign ;
|
||||
"ECDSA verify", `Quick, ecdsa_verify ;
|
||||
]
|
||||
|
||||
let pub_key_compression (module Dsa:Mirage_crypto_ec.Dsa) () =
|
||||
for _ = 1 to 20 do
|
||||
let _, pub = Dsa.generate () in
|
||||
let compressed = Dsa.pub_to_octets ~compress:true pub in
|
||||
let decompressed = Dsa.pub_of_octets compressed in
|
||||
match decompressed with
|
||||
| Ok decompressed ->
|
||||
let p1 = Dsa.pub_to_octets pub in
|
||||
let p2 = Dsa.pub_to_octets decompressed in
|
||||
Alcotest.(check string __LOC__ p1 p2);
|
||||
let prefix = String.get_uint8 compressed 0 in
|
||||
let expected = 2 + String.(get_uint8 p1 (length p1 - 1)) land 1 in
|
||||
Alcotest.(check int __LOC__ expected prefix);
|
||||
| Error e -> Alcotest.failf "%a" pp_error e
|
||||
done
|
||||
|
||||
let ecdsa_rfc6979_p256 =
|
||||
(* A.2.5 - P 256 *)
|
||||
let priv, pub =
|
||||
let data = of_hex "C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721" in
|
||||
match P256.Dsa.priv_of_octets data with
|
||||
| Ok p -> p, P256.Dsa.pub_of_priv p
|
||||
| Error _ -> assert false
|
||||
in
|
||||
let pub_rfc () =
|
||||
let fst = String.make 1 '\004' in
|
||||
let ux = of_hex "60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6"
|
||||
and uy = of_hex "7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299"
|
||||
in
|
||||
match P256.Dsa.pub_of_octets (fst ^ ux ^ uy) with
|
||||
| Ok p ->
|
||||
let pub_eq =
|
||||
String.equal (P256.Dsa.pub_to_octets pub) (P256.Dsa.pub_to_octets p)
|
||||
in
|
||||
Alcotest.(check bool __LOC__ true pub_eq)
|
||||
| Error _ -> Alcotest.fail "bad public key"
|
||||
in
|
||||
let case (type a) (hash : a Digestif.hash) ~message ~k ~r ~s () =
|
||||
let msg =
|
||||
let h = Digestif.(digest_string hash message |> to_raw_string hash) in
|
||||
String.sub h 0 (min (String.length h) 32)
|
||||
and k = of_hex k
|
||||
in
|
||||
let k' =
|
||||
let module H = (val Digestif.module_of hash) in
|
||||
let module K = P256.Dsa.K_gen (H) in
|
||||
K.generate ~key:priv msg
|
||||
in
|
||||
Alcotest.(check bool __LOC__ true (String.equal k k'));
|
||||
let sig_eq (r', s') =
|
||||
String.equal (of_hex r) r' && String.equal (of_hex s) s'
|
||||
in
|
||||
let sig' = P256.Dsa.sign ~key:priv ~k msg in
|
||||
Alcotest.(check bool __LOC__ true (sig_eq sig'))
|
||||
in
|
||||
let cases = [
|
||||
case Digestif.sha1 ~message:"sample"
|
||||
~k:"882905F1227FD620FBF2ABF21244F0BA83D0DC3A9103DBBEE43A1FB858109DB4"
|
||||
~r:"61340C88C3AAEBEB4F6D667F672CA9759A6CCAA9FA8811313039EE4A35471D32"
|
||||
~s:"6D7F147DAC089441BB2E2FE8F7A3FA264B9C475098FDCF6E00D7C996E1B8B7EB" ;
|
||||
case Digestif.sha224 ~message:"sample"
|
||||
~k:"103F90EE9DC52E5E7FB5132B7033C63066D194321491862059967C715985D473"
|
||||
~r:"53B2FFF5D1752B2C689DF257C04C40A587FABABB3F6FC2702F1343AF7CA9AA3F"
|
||||
~s:"B9AFB64FDC03DC1A131C7D2386D11E349F070AA432A4ACC918BEA988BF75C74C" ;
|
||||
case Digestif.sha256 ~message:"sample"
|
||||
~k:"A6E3C57DD01ABE90086538398355DD4C3B17AA873382B0F24D6129493D8AAD60"
|
||||
~r:"EFD48B2AACB6A8FD1140DD9CD45E81D69D2C877B56AAF991C34D0EA84EAF3716"
|
||||
~s:"F7CB1C942D657C41D436C7A1B6E29F65F3E900DBB9AFF4064DC4AB2F843ACDA8" ;
|
||||
case Digestif.sha384 ~message:"sample"
|
||||
~k:"09F634B188CEFD98E7EC88B1AA9852D734D0BC272F7D2A47DECC6EBEB375AAD4"
|
||||
~r:"0EAFEA039B20E9B42309FB1D89E213057CBF973DC0CFC8F129EDDDC800EF7719"
|
||||
~s:"4861F0491E6998B9455193E34E7B0D284DDD7149A74B95B9261F13ABDE940954" ;
|
||||
case Digestif.sha512 ~message:"sample"
|
||||
~k:"5FA81C63109BADB88C1F367B47DA606DA28CAD69AA22C4FE6AD7DF73A7173AA5"
|
||||
~r:"8496A60B5E9B47C825488827E0495B0E3FA109EC4568FD3F8D1097678EB97F00"
|
||||
~s:"2362AB1ADBE2B8ADF9CB9EDAB740EA6049C028114F2460F96554F61FAE3302FE" ;
|
||||
case Digestif.sha1 ~message:"test"
|
||||
~k:"8C9520267C55D6B980DF741E56B4ADEE114D84FBFA2E62137954164028632A2E"
|
||||
~r:"0CBCC86FD6ABD1D99E703E1EC50069EE5C0B4BA4B9AC60E409E8EC5910D81A89"
|
||||
~s:"01B9D7B73DFAA60D5651EC4591A0136F87653E0FD780C3B1BC872FFDEAE479B1" ;
|
||||
case Digestif.sha224 ~message:"test"
|
||||
~k:"669F4426F2688B8BE0DB3A6BD1989BDAEFFF84B649EEB84F3DD26080F667FAA7"
|
||||
~r:"C37EDB6F0AE79D47C3C27E962FA269BB4F441770357E114EE511F662EC34A692"
|
||||
~s:"C820053A05791E521FCAAD6042D40AEA1D6B1A540138558F47D0719800E18F2D" ;
|
||||
case Digestif.sha256 ~message:"test"
|
||||
~k:"D16B6AE827F17175E040871A1C7EC3500192C4C92677336EC2537ACAEE0008E0"
|
||||
~r:"F1ABB023518351CD71D881567B1EA663ED3EFCF6C5132B354F28D3B0B7D38367"
|
||||
~s:"019F4113742A2B14BD25926B49C649155F267E60D3814B4C0CC84250E46F0083" ;
|
||||
case Digestif.sha384 ~message:"test"
|
||||
~k:"16AEFFA357260B04B1DD199693960740066C1A8F3E8EDD79070AA914D361B3B8"
|
||||
~r:"83910E8B48BB0C74244EBDF7F07A1C5413D61472BD941EF3920E623FBCCEBEB6"
|
||||
~s:"8DDBEC54CF8CD5874883841D712142A56A8D0F218F5003CB0296B6B509619F2C" ;
|
||||
case Digestif.sha512 ~message:"test"
|
||||
~k:"6915D11632ACA3C40D5D51C08DAF9C555933819548784480E93499000D9F0B7F"
|
||||
~r:"461D93F31B6540894788FD206C07CFA0CC35F46FA3C91816FFF1040AD1581A04"
|
||||
~s:"39AF9F15DE0DB8D97E72719C74820D304CE5226E32DEDAE67519E840D1194E55" ;
|
||||
] in
|
||||
("public key matches", `Quick, pub_rfc) ::
|
||||
("public key compression and decompression", `Quick, (pub_key_compression (module P256.Dsa))) ::
|
||||
List.mapi (fun i c -> "RFC 6979 A.2.5 " ^ string_of_int i, `Quick, c) cases
|
||||
|
||||
let ecdsa_rfc6979_p384 =
|
||||
(* A.2.6 - P 384 *)
|
||||
let priv, pub =
|
||||
let data = of_hex "6B9D3DAD2E1B8C1C05B19875B6659F4DE23C3B667BF297BA9AA47740787137D896D5724E4C70A825F872C9EA60D2EDF5" in
|
||||
match P384.Dsa.priv_of_octets data with
|
||||
| Ok p -> p, P384.Dsa.pub_of_priv p
|
||||
| Error _ -> assert false
|
||||
in
|
||||
let pub_rfc () =
|
||||
let fst = String.make 1 '\004' in
|
||||
let ux = of_hex "EC3A4E415B4E19A4568618029F427FA5DA9A8BC4AE92E02E06AAE5286B300C64DEF8F0EA9055866064A254515480BC13"
|
||||
and uy = of_hex "8015D9B72D7D57244EA8EF9AC0C621896708A59367F9DFB9F54CA84B3F1C9DB1288B231C3AE0D4FE7344FD2533264720"
|
||||
in
|
||||
match P384.Dsa.pub_of_octets (fst ^ ux ^ uy) with
|
||||
| Ok p ->
|
||||
let pub_eq =
|
||||
String.equal (P384.Dsa.pub_to_octets pub) (P384.Dsa.pub_to_octets p)
|
||||
in
|
||||
Alcotest.(check bool __LOC__ true pub_eq)
|
||||
| Error _ -> Alcotest.fail "bad public key"
|
||||
in
|
||||
let case (type a) (hash : a Digestif.hash) ~message ~k ~r ~s () =
|
||||
let msg =
|
||||
let h = Digestif.(digest_string hash message |> to_raw_string hash) in
|
||||
String.sub h 0 (min (String.length h) 48)
|
||||
and k = of_hex k
|
||||
in
|
||||
let k' =
|
||||
let module H = (val Digestif.module_of hash) in
|
||||
let module K = P384.Dsa.K_gen (H) in
|
||||
K.generate ~key:priv msg
|
||||
in
|
||||
Alcotest.(check bool __LOC__ true (String.equal k k'));
|
||||
let sig_eq (r', s') =
|
||||
String.equal (of_hex r) r' && String.equal (of_hex s) s'
|
||||
in
|
||||
let sig' = P384.Dsa.sign ~key:priv ~k msg in
|
||||
Alcotest.(check bool __LOC__ true (sig_eq sig'))
|
||||
in
|
||||
let cases = [
|
||||
case Digestif.sha1 ~message:"sample"
|
||||
~k:"4471EF7518BB2C7C20F62EAE1C387AD0C5E8E470995DB4ACF694466E6AB09663
|
||||
0F29E5938D25106C3C340045A2DB01A7"
|
||||
~r:"EC748D839243D6FBEF4FC5C4859A7DFFD7F3ABDDF72014540C16D73309834FA3
|
||||
7B9BA002899F6FDA3A4A9386790D4EB2"
|
||||
~s:"A3BCFA947BEEF4732BF247AC17F71676CB31A847B9FF0CBC9C9ED4C1A5B3FACF
|
||||
26F49CA031D4857570CCB5CA4424A443";
|
||||
|
||||
case Digestif.sha224 ~message:"sample"
|
||||
~k:"A4E4D2F0E729EB786B31FC20AD5D849E304450E0AE8E3E341134A5C1AFA03CAB
|
||||
8083EE4E3C45B06A5899EA56C51B5879"
|
||||
~r:"42356E76B55A6D9B4631C865445DBE54E056D3B3431766D0509244793C3F9366
|
||||
450F76EE3DE43F5A125333A6BE060122"
|
||||
~s:"9DA0C81787064021E78DF658F2FBB0B042BF304665DB721F077A4298B095E483
|
||||
4C082C03D83028EFBF93A3C23940CA8D";
|
||||
|
||||
case Digestif.sha256 ~message:"sample"
|
||||
~k:"180AE9F9AEC5438A44BC159A1FCB277C7BE54FA20E7CF404B490650A8ACC414E
|
||||
375572342863C899F9F2EDF9747A9B60"
|
||||
~r:"21B13D1E013C7FA1392D03C5F99AF8B30C570C6F98D4EA8E354B63A21D3DAA33
|
||||
BDE1E888E63355D92FA2B3C36D8FB2CD"
|
||||
~s:"F3AA443FB107745BF4BD77CB3891674632068A10CA67E3D45DB2266FA7D1FEEB
|
||||
EFDC63ECCD1AC42EC0CB8668A4FA0AB0";
|
||||
|
||||
case Digestif.sha384 ~message:"sample"
|
||||
~k:"94ED910D1A099DAD3254E9242AE85ABDE4BA15168EAF0CA87A555FD56D10FBCA
|
||||
2907E3E83BA95368623B8C4686915CF9"
|
||||
~r:"94EDBB92A5ECB8AAD4736E56C691916B3F88140666CE9FA73D64C4EA95AD133C
|
||||
81A648152E44ACF96E36DD1E80FABE46"
|
||||
~s:"99EF4AEB15F178CEA1FE40DB2603138F130E740A19624526203B6351D0A3A94F
|
||||
A329C145786E679E7B82C71A38628AC8";
|
||||
|
||||
case Digestif.sha512 ~message:"sample"
|
||||
~k:"92FC3C7183A883E24216D1141F1A8976C5B0DD797DFA597E3D7B32198BD35331
|
||||
A4E966532593A52980D0E3AAA5E10EC3"
|
||||
~r:"ED0959D5880AB2D869AE7F6C2915C6D60F96507F9CB3E047C0046861DA4A799C
|
||||
FE30F35CC900056D7C99CD7882433709"
|
||||
~s:"512C8CCEEE3890A84058CE1E22DBC2198F42323CE8ACA9135329F03C068E5112
|
||||
DC7CC3EF3446DEFCEB01A45C2667FDD5";
|
||||
|
||||
case Digestif.sha1 ~message:"test"
|
||||
~k:"66CC2C8F4D303FC962E5FF6A27BD79F84EC812DDAE58CF5243B64A4AD8094D47
|
||||
EC3727F3A3C186C15054492E30698497"
|
||||
~r:"4BC35D3A50EF4E30576F58CD96CE6BF638025EE624004A1F7789A8B8E43D0678
|
||||
ACD9D29876DAF46638645F7F404B11C7"
|
||||
~s:"D5A6326C494ED3FF614703878961C0FDE7B2C278F9A65FD8C4B7186201A29916
|
||||
95BA1C84541327E966FA7B50F7382282";
|
||||
|
||||
case Digestif.sha224 ~message:"test"
|
||||
~k:"18FA39DB95AA5F561F30FA3591DC59C0FA3653A80DAFFA0B48D1A4C6DFCBFF6E
|
||||
3D33BE4DC5EB8886A8ECD093F2935726"
|
||||
~r:"E8C9D0B6EA72A0E7837FEA1D14A1A9557F29FAA45D3E7EE888FC5BF954B5E624
|
||||
64A9A817C47FF78B8C11066B24080E72"
|
||||
~s:"07041D4A7A0379AC7232FF72E6F77B6DDB8F09B16CCE0EC3286B2BD43FA8C614
|
||||
1C53EA5ABEF0D8231077A04540A96B66";
|
||||
|
||||
case Digestif.sha256 ~message:"test"
|
||||
~k:"0CFAC37587532347DC3389FDC98286BBA8C73807285B184C83E62E26C401C0FA
|
||||
A48DD070BA79921A3457ABFF2D630AD7"
|
||||
~r:"6D6DEFAC9AB64DABAFE36C6BF510352A4CC27001263638E5B16D9BB51D451559
|
||||
F918EEDAF2293BE5B475CC8F0188636B"
|
||||
~s:"2D46F3BECBCC523D5F1A1256BF0C9B024D879BA9E838144C8BA6BAEB4B53B47D
|
||||
51AB373F9845C0514EEFB14024787265";
|
||||
|
||||
case Digestif.sha384 ~message:"test"
|
||||
~k:"015EE46A5BF88773ED9123A5AB0807962D193719503C527B031B4C2D225092AD
|
||||
A71F4A459BC0DA98ADB95837DB8312EA"
|
||||
~r:"8203B63D3C853E8D77227FB377BCF7B7B772E97892A80F36AB775D509D7A5FEB
|
||||
0542A7F0812998DA8F1DD3CA3CF023DB"
|
||||
~s:"DDD0760448D42D8A43AF45AF836FCE4DE8BE06B485E9B61B827C2F13173923E0
|
||||
6A739F040649A667BF3B828246BAA5A5";
|
||||
|
||||
case Digestif.sha512 ~message:"test"
|
||||
~k:"3780C4F67CB15518B6ACAE34C9F83568D2E12E47DEAB6C50A4E4EE5319D1E8CE
|
||||
0E2CC8A136036DC4B9C00E6888F66B6C"
|
||||
~r:"A0D5D090C9980FAF3C2CE57B7AE951D31977DD11C775D314AF55F76C676447D0
|
||||
6FB6495CD21B4B6E340FC236584FB277"
|
||||
~s:"976984E59B4C77B0E8E4460DCA3D9F20E07B9BB1F63BEEFAF576F6B2E8B22463
|
||||
4A2092CD3792E0159AD9CEE37659C736"
|
||||
] in
|
||||
("public key matches", `Quick, pub_rfc) ::
|
||||
("public key compression and decompression", `Quick, pub_key_compression (module P384.Dsa)) ::
|
||||
List.mapi (fun i c -> "RFC 6979 A.2.6 " ^ string_of_int i, `Quick, c) cases
|
||||
|
||||
let ecdsa_rfc6979_p521 =
|
||||
(* A.2.7 - P 521 *)
|
||||
let of_h b = of_hex ((String.make 1 '0') ^ b) in
|
||||
let priv, pub =
|
||||
let data = of_h
|
||||
"0FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75C
|
||||
AA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B83
|
||||
538"
|
||||
in
|
||||
match P521.Dsa.priv_of_octets data with
|
||||
| Ok p -> p, P521.Dsa.pub_of_priv p
|
||||
| Error _ -> assert false
|
||||
in
|
||||
let pub_rfc () =
|
||||
let fst = String.make 1 '\004' in
|
||||
let ux = of_h
|
||||
"1894550D0785932E00EAA23B694F213F8C3121F86DC97A04E5A7167DB4E5BCD3
|
||||
71123D46E45DB6B5D5370A7F20FB633155D38FFA16D2BD761DCAC474B9A2F502
|
||||
3A4"
|
||||
and uy = of_h
|
||||
"0493101C962CD4D2FDDF782285E64584139C2F91B47F87FF82354D6630F746A2
|
||||
8A0DB25741B5B34A828008B22ACC23F924FAAFBD4D33F81EA66956DFEAA2BFDF
|
||||
CF5"
|
||||
in
|
||||
match P521.Dsa.pub_of_octets (fst ^ ux ^ uy) with
|
||||
| Ok p ->
|
||||
let pub_eq =
|
||||
String.equal (P521.Dsa.pub_to_octets pub) (P521.Dsa.pub_to_octets p)
|
||||
in
|
||||
Alcotest.(check bool __LOC__ true pub_eq)
|
||||
| Error _ -> Alcotest.fail "bad public key"
|
||||
in
|
||||
let case (type a) (hash : a Digestif.hash) ~message ~k ~r ~s () =
|
||||
let msg = Digestif.(digest_string hash message |> to_raw_string hash)
|
||||
and k = of_h k
|
||||
in
|
||||
let k' =
|
||||
let module H = (val Digestif.module_of hash) in
|
||||
let module K = P521.Dsa.K_gen (H) in
|
||||
K.generate ~key:priv msg
|
||||
in
|
||||
Alcotest.(check bool __LOC__ true (String.equal k k'));
|
||||
let sig_eq (r', s') =
|
||||
String.equal (of_h r) r' && String.equal (of_h s) s'
|
||||
in
|
||||
let sig' = P521.Dsa.sign ~key:priv ~k msg in
|
||||
Alcotest.(check bool __LOC__ true (sig_eq sig'))
|
||||
in
|
||||
let cases = [
|
||||
|
||||
case Digestif.sha1 ~message:"sample"
|
||||
~k:"089C071B419E1C2820962321787258469511958E80582E95D8378E0C2CCDB3CB
|
||||
42BEDE42F50E3FA3C71F5A76724281D31D9C89F0F91FC1BE4918DB1C03A5838D
|
||||
0F9"
|
||||
~r:"0343B6EC45728975EA5CBA6659BBB6062A5FF89EEA58BE3C80B619F322C87910
|
||||
FE092F7D45BB0F8EEE01ED3F20BABEC079D202AE677B243AB40B5431D497C55D
|
||||
75D"
|
||||
~s:"0E7B0E675A9B24413D448B8CC119D2BF7B2D2DF032741C096634D6D65D0DBE3D
|
||||
5694625FB9E8104D3B842C1B0E2D0B98BEA19341E8676AEF66AE4EBA3D5475D5
|
||||
D16";
|
||||
|
||||
case Digestif.sha224 ~message:"sample"
|
||||
~k:"121415EC2CD7726330A61F7F3FA5DE14BE9436019C4DB8CB4041F3B54CF31BE0
|
||||
493EE3F427FB906393D895A19C9523F3A1D54BB8702BD4AA9C99DAB2597B9211
|
||||
3F3"
|
||||
~r:"1776331CFCDF927D666E032E00CF776187BC9FDD8E69D0DABB4109FFE1B5E2A3
|
||||
0715F4CC923A4A5E94D2503E9ACFED92857B7F31D7152E0F8C00C15FF3D87E2E
|
||||
D2E"
|
||||
~s:"050CB5265417FE2320BBB5A122B8E1A32BD699089851128E360E620A30C7E17B
|
||||
A41A666AF126CE100E5799B153B60528D5300D08489CA9178FB610A2006C254B
|
||||
41F";
|
||||
|
||||
case Digestif.sha256 ~message:"sample"
|
||||
~k:"0EDF38AFCAAECAB4383358B34D67C9F2216C8382AAEA44A3DAD5FDC9C3257576
|
||||
1793FEF24EB0FC276DFC4F6E3EC476752F043CF01415387470BCBD8678ED2C7E
|
||||
1A0"
|
||||
~r:"1511BB4D675114FE266FC4372B87682BAECC01D3CC62CF2303C92B3526012659
|
||||
D16876E25C7C1E57648F23B73564D67F61C6F14D527D54972810421E7D87589E
|
||||
1A7"
|
||||
~s:"04A171143A83163D6DF460AAF61522695F207A58B95C0644D87E52AA1A347916
|
||||
E4F7A72930B1BC06DBE22CE3F58264AFD23704CBB63B29B931F7DE6C9D949A7E
|
||||
CFC";
|
||||
|
||||
case Digestif.sha384 ~message:"sample"
|
||||
~k:"1546A108BC23A15D6F21872F7DED661FA8431DDBD922D0DCDB77CC878C8553FF
|
||||
AD064C95A920A750AC9137E527390D2D92F153E66196966EA554D9ADFCB109C4
|
||||
211"
|
||||
~r:"1EA842A0E17D2DE4F92C15315C63DDF72685C18195C2BB95E572B9C5136CA4B4
|
||||
B576AD712A52BE9730627D16054BA40CC0B8D3FF035B12AE75168397F5D50C67
|
||||
451"
|
||||
~s:"1F21A3CEE066E1961025FB048BD5FE2B7924D0CD797BABE0A83B66F1E35EEAF5
|
||||
FDE143FA85DC394A7DEE766523393784484BDF3E00114A1C857CDE1AA203DB65
|
||||
D61";
|
||||
|
||||
case Digestif.sha512 ~message:"sample"
|
||||
~k:"1DAE2EA071F8110DC26882D4D5EAE0621A3256FC8847FB9022E2B7D28E6F1019
|
||||
8B1574FDD03A9053C08A1854A168AA5A57470EC97DD5CE090124EF52A2F7ECBF
|
||||
FD3"
|
||||
~r:"0C328FAFCBD79DD77850370C46325D987CB525569FB63C5D3BC53950E6D4C5F1
|
||||
74E25A1EE9017B5D450606ADD152B534931D7D4E8455CC91F9B15BF05EC36E37
|
||||
7FA"
|
||||
~s:"0617CCE7CF5064806C467F678D3B4080D6F1CC50AF26CA209417308281B68AF2
|
||||
82623EAA63E5B5C0723D8B8C37FF0777B1A20F8CCB1DCCC43997F1EE0E44DA4A
|
||||
67A";
|
||||
|
||||
case Digestif.sha1 ~message:"test"
|
||||
~k:"0BB9F2BF4FE1038CCF4DABD7139A56F6FD8BB1386561BD3C6A4FC818B20DF5DD
|
||||
BA80795A947107A1AB9D12DAA615B1ADE4F7A9DC05E8E6311150F47F5C57CE8B
|
||||
222"
|
||||
~r:"13BAD9F29ABE20DE37EBEB823C252CA0F63361284015A3BF430A46AAA80B87B0
|
||||
693F0694BD88AFE4E661FC33B094CD3B7963BED5A727ED8BD6A3A202ABE009D0
|
||||
367"
|
||||
~s:"1E9BB81FF7944CA409AD138DBBEE228E1AFCC0C890FC78EC8604639CB0DBDC90
|
||||
F717A99EAD9D272855D00162EE9527567DD6A92CBD629805C0445282BBC91679
|
||||
7FF";
|
||||
|
||||
case Digestif.sha224 ~message:"test"
|
||||
~k:"040D09FCF3C8A5F62CF4FB223CBBB2B9937F6B0577C27020A99602C25A011369
|
||||
87E452988781484EDBBCF1C47E554E7FC901BC3085E5206D9F619CFF07E73D6F
|
||||
706"
|
||||
~r:"1C7ED902E123E6815546065A2C4AF977B22AA8EADDB68B2C1110E7EA44D42086
|
||||
BFE4A34B67DDC0E17E96536E358219B23A706C6A6E16BA77B65E1C595D43CAE1
|
||||
7FB"
|
||||
~s:"177336676304FCB343CE028B38E7B4FBA76C1C1B277DA18CAD2A8478B2A9A9F5
|
||||
BEC0F3BA04F35DB3E4263569EC6AADE8C92746E4C82F8299AE1B8F1739F8FD51
|
||||
9A4";
|
||||
|
||||
case Digestif.sha256 ~message:"test"
|
||||
~k:"01DE74955EFAABC4C4F17F8E84D881D1310B5392D7700275F82F145C61E84384
|
||||
1AF09035BF7A6210F5A431A6A9E81C9323354A9E69135D44EBD2FCAA7731B909
|
||||
258"
|
||||
~r:"00E871C4A14F993C6C7369501900C4BC1E9C7B0B4BA44E04868B30B41D807104
|
||||
2EB28C4C250411D0CE08CD197E4188EA4876F279F90B3D8D74A3C76E6F1E4656
|
||||
AA8"
|
||||
~s:"0CD52DBAA33B063C3A6CD8058A1FB0A46A4754B034FCC644766CA14DA8CA5CA9
|
||||
FDE00E88C1AD60CCBA759025299079D7A427EC3CC5B619BFBC828E7769BCD694
|
||||
E86";
|
||||
|
||||
case Digestif.sha384 ~message:"test"
|
||||
~k:"1F1FC4A349A7DA9A9E116BFDD055DC08E78252FF8E23AC276AC88B1770AE0B5D
|
||||
CEB1ED14A4916B769A523CE1E90BA22846AF11DF8B300C38818F713DADD85DE0
|
||||
C88"
|
||||
~r:"14BEE21A18B6D8B3C93FAB08D43E739707953244FDBE924FA926D76669E7AC8C
|
||||
89DF62ED8975C2D8397A65A49DCC09F6B0AC62272741924D479354D74FF60755
|
||||
78C"
|
||||
~s:"133330865C067A0EAF72362A65E2D7BC4E461E8C8995C3B6226A21BD1AA78F0E
|
||||
D94FE536A0DCA35534F0CD1510C41525D163FE9D74D134881E35141ED5E8E95B
|
||||
979";
|
||||
|
||||
case Digestif.sha512 ~message:"test"
|
||||
~k:"16200813020EC986863BEDFC1B121F605C1215645018AEA1A7B215A564DE9EB1
|
||||
B38A67AA1128B80CE391C4FB71187654AAA3431027BFC7F395766CA988C964DC
|
||||
56D"
|
||||
~r:"13E99020ABF5CEE7525D16B69B229652AB6BDF2AFFCAEF38773B4B7D08725F10
|
||||
CDB93482FDCC54EDCEE91ECA4166B2A7C6265EF0CE2BD7051B7CEF945BABD47E
|
||||
E6D"
|
||||
~s:"1FBD0013C674AA79CB39849527916CE301C66EA7CE8B80682786AD60F98F7E78
|
||||
A19CA69EFF5C57400E3B3A0AD66CE0978214D13BAF4E9AC60752F7B155E2DE4D
|
||||
CE3"
|
||||
|
||||
] in
|
||||
("public key matches", `Quick, pub_rfc) ::
|
||||
("public key compression and decompression", `Quick, pub_key_compression (module P521.Dsa)) ::
|
||||
List.mapi (fun i c -> "RFC 6979 A.2.7 " ^ string_of_int i, `Quick, c) cases
|
||||
|
||||
let x25519 () =
|
||||
(* RFC 7748, 6.1 *)
|
||||
let a = of_hex "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a"
|
||||
and apub = of_hex "8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a"
|
||||
and b = of_hex "5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb"
|
||||
and bpub = of_hex "de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f"
|
||||
and shared = of_hex "4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742"
|
||||
in
|
||||
let of_octets cs = match X25519.secret_of_octets cs with
|
||||
| Ok (a, b) -> a, b
|
||||
| Error _ -> Alcotest.fail "couldn't decode secret"
|
||||
in
|
||||
let apriv, apub' = of_octets a in
|
||||
Alcotest.(check bool __LOC__ true (String.equal apub apub'));
|
||||
let bpriv, bpub' = of_octets b in
|
||||
Alcotest.(check bool __LOC__ true (String.equal bpub bpub'));
|
||||
(match X25519.key_exchange apriv bpub with
|
||||
| Ok shared' ->
|
||||
Alcotest.(check bool __LOC__ true (String.equal shared shared'))
|
||||
| Error e ->
|
||||
Alcotest.failf "X25519 key exchange apriv bpub failed %a" pp_error e);
|
||||
match X25519.key_exchange bpriv apub with
|
||||
| Ok shared' ->
|
||||
Alcotest.(check bool __LOC__ true (String.equal shared shared'))
|
||||
| Error e ->
|
||||
Alcotest.failf "X25519 key exchange bpriv apub failed %a" pp_error e
|
||||
|
||||
let ed25519 =
|
||||
let test secret public msg signature =
|
||||
Alcotest.(
|
||||
check string "public key is ok" (Ed25519.pub_to_octets public)
|
||||
Ed25519.(pub_to_octets (pub_of_priv secret)));
|
||||
Alcotest.(check string "signature is ok" signature (Ed25519.sign ~key:secret msg));
|
||||
Alcotest.(check bool "verify is ok" true
|
||||
(Ed25519.verify ~key:public signature ~msg))
|
||||
in
|
||||
let case i ~secret ~public ~msg ~signature =
|
||||
"RFC 8032 " ^ string_of_int i, `Quick, fun () ->
|
||||
let s =
|
||||
match Ed25519.priv_of_octets (of_hex secret) with
|
||||
| Ok p ->
|
||||
Alcotest.(check string "private key encoding is good"
|
||||
(of_hex secret) (Ed25519.priv_to_octets p));
|
||||
p
|
||||
| Error _ -> Alcotest.fail "failed to decode private key"
|
||||
and p =
|
||||
match Ed25519.pub_of_octets (of_hex public) with
|
||||
| Ok p ->
|
||||
Alcotest.(check string "public key encoding is good"
|
||||
(of_hex public) (Ed25519.pub_to_octets p));
|
||||
p
|
||||
| Error _ -> Alcotest.fail "failed to decode public key"
|
||||
and m = of_hex msg
|
||||
and si = of_hex signature
|
||||
in
|
||||
test s p m si
|
||||
in
|
||||
[
|
||||
case 1
|
||||
~secret:
|
||||
"9d61b19deffd5a60ba844af492ec2cc4 4449c5697b326919703bac031cae7f60"
|
||||
~public:
|
||||
"d75a980182b10ab7d54bfed3c964073a 0ee172f3daa62325af021a68f707511a"
|
||||
~msg:""
|
||||
~signature:
|
||||
{|
|
||||
e5564300c360ac729086e2cc806e828a
|
||||
84877f1eb8e5d974d873e06522490155
|
||||
5fb8821590a33bacc61e39701cf9b46b
|
||||
d25bf5f0595bbe24655141438e7a100b
|
||||
|};
|
||||
case 2
|
||||
~secret:
|
||||
"4ccd089b28ff96da9db6c346ec114e0f 5b8a319f35aba624da8cf6ed4fb8a6fb"
|
||||
~public:
|
||||
"3d4017c3e843895a92b70aa74d1b7ebc 9c982ccf2ec4968cc0cd55f12af4660c"
|
||||
~msg:"72"
|
||||
~signature:
|
||||
{|
|
||||
92a009a9f0d4cab8720e820b5f642540
|
||||
a2b27b5416503f8fb3762223ebdb69da
|
||||
085ac1e43e15996e458f3613d0f11d8c
|
||||
387b2eaeb4302aeeb00d291612bb0c00
|
||||
|};
|
||||
case 3
|
||||
~secret:
|
||||
"c5aa8df43f9f837bedb7442f31dcb7b1 66d38535076f094b85ce3a2e0b4458f7"
|
||||
~public:
|
||||
"fc51cd8e6218a1a38da47ed00230f058 0816ed13ba3303ac5deb911548908025"
|
||||
~msg:"af82"
|
||||
~signature:
|
||||
{|
|
||||
6291d657deec24024827e69c3abe01a3
|
||||
0ce548a284743a445e3680d7db5ac3ac
|
||||
18ff9b538d16f290ae67f760984dc659
|
||||
4a7c15e9716ed28dc027beceea1ec40a
|
||||
|};
|
||||
case 4
|
||||
~secret:
|
||||
"f5e5767cf153319517630f226876b86c 8160cc583bc013744c6bf255f5cc0ee5"
|
||||
~public:
|
||||
"278117fc144c72340f67d0f2316e8386 ceffbf2b2428c9c51fef7c597f1d426e"
|
||||
~msg:
|
||||
{|
|
||||
08b8b2b733424243760fe426a4b54908
|
||||
632110a66c2f6591eabd3345e3e4eb98
|
||||
fa6e264bf09efe12ee50f8f54e9f77b1
|
||||
e355f6c50544e23fb1433ddf73be84d8
|
||||
79de7c0046dc4996d9e773f4bc9efe57
|
||||
38829adb26c81b37c93a1b270b20329d
|
||||
658675fc6ea534e0810a4432826bf58c
|
||||
941efb65d57a338bbd2e26640f89ffbc
|
||||
1a858efcb8550ee3a5e1998bd177e93a
|
||||
7363c344fe6b199ee5d02e82d522c4fe
|
||||
ba15452f80288a821a579116ec6dad2b
|
||||
3b310da903401aa62100ab5d1a36553e
|
||||
06203b33890cc9b832f79ef80560ccb9
|
||||
a39ce767967ed628c6ad573cb116dbef
|
||||
efd75499da96bd68a8a97b928a8bbc10
|
||||
3b6621fcde2beca1231d206be6cd9ec7
|
||||
aff6f6c94fcd7204ed3455c68c83f4a4
|
||||
1da4af2b74ef5c53f1d8ac70bdcb7ed1
|
||||
85ce81bd84359d44254d95629e9855a9
|
||||
4a7c1958d1f8ada5d0532ed8a5aa3fb2
|
||||
d17ba70eb6248e594e1a2297acbbb39d
|
||||
502f1a8c6eb6f1ce22b3de1a1f40cc24
|
||||
554119a831a9aad6079cad88425de6bd
|
||||
e1a9187ebb6092cf67bf2b13fd65f270
|
||||
88d78b7e883c8759d2c4f5c65adb7553
|
||||
878ad575f9fad878e80a0c9ba63bcbcc
|
||||
2732e69485bbc9c90bfbd62481d9089b
|
||||
eccf80cfe2df16a2cf65bd92dd597b07
|
||||
07e0917af48bbb75fed413d238f5555a
|
||||
7a569d80c3414a8d0859dc65a46128ba
|
||||
b27af87a71314f318c782b23ebfe808b
|
||||
82b0ce26401d2e22f04d83d1255dc51a
|
||||
ddd3b75a2b1ae0784504df543af8969b
|
||||
e3ea7082ff7fc9888c144da2af58429e
|
||||
c96031dbcad3dad9af0dcbaaaf268cb8
|
||||
fcffead94f3c7ca495e056a9b47acdb7
|
||||
51fb73e666c6c655ade8297297d07ad1
|
||||
ba5e43f1bca32301651339e22904cc8c
|
||||
42f58c30c04aafdb038dda0847dd988d
|
||||
cda6f3bfd15c4b4c4525004aa06eeff8
|
||||
ca61783aacec57fb3d1f92b0fe2fd1a8
|
||||
5f6724517b65e614ad6808d6f6ee34df
|
||||
f7310fdc82aebfd904b01e1dc54b2927
|
||||
094b2db68d6f903b68401adebf5a7e08
|
||||
d78ff4ef5d63653a65040cf9bfd4aca7
|
||||
984a74d37145986780fc0b16ac451649
|
||||
de6188a7dbdf191f64b5fc5e2ab47b57
|
||||
f7f7276cd419c17a3ca8e1b939ae49e4
|
||||
88acba6b965610b5480109c8b17b80e1
|
||||
b7b750dfc7598d5d5011fd2dcc5600a3
|
||||
2ef5b52a1ecc820e308aa342721aac09
|
||||
43bf6686b64b2579376504ccc493d97e
|
||||
6aed3fb0f9cd71a43dd497f01f17c0e2
|
||||
cb3797aa2a2f256656168e6c496afc5f
|
||||
b93246f6b1116398a346f1a641f3b041
|
||||
e989f7914f90cc2c7fff357876e506b5
|
||||
0d334ba77c225bc307ba537152f3f161
|
||||
0e4eafe595f6d9d90d11faa933a15ef1
|
||||
369546868a7f3a45a96768d40fd9d034
|
||||
12c091c6315cf4fde7cb68606937380d
|
||||
b2eaaa707b4c4185c32eddcdd306705e
|
||||
4dc1ffc872eeee475a64dfac86aba41c
|
||||
0618983f8741c5ef68d3a101e8a3b8ca
|
||||
c60c905c15fc910840b94c00a0b9d0
|
||||
|}
|
||||
~signature:
|
||||
{|
|
||||
0aab4c900501b3e24d7cdf4663326a3a
|
||||
87df5e4843b2cbdb67cbf6e460fec350
|
||||
aa5371b1508f9f4528ecea23c436d94b
|
||||
5e8fcd4f681e30a6ac00a9704a188a03
|
||||
|};
|
||||
case 5
|
||||
~secret:
|
||||
"833fe62409237b9d62ec77587520911e 9a759cec1d19755b7da901b96dca3d42"
|
||||
~public:
|
||||
"ec172b93ad5e563bf4932c70e1245034 c35467ef2efd4d64ebf819683467e2bf"
|
||||
~msg:
|
||||
{|
|
||||
ddaf35a193617abacc417349ae204131
|
||||
12e6fa4e89a97ea20a9eeee64b55d39a
|
||||
2192992a274fc1a836ba3c23a3feebbd
|
||||
454d4423643ce80e2a9ac94fa54ca49f
|
||||
|}
|
||||
~signature:
|
||||
{|
|
||||
dc2a4459e7369633a52b1bf277839a00
|
||||
201009a3efbf3ecb69bea2186c26b589
|
||||
09351fc9ac90b3ecfdfbc7c66431e030
|
||||
3dca179c138ac17ad9bef1177331a704
|
||||
|};
|
||||
]
|
||||
|
||||
let p521_regression () =
|
||||
let key = of_hex
|
||||
"04 01 e4 f8 8a 40 3d fe 2f 65 a0 20 50 01 9b 87
|
||||
86 2c 30 2f 64 58 de 68 63 ab 92 72 88 04 c6 20
|
||||
7b 6f 9a 52 95 2d ff c7 80 df 50 44 b1 c4 91 e3
|
||||
a7 65 39 e6 9c cf ed d2 2a eb 47 84 ea 0f 3d 05
|
||||
dd 25 0e 00 95 6e 19 fb 7f b7 ce 47 5a 59 01 5f
|
||||
35 33 fc 85 ac 34 1a b0 7a 67 86 e8 3e 31 fe 38
|
||||
35 5c bb a1 b5 74 f4 47 a3 4c 0a f0 5f 6d 68 47
|
||||
85 0f e9 79 74 23 e8 75 47 6e 2b e5 ea 1b 0a 36
|
||||
b9 c3 94 ca b0"
|
||||
and data = of_hex
|
||||
"a8 98 57 b9 3f 58 02 c7 9a 37 e2 d7 89 d8 0b f4
|
||||
2d 84 c2 24 7c 7f ff 5f 7b 65 c5 17 cf 79 7d 36
|
||||
ff d3 9d 47 5e 68 90 57 f1 61 48 18 04 c3 fe ee
|
||||
59 b2 15 2d 75 8b 9a 3c 52 60 96 5c 52 a8 55 9c"
|
||||
and sigr = of_hex
|
||||
"3a 2c 99 0b 61 a1 da 06 20 bf 6c fe 1f d3 f8 2a
|
||||
cb f1 e5 0f 78 11 61 58 22 e4 a0 5f 18 81 8d 98
|
||||
f8 7a ca 8b f8 f8 cc b8 95 f7 6f 03 54 1b 66 6e
|
||||
cf c5 cb f1 7b 48 82 d2 c3 0e 0e 1b b4 ad e6 a4
|
||||
5c"
|
||||
and sigs = of_hex
|
||||
"01 7b 8c 82 a5 aa 80 c5 ee 23 0f 91 55 89 a7 b0
|
||||
3c 46 7f 56 ff b4 52 89 52 99 59 1e 5e b7 f2 c1
|
||||
df f8 a0 4f d3 dd 1d f0 07 78 3a 2f 29 d6 61 61
|
||||
55 dc 3b be 14 82 93 75 c2 0d be 7e ca 50 e4 3c
|
||||
98 88"
|
||||
in
|
||||
match P521.Dsa.pub_of_octets key with
|
||||
| Ok key ->
|
||||
Alcotest.check Alcotest.bool "regression 1" true
|
||||
(P521.Dsa.verify ~key (sigr, sigs) data)
|
||||
| Error _ -> Alcotest.fail "regression failed"
|
||||
|
||||
let () =
|
||||
Mirage_crypto_rng_unix.use_default ();
|
||||
Alcotest.run "EC"
|
||||
[
|
||||
("P256 Key exchange", key_exchange);
|
||||
("P256 Low level scalar mult", scalar_mult);
|
||||
("P256 Point validation", point_validation);
|
||||
("P256 Scalar validation when generating", scalar_validation);
|
||||
("ECDSA NIST", ecdsa);
|
||||
("ECDSA RFC 6979 P256", ecdsa_rfc6979_p256);
|
||||
("ECDSA RFC 6979 P384", ecdsa_rfc6979_p384);
|
||||
("ECDSA RFC 6979 P521", ecdsa_rfc6979_p521);
|
||||
("X25519", [ "RFC 7748", `Quick, x25519 ]);
|
||||
("ED25519", ed25519);
|
||||
("ECDSA P521 regression", [ "regreesion1", `Quick, p521_regression ]);
|
||||
]
|
||||
314
unikernel/duniverse/mirage-crypto/tests/test_ec_wycheproof.ml
Normal file
314
unikernel/duniverse/mirage-crypto/tests/test_ec_wycheproof.ml
Normal file
|
|
@ -0,0 +1,314 @@
|
|||
open Wycheproof
|
||||
|
||||
open Mirage_crypto_ec
|
||||
|
||||
let ( let* ) = Result.bind
|
||||
|
||||
let hex = Alcotest.testable Wycheproof.pp_hex Wycheproof.equal_hex
|
||||
|
||||
module Asn = struct
|
||||
let parse_point curve s =
|
||||
let seq2 a b = Asn.S.(sequence2 (required a) (required b)) in
|
||||
let term = Asn.S.(seq2 (seq2 oid oid) bit_string_octets) in
|
||||
let ec_public_key = Asn.OID.(base 1 2 <|| [ 840; 10045; 2; 1 ]) in
|
||||
let prime_oid = match curve with
|
||||
| "secp256r1" -> Asn.OID.(base 1 2 <|| [ 840; 10045; 3; 1; 7 ])
|
||||
| "secp384r1" -> Asn.OID.(base 1 3 <|| [ 132; 0; 34 ])
|
||||
| "secp521r1" -> Asn.OID.(base 1 3 <|| [ 132; 0; 35 ])
|
||||
| _ -> assert false
|
||||
in
|
||||
match Asn.decode (Asn.codec Asn.ber term) s with
|
||||
| Error _ -> Error "ASN1 parse error"
|
||||
| Ok (((oid1, oid2), data), rest) ->
|
||||
if String.length rest <> 0 then Error "ASN1 leftover"
|
||||
else if not (Asn.OID.equal oid1 ec_public_key) then
|
||||
Error "ASN1: wrong oid 1"
|
||||
else if not (Asn.OID.equal oid2 prime_oid) then Error "ASN1: wrong oid 2"
|
||||
else Ok data
|
||||
|
||||
let parse_signature cs =
|
||||
let asn = Asn.S.(sequence2 (required unsigned_integer) (required unsigned_integer)) in
|
||||
match Asn.(decode (codec der asn) cs) with
|
||||
| Error _ -> Error "ASN1 parse error"
|
||||
| Ok (r_s, rest) ->
|
||||
if String.length rest <> 0 then Error "ASN1 leftover"
|
||||
else
|
||||
Ok r_s
|
||||
end
|
||||
|
||||
let to_string_result ~pp_error = function
|
||||
| Ok _ as ok -> ok
|
||||
| Error e ->
|
||||
let msg = Format.asprintf "%a" pp_error e in
|
||||
Error msg
|
||||
|
||||
let pad ~total_len buf =
|
||||
match total_len - String.length buf with
|
||||
| 0 -> Ok buf
|
||||
| n when n < 0 ->
|
||||
let is_zero = ref true in
|
||||
for i = 0 to abs n - 1 do
|
||||
if Bytes.(get_uint8 (Bytes.unsafe_of_string buf) i) <> 0 then
|
||||
is_zero := false
|
||||
done;
|
||||
if !is_zero then
|
||||
Ok (String.sub buf (abs n) total_len)
|
||||
else
|
||||
Error "input is too long"
|
||||
| pad_len ->
|
||||
Ok (String.make pad_len '\000' ^ buf)
|
||||
|
||||
let len = function
|
||||
| "secp256r1" -> 32
|
||||
| "secp384r1" -> 48
|
||||
| "secp521r1" -> 66
|
||||
| _ -> assert false
|
||||
|
||||
let parse_secret curve s =
|
||||
let total_len = len curve in
|
||||
pad ~total_len s
|
||||
|
||||
type test = {
|
||||
public_key : string;
|
||||
raw_private_key : string;
|
||||
expected : string;
|
||||
}
|
||||
|
||||
let perform_key_exchange curve ~public_key ~raw_private_key =
|
||||
to_string_result ~pp_error
|
||||
(match curve with
|
||||
| "secp256r1" ->
|
||||
begin match P256.Dh.secret_of_octets raw_private_key with
|
||||
| Ok (p, _) -> P256.Dh.key_exchange p public_key
|
||||
| Error _ -> assert false
|
||||
end
|
||||
| "secp384r1" ->
|
||||
begin match P384.Dh.secret_of_octets raw_private_key with
|
||||
| Ok (p, _) -> P384.Dh.key_exchange p public_key
|
||||
| Error _ -> assert false
|
||||
end
|
||||
| "secp521r1" ->
|
||||
begin match P521.Dh.secret_of_octets raw_private_key with
|
||||
| Ok (p, _) -> P521.Dh.key_exchange p public_key
|
||||
| Error _ -> assert false
|
||||
end
|
||||
| _ -> assert false)
|
||||
|
||||
let interpret_test ~tcId curve { public_key; raw_private_key; expected } () =
|
||||
match perform_key_exchange curve ~public_key ~raw_private_key with
|
||||
| Ok got -> Alcotest.check hex __LOC__ expected got
|
||||
| Error err ->
|
||||
Printf.ksprintf (fun s -> Alcotest.fail s) "While parsing %d: %s" tcId err
|
||||
|
||||
type invalid_test = { public : string; private_ : string }
|
||||
|
||||
let is_ok = function Ok _ -> true | Error _ -> false
|
||||
|
||||
let interpret_invalid_test curve { public; private_ } () =
|
||||
let result =
|
||||
let* public_key = Asn.parse_point curve public in
|
||||
let* raw_private_key = parse_secret curve private_ in
|
||||
perform_key_exchange curve ~public_key ~raw_private_key
|
||||
in
|
||||
Alcotest.check Alcotest.bool __LOC__ false (is_ok result)
|
||||
|
||||
type strategy = Test of test | Invalid_test of invalid_test | Skip
|
||||
|
||||
let make_ecdh_test curve (test : ecdh_test) =
|
||||
let ignored_flags = ["UnnamedCurve"] in
|
||||
let curve_compression_test curve =
|
||||
let curves = ["secp256r1"; "secp384r1"; "secp521r1"] in
|
||||
test.tcId = 2 && List.exists (fun x -> String.equal x curve) curves
|
||||
in
|
||||
match test.result with
|
||||
| _ when has_ignored_flag test ~ignored_flags -> Ok Skip
|
||||
| Invalid ->
|
||||
Ok (Invalid_test { public = test.public; private_ = test.private_ })
|
||||
| Acceptable when curve_compression_test curve ->
|
||||
let* public_key = Asn.parse_point curve test.public in
|
||||
let* raw_private_key = parse_secret curve test.private_ in
|
||||
Ok (Test { public_key; raw_private_key; expected = test.shared })
|
||||
| Acceptable -> Ok Skip
|
||||
| Valid ->
|
||||
let* public_key = Asn.parse_point curve test.public in
|
||||
let* raw_private_key = parse_secret curve test.private_ in
|
||||
Ok (Test { public_key; raw_private_key; expected = test.shared })
|
||||
|
||||
let to_ecdh_tests curve (x : ecdh_test) =
|
||||
let name = Printf.sprintf "%d - %s" x.tcId x.comment in
|
||||
match make_ecdh_test curve x with
|
||||
| Ok (Test t) -> [ (name, `Quick, interpret_test ~tcId:x.tcId curve t) ]
|
||||
| Ok (Invalid_test t) -> [ (name, `Quick, interpret_invalid_test curve t) ]
|
||||
| Ok Skip -> []
|
||||
| Error e -> Printf.ksprintf failwith "While parsing %d: %s" x.tcId e
|
||||
|
||||
let ecdh_tests file =
|
||||
let data = load_file_exn file in
|
||||
let groups : ecdh_test_group list =
|
||||
List.map ecdh_test_group_exn data.testGroups
|
||||
in
|
||||
List.concat_map (fun (group : ecdh_test_group) ->
|
||||
List.concat_map (to_ecdh_tests group.curve) group.tests)
|
||||
groups
|
||||
|
||||
let make_ecdsa_test curve key hash (tst : dsa_test) =
|
||||
let name = Printf.sprintf "%d - %s" tst.tcId tst.comment in
|
||||
let size = len curve in
|
||||
let msg =
|
||||
let dgst =
|
||||
match hash with
|
||||
| "SHA-256" -> Digestif.SHA256.(digest_string tst.msg |> to_raw_string)
|
||||
| "SHA-384" -> Digestif.SHA384.(digest_string tst.msg |> to_raw_string)
|
||||
| "SHA-512" -> Digestif.SHA512.(digest_string tst.msg |> to_raw_string)
|
||||
| "SHA-224" -> Digestif.SHA224.(digest_string tst.msg |> to_raw_string)
|
||||
| _ -> assert false
|
||||
in
|
||||
String.sub dgst 0 (min size (String.length dgst))
|
||||
in
|
||||
let verified (r,s) =
|
||||
match curve with
|
||||
| "secp256r1" ->
|
||||
begin match P256.Dsa.pub_of_octets key with
|
||||
| Ok key -> P256.Dsa.verify ~key (r, s) msg
|
||||
| Error _ -> assert false
|
||||
end
|
||||
| "secp384r1" ->
|
||||
begin match P384.Dsa.pub_of_octets key with
|
||||
| Ok key -> P384.Dsa.verify ~key (r, s) msg
|
||||
| Error _ -> assert false
|
||||
end
|
||||
| "secp521r1" ->
|
||||
begin match P521.Dsa.pub_of_octets key with
|
||||
| Ok key -> P521.Dsa.verify ~key (r, s) msg
|
||||
| Error _ -> assert false
|
||||
end
|
||||
| _ -> assert false
|
||||
in
|
||||
match tst.result with
|
||||
| Acceptable
|
||||
| Invalid ->
|
||||
let f () =
|
||||
match Asn.parse_signature tst.sig_ with
|
||||
| Ok (r, s) -> Alcotest.(check bool __LOC__ false (verified (r, s)))
|
||||
| Error _s -> ()
|
||||
in
|
||||
name, `Quick, f
|
||||
| Valid ->
|
||||
let f () =
|
||||
match Asn.parse_signature tst.sig_ with
|
||||
| Ok (r, s) -> Alcotest.(check bool __LOC__ true (verified (r, s)))
|
||||
| Error s -> Alcotest.fail s
|
||||
in
|
||||
name, `Quick, f
|
||||
|
||||
let to_ecdsa_tests (x : ecdsa_test_group) =
|
||||
List.map
|
||||
(make_ecdsa_test x.key.curve x.key.uncompressed x.sha)
|
||||
x.tests
|
||||
|
||||
let ecdsa_tests file =
|
||||
let data = load_file_exn file in
|
||||
let groups : ecdsa_test_group list =
|
||||
List.map ecdsa_test_group_exn data.testGroups
|
||||
in
|
||||
List.concat_map to_ecdsa_tests groups
|
||||
|
||||
let to_x25519_test (x : ecdh_test) =
|
||||
let name = Printf.sprintf "%d - %s" x.tcId x.comment
|
||||
and priv =
|
||||
match X25519.secret_of_octets x.private_ with
|
||||
| Ok (p, _) -> p
|
||||
| Error _ -> assert false
|
||||
in
|
||||
match x.result with
|
||||
| Acceptable ->
|
||||
let f () =
|
||||
match
|
||||
X25519.key_exchange priv x.public,
|
||||
has_ignored_flag x ~ignored_flags:[ "LowOrderPublic" ]
|
||||
with
|
||||
| Ok _, true -> Alcotest.fail "acceptable should have errored"
|
||||
| Ok r, false ->
|
||||
Alcotest.(check bool __LOC__ true (String.equal r x.shared))
|
||||
| Error _, true -> ()
|
||||
| Error e, false -> Alcotest.failf "acceptable errored %a" pp_error e
|
||||
in
|
||||
name, `Quick, f
|
||||
| Invalid ->
|
||||
let f () =
|
||||
match X25519.key_exchange priv x.public with
|
||||
| Ok r -> Alcotest.(check bool __LOC__ false (String.equal r x.shared))
|
||||
| Error e -> Alcotest.failf "invalid errored %a" pp_error e
|
||||
in
|
||||
name, `Quick, f
|
||||
| Valid ->
|
||||
let f () =
|
||||
match X25519.key_exchange priv x.public with
|
||||
| Ok r -> Alcotest.(check bool __LOC__ true (String.equal r x.shared))
|
||||
| Error e -> Alcotest.failf "valid errored %a" pp_error e
|
||||
in
|
||||
name, `Quick, f
|
||||
|
||||
let x25519_tests =
|
||||
let data = load_file_exn "x25519_test.json" in
|
||||
let groups : ecdh_test_group list =
|
||||
List.map ecdh_test_group_exn data.testGroups
|
||||
in
|
||||
List.concat_map (fun (group : ecdh_test_group) ->
|
||||
List.map to_x25519_test group.tests)
|
||||
groups
|
||||
|
||||
let to_ed25519_test (priv, pub) (x : dsa_test) =
|
||||
let name = Printf.sprintf "%d - %s" x.tcId x.comment in
|
||||
match x.result with
|
||||
| Invalid ->
|
||||
let f () =
|
||||
Alcotest.(check bool __LOC__ false (Ed25519.verify ~key:pub x.sig_ ~msg:x.msg));
|
||||
let s = Ed25519.sign ~key:priv x.msg in
|
||||
Alcotest.(check bool __LOC__ false (String.equal s x.sig_))
|
||||
in
|
||||
name, `Quick, f
|
||||
| Valid ->
|
||||
let f () =
|
||||
Alcotest.(check bool __LOC__ true (Ed25519.verify ~key:pub x.sig_ ~msg:x.msg));
|
||||
let s = Ed25519.sign ~key:priv x.msg in
|
||||
Alcotest.(check bool __LOC__ true (String.equal s x.sig_))
|
||||
in
|
||||
name, `Quick, f
|
||||
| Acceptable -> assert false
|
||||
|
||||
let to_ed25519_keys (key : eddsa_key) =
|
||||
match Ed25519.priv_of_octets key.sk, Ed25519.pub_of_octets key.pk with
|
||||
| Ok priv, Ok pub ->
|
||||
assert (String.equal Ed25519.(pub_to_octets (pub_of_priv priv)) key.pk);
|
||||
priv, pub
|
||||
| _ -> assert false
|
||||
|
||||
let ed25519_tests =
|
||||
let data = load_file_exn "eddsa_test.json" in
|
||||
let groups : eddsa_test_group list =
|
||||
List.map eddsa_test_group_exn data.testGroups
|
||||
in
|
||||
List.concat_map (fun (group : eddsa_test_group) ->
|
||||
let keys = to_ed25519_keys group.key in
|
||||
List.map (to_ed25519_test keys) group.tests)
|
||||
groups
|
||||
|
||||
let () =
|
||||
Alcotest.run "Wycheproof NIST curves" [
|
||||
("ECDH P256 test vectors", ecdh_tests "ecdh_secp256r1_test.json") ;
|
||||
("ECDSA P256 test vectors (SHA256)",
|
||||
ecdsa_tests "ecdsa_secp256r1_sha256_test.json") ;
|
||||
("ECDSA P256 test vectors (SHA512)",
|
||||
ecdsa_tests "ecdsa_secp256r1_sha512_test.json") ;
|
||||
("ECDH P384 test vectors", ecdh_tests "ecdh_secp384r1_test.json") ;
|
||||
("ECDSA P384 test vectors (SHA384)",
|
||||
ecdsa_tests "ecdsa_secp384r1_sha384_test.json") ;
|
||||
("ECDSA P384 test vectors (SHA512)",
|
||||
ecdsa_tests "ecdsa_secp384r1_sha512_test.json") ;
|
||||
("ECDH P521 test vectors", ecdh_tests "ecdh_secp521r1_test.json") ;
|
||||
("ECDSA P521 test vectors (SHA512)",
|
||||
ecdsa_tests "ecdsa_secp521r1_sha512_test.json") ;
|
||||
("X25519 test vectors", x25519_tests) ;
|
||||
("ED25519 test vectors", ed25519_tests) ;
|
||||
]
|
||||
47
unikernel/duniverse/mirage-crypto/tests/test_entropy.ml
Normal file
47
unikernel/duniverse/mirage-crypto/tests/test_entropy.ml
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
|
||||
let data = ref ""
|
||||
|
||||
let cpu_bootstrap_check () =
|
||||
match Mirage_crypto_rng.Entropy.cpu_rng_bootstrap with
|
||||
| Error `Not_supported -> print_endline "no CPU RNG available"
|
||||
| Ok cpu_rng_bootstrap ->
|
||||
match cpu_rng_bootstrap 1 with
|
||||
| exception Failure _ -> print_endline "bad CPU RNG"
|
||||
| data' ->
|
||||
data := data';
|
||||
for i = 0 to 10 do
|
||||
try
|
||||
let data' = cpu_rng_bootstrap 1 in
|
||||
if String.equal !data data' then begin
|
||||
Ohex.pp Format.std_formatter data';
|
||||
failwith ("same data from CPU bootstrap at " ^ string_of_int i);
|
||||
end;
|
||||
data := data'
|
||||
with Failure _ -> print_endline ("CPU RNG failed at " ^ string_of_int i)
|
||||
done
|
||||
|
||||
let whirlwind_bootstrap_check () =
|
||||
for i = 0 to 10 do
|
||||
let data' = Mirage_crypto_rng.Entropy.whirlwind_bootstrap 1 in
|
||||
if String.equal !data data' then begin
|
||||
Ohex.pp Format.std_formatter data';
|
||||
failwith ("same data from whirlwind bootstrap at " ^ string_of_int i);
|
||||
end;
|
||||
data := data'
|
||||
done
|
||||
|
||||
let timer_check () =
|
||||
for i = 0 to 10 do
|
||||
let data' = Mirage_crypto_rng.Entropy.interrupt_hook () in
|
||||
if String.equal !data data' then begin
|
||||
Ohex.pp Format.std_formatter data';
|
||||
failwith ("same data from timer at " ^ string_of_int i);
|
||||
end;
|
||||
data := data'
|
||||
done
|
||||
|
||||
let () =
|
||||
timer_check ();
|
||||
cpu_bootstrap_check ();
|
||||
whirlwind_bootstrap_check ();
|
||||
print_endline "test entropy OK"
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
open Lwt.Infix
|
||||
|
||||
module Printing_rng = struct
|
||||
type g = unit
|
||||
|
||||
let block = 16
|
||||
|
||||
let create ?time:_ () = ()
|
||||
|
||||
let generate_into ~g:_ _buf ~off:_ _len = assert false
|
||||
|
||||
let reseed ~g:_ data =
|
||||
Format.printf "reseeding:@.%a@.%!" (Ohex.pp_hexdump ()) data
|
||||
|
||||
let accumulate ~g:_ source =
|
||||
let print data =
|
||||
Format.printf "accumulate: (src: %a) %a@.%!"
|
||||
Mirage_crypto_rng.Entropy.pp_source source Ohex.pp data
|
||||
in
|
||||
`Acc print
|
||||
|
||||
let seeded ~g:_ = true
|
||||
let pools = 1
|
||||
end
|
||||
|
||||
let with_entropy act =
|
||||
Mirage_crypto_rng_mirage.initialize (module Printing_rng) >>= fun () ->
|
||||
Format.printf "entropy sources: %a@,%!"
|
||||
(fun ppf -> List.iter (fun x ->
|
||||
Mirage_crypto_rng.Entropy.pp_source ppf x;
|
||||
Format.pp_print_space ppf ()))
|
||||
(Mirage_crypto_rng.Entropy.sources ());
|
||||
act ()
|
||||
|
||||
let () =
|
||||
Unix_os.(Main.run (with_entropy (fun () -> Time.sleep_ns (Duration.of_sec 3))))
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
module Printing_rng = struct
|
||||
type g = unit
|
||||
|
||||
let block = 16
|
||||
let create ?time:_ () = ()
|
||||
let generate_into ~g:_ _buf ~off:_ _len = assert false
|
||||
let seeded ~g:_ = true
|
||||
let pools = 1
|
||||
|
||||
let reseed ~g:_ data =
|
||||
Format.printf "reseeding:@.%a@.%!" (Ohex.pp_hexdump ()) data
|
||||
|
||||
let accumulate ~g:_ source =
|
||||
let print data =
|
||||
Format.printf "accumulate: (src: %a) %a@.%!"
|
||||
Mirage_crypto_rng.Entropy.pp_source source Ohex.pp data
|
||||
in
|
||||
`Acc print
|
||||
end
|
||||
|
||||
let () =
|
||||
Miou_unix.run @@ fun () ->
|
||||
let rng = Mirage_crypto_rng_miou_unix.initialize (module Printing_rng) in
|
||||
Format.printf "entropy sources: %a@,%!"
|
||||
(fun ppf -> List.iter (fun x ->
|
||||
Mirage_crypto_rng.Entropy.pp_source ppf x;
|
||||
Format.pp_print_space ppf ()))
|
||||
(Mirage_crypto_rng.Entropy.sources ());
|
||||
let sleep = Duration.(of_sec 2 |> to_f) in
|
||||
Miou_unix.sleep sleep;
|
||||
Mirage_crypto_rng_miou_unix.kill rng
|
||||
16
unikernel/duniverse/mirage-crypto/tests/test_miou_rng.ml
Normal file
16
unikernel/duniverse/mirage-crypto/tests/test_miou_rng.ml
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
let () = Miou_unix.run @@ fun () ->
|
||||
let rng = Mirage_crypto_rng_miou_unix.(initialize (module Pfortuna)) in
|
||||
let random_num = Mirage_crypto_rng.generate 32 in
|
||||
assert (String.length random_num = 32);
|
||||
Printf.printf "32 bit random number: %s\n%!" (Ohex.encode random_num);
|
||||
let random_num = Mirage_crypto_rng.generate 16 in
|
||||
assert (String.length random_num = 16);
|
||||
Printf.printf "16 bit random number: %s\n%!" (Ohex.encode random_num);
|
||||
(* NOTE(dinosaure): the test below shows that [Pfortuna] is domain-safe when
|
||||
run with TSan. If we use the Fortuna engine, TSan will report invalid
|
||||
accesses between the domain that seeds the RNG and [dom0]. *)
|
||||
for _ = 0 to 4 do
|
||||
let _ = Mirage_crypto_rng.generate 16 in
|
||||
Miou_unix.sleep 0.5;
|
||||
done;
|
||||
Mirage_crypto_rng_miou_unix.kill rng
|
||||
49
unikernel/duniverse/mirage-crypto/tests/test_numeric.ml
Normal file
49
unikernel/duniverse/mirage-crypto/tests/test_numeric.ml
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
open OUnit2
|
||||
|
||||
open Mirage_crypto.Uncommon
|
||||
open Mirage_crypto_pk
|
||||
|
||||
open Test_common
|
||||
|
||||
let n_encode_decode_selftest ~typ ~bound n =
|
||||
typ ^ "selftest" >:: times ~n @@ fun _ ->
|
||||
let r = Z_extra.gen bound in
|
||||
let s = Z_extra.(of_octets_be @@ to_octets_be r)
|
||||
and t = Z_extra.(of_octets_be @@ to_octets_be ~size:24 r) in
|
||||
assert_equal r s;
|
||||
assert_equal r t
|
||||
|
||||
let n_decode_reencode_selftest ~typ ~bytes n =
|
||||
typ ^ " selftest" >:: times ~n @@ fun _ ->
|
||||
let cs = Mirage_crypto_rng.generate bytes in
|
||||
let cs' = Z_extra.(to_octets_be ~size:bytes @@ of_octets_be cs) in
|
||||
assert_oct_equal cs cs'
|
||||
|
||||
let random_n_selftest ~typ n bounds =
|
||||
typ ^ " selftest" >::: (
|
||||
bounds |> List.map @@ fun (lo, hi) ->
|
||||
"selftest" >:: times ~n @@ fun _ ->
|
||||
let x = Z_extra.gen_r lo hi in
|
||||
if x < lo || x >= hi then assert_failure "range error"
|
||||
)
|
||||
|
||||
let int_safe_bytes = Sys.word_size // 8 - 1
|
||||
|
||||
let suite = [
|
||||
"Numeric extraction 1" >::: [
|
||||
n_encode_decode_selftest
|
||||
~typ:"z" ~bound:Z.(of_int64 Int64.max_int) 2000 ;
|
||||
] ;
|
||||
|
||||
"Numeric extraction 2" >::: [
|
||||
n_decode_reencode_selftest ~typ:"z" ~bytes:37 2000 ;
|
||||
];
|
||||
|
||||
"RNG extraction" >::: [
|
||||
random_n_selftest ~typ:"Z" 1000 [
|
||||
Z.(of_int 7, of_int 135);
|
||||
Z.(of_int 0, of_int 536870913);
|
||||
Z.(of_int 0, of_int64 2305843009213693953L)
|
||||
] ;
|
||||
]
|
||||
]
|
||||
13
unikernel/duniverse/mirage-crypto/tests/test_pk_runner.ml
Normal file
13
unikernel/duniverse/mirage-crypto/tests/test_pk_runner.ml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
open OUnit2
|
||||
|
||||
let suite =
|
||||
"All" >::: [
|
||||
"Numeric" >::: Test_numeric.suite;
|
||||
"DHE" >::: Test_dh.suite;
|
||||
"DSA" >::: Test_dsa.suite;
|
||||
"RSA" >::: Test_rsa.suite;
|
||||
]
|
||||
|
||||
let () =
|
||||
Mirage_crypto_rng_unix.use_default ();
|
||||
run_test_tt_main suite
|
||||
109
unikernel/duniverse/mirage-crypto/tests/test_random_runner.ml
Normal file
109
unikernel/duniverse/mirage-crypto/tests/test_random_runner.ml
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
open OUnit2
|
||||
|
||||
open Mirage_crypto
|
||||
|
||||
open Test_common
|
||||
|
||||
let sample arr =
|
||||
let ix =
|
||||
Randomconv.int ~bound:(Array.length arr) Mirage_crypto_rng.generate
|
||||
in
|
||||
arr.(ix)
|
||||
|
||||
(* randomized selfies *)
|
||||
|
||||
let ecb_selftest (m : (module Block.ECB)) n =
|
||||
let module C = ( val m ) in
|
||||
"selftest" >:: times ~n @@ fun _ ->
|
||||
let data = Mirage_crypto_rng.generate (C.block_size * 8)
|
||||
and key = C.of_secret @@ Mirage_crypto_rng.generate (sample C.key_sizes) in
|
||||
let data' =
|
||||
C.( data |> encrypt ~key |> encrypt ~key
|
||||
|> decrypt ~key |> decrypt ~key ) in
|
||||
assert_oct_equal ~msg:"ecb mismatch" data data'
|
||||
|
||||
let cbc_selftest (m : (module Block.CBC)) n =
|
||||
let module C = ( val m ) in
|
||||
"selftest" >:: times ~n @@ fun _ ->
|
||||
let data = Mirage_crypto_rng.generate (C.block_size * 8)
|
||||
and iv = Mirage_crypto_rng.generate C.block_size
|
||||
and key = C.of_secret @@ Mirage_crypto_rng.generate (sample C.key_sizes) in
|
||||
assert_oct_equal ~msg:"CBC e->e->d->d" data
|
||||
C.( data |> encrypt ~key ~iv |> encrypt ~key ~iv
|
||||
|> decrypt ~key ~iv |> decrypt ~key ~iv );
|
||||
let (d1, d2) =
|
||||
String.sub data 0 (C.block_size * 4),
|
||||
String.sub data (C.block_size * 4) (String.length data - C.block_size * 4)
|
||||
in
|
||||
assert_oct_equal ~msg:"CBC chain"
|
||||
C.(encrypt ~key ~iv data)
|
||||
C.( let e1 = encrypt ~key ~iv d1 in
|
||||
e1 ^ encrypt ~key ~iv:(next_iv ~iv e1) d2)
|
||||
|
||||
let ctr_selftest (m : (module Block.CTR)) n =
|
||||
let module M = (val m) in
|
||||
let bs = M.block_size in
|
||||
"selftest" >:: times ~n @@ fun _ ->
|
||||
let key = M.of_secret @@ Mirage_crypto_rng.generate (sample M.key_sizes)
|
||||
and ctr = Mirage_crypto_rng.generate bs |> M.ctr_of_octets
|
||||
and data = Mirage_crypto_rng.(generate @@ bs + Randomconv.int ~bound:(20 * bs) Mirage_crypto_rng.generate) in
|
||||
let enc = M.encrypt ~key ~ctr data in
|
||||
let dec = M.decrypt ~key ~ctr enc in
|
||||
assert_oct_equal ~msg:"CTR e->d" data dec;
|
||||
let (d1, d2) =
|
||||
let s = bs * Randomconv.int ~bound:(String.length data / bs) Mirage_crypto_rng.generate in
|
||||
String.sub data 0 s, String.sub data s (String.length data - s)
|
||||
in
|
||||
assert_oct_equal ~msg:"CTR chain" enc @@
|
||||
M.encrypt ~key ~ctr d1 ^ M.encrypt ~key ~ctr:(M.next_ctr ~ctr d1) d2
|
||||
|
||||
let ctr_offsets (type c) ~zero (m : (module Block.CTR with type ctr = c)) n =
|
||||
let module M = (val m) in
|
||||
"offsets" >:: fun _ ->
|
||||
let key = M.of_secret @@ Mirage_crypto_rng.generate M.key_sizes.(0) in
|
||||
for i = 0 to n - 1 do
|
||||
let ctr = match i with
|
||||
| 0 -> M.add_ctr zero (-1L)
|
||||
| _ -> Mirage_crypto_rng.generate M.block_size |> M.ctr_of_octets
|
||||
and gap = Randomconv.int ~bound:64 Mirage_crypto_rng.generate in
|
||||
let s1 = M.stream ~key ~ctr ((gap + 1) * M.block_size)
|
||||
and s2 = M.stream ~key ~ctr:(M.add_ctr ctr (Int64.of_int gap)) M.block_size in
|
||||
assert_oct_equal ~msg:"shifted stream"
|
||||
String.(sub s1 (gap * M.block_size) M.block_size) s2
|
||||
done
|
||||
|
||||
let xor_selftest n =
|
||||
"selftest" >:: times ~n @@ fun _ ->
|
||||
|
||||
let n = Randomconv.int ~bound:30 Mirage_crypto_rng.generate in
|
||||
let (x, y, z) = Mirage_crypto_rng.(generate n, generate n, generate n) in
|
||||
|
||||
let xyz = Uncommon.(xor (xor x y) z)
|
||||
and xyz' = Uncommon.(xor x (xor y z)) in
|
||||
let x1 = Uncommon.(xor xyz (xor y z))
|
||||
and x2 = Uncommon.(xor (xor z y) xyz) in
|
||||
|
||||
assert_oct_equal ~msg:"assoc" xyz xyz' ;
|
||||
assert_oct_equal ~msg:"invert" x x1 ;
|
||||
assert_oct_equal ~msg:"commut" x1 x2
|
||||
|
||||
let suite =
|
||||
"All" >::: [
|
||||
"XOR" >::: [ xor_selftest 300 ] ;
|
||||
"3DES-ECB" >::: [ ecb_selftest (module DES.ECB) 100 ] ;
|
||||
|
||||
"3DES-CBC" >::: [ cbc_selftest (module DES.CBC) 100 ] ;
|
||||
|
||||
"3DES-CTR" >::: [ ctr_selftest (module DES.CTR) 100;
|
||||
ctr_offsets (module DES.CTR) 100 ~zero:0L; ] ;
|
||||
|
||||
"AES-ECB" >::: [ ecb_selftest (module AES.ECB) 100 ] ;
|
||||
"AES-CBC" >::: [ cbc_selftest (module AES.CBC) 100 ] ;
|
||||
"AES-CTR" >::: [ ctr_selftest (module AES.CTR) 100;
|
||||
ctr_offsets (module AES.CTR) 100 ~zero:(0L, 0L) ] ;
|
||||
|
||||
]
|
||||
|
||||
let () =
|
||||
Mirage_crypto_rng_unix.use_default ();
|
||||
run_test_tt_main suite
|
||||
326
unikernel/duniverse/mirage-crypto/tests/test_rsa.ml
Normal file
326
unikernel/duniverse/mirage-crypto/tests/test_rsa.ml
Normal file
|
|
@ -0,0 +1,326 @@
|
|||
open OUnit2
|
||||
|
||||
open Mirage_crypto.Uncommon
|
||||
open Mirage_crypto_pk
|
||||
|
||||
open Test_common
|
||||
|
||||
let vz = Z.of_string_base 16
|
||||
|
||||
module Null = struct
|
||||
|
||||
type g = string ref
|
||||
|
||||
let block = 1
|
||||
|
||||
let create ?time:_ () = ref ""
|
||||
|
||||
let generate_into ~g buf ~off n =
|
||||
try
|
||||
Bytes.blit_string !g 0 buf off n;
|
||||
g := String.sub !g n (String.length !g - n)
|
||||
with Invalid_argument _ -> raise Mirage_crypto_rng.Unseeded_generator
|
||||
|
||||
let reseed ~g buf = g := !g ^ buf
|
||||
|
||||
let seeded ~g = String.length !g > 0
|
||||
|
||||
let accumulate ~g _source = `Acc (reseed ~g)
|
||||
|
||||
let pools = 0
|
||||
end
|
||||
|
||||
let random_is seed =
|
||||
Mirage_crypto_rng.create ~seed:seed (module Null)
|
||||
|
||||
let gen_rsa ~bits =
|
||||
let e = Z.(if bits < 24 then ~$3 else ~$0x10001) in
|
||||
let key = Rsa.(generate ~e ~bits ()) in
|
||||
assert_equal
|
||||
~msg:Printf.(sprintf "key size not %d bits" bits)
|
||||
bits Rsa.(priv_bits key);
|
||||
key
|
||||
|
||||
let rsa_priv_of_primes_regression _ =
|
||||
let e = Z.of_string "65537"
|
||||
and p = Z.of_string "63541376186162969"
|
||||
and q = Z.of_string "31114890003960709"
|
||||
in
|
||||
match Rsa.priv_of_primes ~e ~p ~q with
|
||||
| exception _ -> assert_failure "expected an error"
|
||||
| Error _ -> () (* expected since there's no multiplicative inverse of e with p and q (e is not coprime to q-1) *)
|
||||
| Ok _ -> assert_failure "expected an error"
|
||||
|
||||
let rsa_priv_of_primes_regression_62 _ =
|
||||
(* reported in https://github.com/mirage/mirage-crypto/issues/62 *)
|
||||
let e = Z.of_string "65537"
|
||||
and d = Z.of_string "3108431922676000487023821479912741349223115124336455693119108686758268939583975029271734799300422643496417197940166373626629291080744953934921341465364968117931378406446980227029856589807773725566867068344285160902403880508627911649654611750749193657211787605701986962527879646827816649512856008836705430283000626732452720870471763615388887743731833942366593788032394353874580439986226556671690116837426402890882760501726581078126288439928304880443426230837881572485961139412262011517513033934716366580117961709814170065275361576176352257579474519828879342959023237100172806323217608845596279839036960301580039126471"
|
||||
and p = Z.of_string "153903575880038685371306078431309624429262243098160628077155385424784731704538502041682563231842507936315834999272165353754081206847521073697105321898935865522941018859502063500927758809727634595752231111149172755709224739427971151799944749671230555614514021717987321482212474581192462617805386071920647746527"
|
||||
and q = Z.of_string "147755586168842154977618773600930512327712333912540690382962931855233965897097814139102488669702400832893695675498969512696944576662243412004204531041931249551207758395795244675585651830739018019197553505240463928167645984560980989768623533294470387237934457819888352229242173694504296968786124698140038767907"
|
||||
in
|
||||
match Rsa.priv_of_primes ~e ~p ~q with
|
||||
| exception _ -> assert_failure "expected ok"
|
||||
| Error _ -> assert_failure "expected ok"
|
||||
| Ok priv -> assert_equal ~msg:"d is equal" d priv.Rsa.d
|
||||
|
||||
let rsa_priv_of_primes_regression_openssl _ =
|
||||
let e = Z.of_string "65537"
|
||||
and d = Z.of_string "21364966876797335224937981624977347791305770821352826744474497613118281825259093305200082888709328664041494911511266059341542974088052755771514853303591832823929488189866359158215383109671205375680439686889619887327157945061169995481249526193538164572824333945969914914389168250738641676992853978375324165227210205971488866002577771580610214948106221456525289283949750296156474480874426885065689443846254958870114957680850339336866525023540164187023510310849878330359224986984785647477789876024460216392539430087762483228942540109987168856343992537776070047681434965518603440527188618027182112877268689620116969210881"
|
||||
and n = Z.of_string "26003711217261578550621411093788590465379160983527099623976249862031215614567566726273034808107255370042109943463095563849992606559609134476057069066550866318424151608276781565055186325047761889573394045234279585405785949661514281355247375815212099164453968239368389736365243837028903903448365174400765513065279734735815019879815099687407795902081216735845663253559329668423470162638675450802885820025108018425582646833277581392446992199509644421030247759098658756879463797225451870622102492377704722852444790028849818045531971545099489092363404165512101521453346604003075697381546910357245133314194790971809369935729"
|
||||
and p = Z.of_string "167173249562998285344683400251639903569188485523881465771532263785652572249038345452185825418846021360573529483365315302293816993785521941622864243995179759923984427691147261149068664025532174455772795926386901753396733517983474861943826134177458663773607339275619054052496007070211507365125143035209397925137"
|
||||
and q = Z.of_string "155549475081910328806496663071699269060677442531084543754539870945308062234020815068226104598610337898669482436828867339638346797527566740356018599563448611471831039630098224992256888467779107812081557864642282199069694603496263731994138092467683330232979926332910833392744391017831937213832896615543518213217"
|
||||
and dp = Z.of_string "132755002521578387208427344594600716257302676970335642531907550489959907687702391789577781987250291220069407638925560669432220144720901230294648011268216967903380465305980866674430162359351152591303223998548604831679503169353677551841013279935481616452288331251969392085510508445032389174215678839807099891905"
|
||||
and dq = Z.of_string "152169667453904159646778469559422238388806519569028538897642778063026012695267963386624048157997842343979683651561853178299789862671237414352891045879600543621061437719219486685819703226188594826677829613436846951019352886368859676966296527494096180039169354974776267777118591655496269139424576967397677391457"
|
||||
and q' = Z.of_string "71680879219372822058570738508033808601658137476144867031269752035545521971293179931151996149323998570187762489030494773672093398051821155138733159825225031201464935294877263527756698979264488516898115736148932950739809310843167520947847241161602397933518005104012950660916455073023725039529353919943223042903"
|
||||
in
|
||||
match Rsa.priv ~e ~d ~n ~p ~q ~dp ~dq ~q' with
|
||||
| exception _ -> assert_failure "expected ok"
|
||||
| Error _ -> assert_failure "expected ok"
|
||||
| Ok _ -> ()
|
||||
|
||||
let rsa_selftest ~bits n =
|
||||
"selftest" >:: times ~n @@ fun _ ->
|
||||
let msg =
|
||||
let size = bits // 8 in
|
||||
let buf = Bytes.create size in
|
||||
Mirage_crypto_rng.generate_into buf ~off:0 size;
|
||||
let i = 1 + Randomconv.int ~bound:(pred size) Mirage_crypto_rng.generate in
|
||||
Bytes.set_uint8 buf 0 0;
|
||||
Bytes.(set_uint8 buf i (get_uint8 buf i lor 2));
|
||||
Bytes.unsafe_to_string buf
|
||||
in
|
||||
let key = gen_rsa ~bits in
|
||||
let enc = Rsa.(encrypt ~key:(pub_of_priv key) msg) in
|
||||
let dec = Rsa.(decrypt ~key enc) in
|
||||
|
||||
assert_oct_equal
|
||||
~msg:Printf.(sprintf "failed decryption with")
|
||||
msg dec
|
||||
|
||||
let show_key_size key =
|
||||
Printf.sprintf "(%d bits)" (Rsa.priv_bits key)
|
||||
|
||||
let pkcs_message_for_bits bits =
|
||||
let padding = 12 in
|
||||
let size = bits // 8 - padding in
|
||||
assert (size >= 0) ; Mirage_crypto_rng.generate size
|
||||
|
||||
let rsa_pkcs1_encode_selftest ~bits n =
|
||||
"selftest" >:: times ~n @@ fun _ ->
|
||||
let key = gen_rsa ~bits
|
||||
and msg = pkcs_message_for_bits bits in
|
||||
let sgn = Rsa.PKCS1.sig_encode ~key msg in
|
||||
match Rsa.(PKCS1.sig_decode ~key:(pub_of_priv key) sgn) with
|
||||
| None -> assert_failure ("unpad failure " ^ show_key_size key)
|
||||
| Some dec -> assert_oct_equal msg dec
|
||||
~msg:("recovery failure " ^ show_key_size key)
|
||||
|
||||
let rsa_pkcs1_sign_selftest n =
|
||||
let open Digestif.SHA1 in
|
||||
"selftest" >:: times ~n @@ fun _ ->
|
||||
let key = gen_rsa ~bits:(Rsa.PKCS1.min_key `SHA1)
|
||||
and msg = Mirage_crypto_rng.generate 47 in
|
||||
let pkey = Rsa.pub_of_priv key in
|
||||
assert_bool "invert 1" Rsa.PKCS1.(
|
||||
verify ~key:pkey ~hashp:any (`Message msg)
|
||||
~signature:(sign ~hash:`SHA1 ~key (`Digest (digest_string msg |> to_raw_string))) );
|
||||
assert_bool "invert 2" Rsa.PKCS1.(
|
||||
verify ~key:pkey ~hashp:any (`Digest (digest_string msg |> to_raw_string))
|
||||
~signature:(sign ~hash:`SHA1 ~key (`Message msg)) )
|
||||
|
||||
let rsa_pkcs1_encrypt_selftest ~bits n =
|
||||
"selftest" >:: times ~n @@ fun _ ->
|
||||
let key = gen_rsa ~bits
|
||||
and msg = pkcs_message_for_bits bits in
|
||||
let enc = Rsa.(PKCS1.encrypt ~key:(pub_of_priv key) msg) in
|
||||
match Rsa.PKCS1.decrypt ~key enc with
|
||||
| None -> assert_failure ("unpad failure " ^ show_key_size key)
|
||||
| Some dec -> assert_oct_equal msg dec
|
||||
~msg:("recovery failure " ^ show_key_size key)
|
||||
|
||||
let rsa_oaep_encrypt_selftest ~bits n =
|
||||
let module OAEP_MD5 = Rsa.OAEP (Digestif.MD5) in
|
||||
let module OAEP_SHA1 = Rsa.OAEP (Digestif.SHA1) in
|
||||
let module OAEP_SHA224 = Rsa.OAEP (Digestif.SHA224) in
|
||||
let module OAEP_SHA256 = Rsa.OAEP (Digestif.SHA256) in
|
||||
let module OAEP_SHA384 = Rsa.OAEP (Digestif.SHA384) in
|
||||
"selftest" >:: times ~n @@ fun _ ->
|
||||
let key = gen_rsa ~bits in
|
||||
let msg = Mirage_crypto_rng.generate (bits // 8 - 2 * Digestif.MD5.digest_size - 2) in
|
||||
let enc = OAEP_MD5.encrypt ~key:(Rsa.pub_of_priv key) msg in
|
||||
(match OAEP_MD5.decrypt ~key enc with
|
||||
| None -> assert_failure "unpad failure"
|
||||
| Some dec -> assert_oct_equal msg dec ~msg:"recovery failure");
|
||||
let msg = Mirage_crypto_rng.generate (bits // 8 - 2 * Digestif.SHA1.digest_size - 2) in
|
||||
let enc = OAEP_SHA1.encrypt ~key:(Rsa.pub_of_priv key) msg in
|
||||
(match OAEP_SHA1.decrypt ~key enc with
|
||||
| None -> assert_failure "unpad failure"
|
||||
| Some dec -> assert_oct_equal msg dec ~msg:"recovery failure");
|
||||
let msg = Mirage_crypto_rng.generate (bits // 8 - 2 * Digestif.SHA224.digest_size - 2) in
|
||||
let enc = OAEP_SHA224.encrypt ~key:(Rsa.pub_of_priv key) msg in
|
||||
(match OAEP_SHA224.decrypt ~key enc with
|
||||
| None -> assert_failure "unpad failure"
|
||||
| Some dec -> assert_oct_equal msg dec ~msg:"recovery failure");
|
||||
let msg = Mirage_crypto_rng.generate (bits // 8 - 2 * Digestif.SHA256.digest_size - 2) in
|
||||
let enc = OAEP_SHA256.encrypt ~key:(Rsa.pub_of_priv key) msg in
|
||||
(match OAEP_SHA256.decrypt ~key enc with
|
||||
| None -> assert_failure "unpad failure"
|
||||
| Some dec -> assert_oct_equal msg dec ~msg:"recovery failure");
|
||||
let msg = Mirage_crypto_rng.generate (bits // 8 - 2 * Digestif.SHA384.digest_size - 2) in
|
||||
let enc = OAEP_SHA384.encrypt ~key:(Rsa.pub_of_priv key) msg in
|
||||
(match OAEP_SHA384.decrypt ~key enc with
|
||||
| None -> assert_failure "unpad failure"
|
||||
| Some dec -> assert_oct_equal msg dec ~msg:"recovery failure")
|
||||
|
||||
let rsa_pss_sign_selftest ~bits n =
|
||||
let module Pss_sha1 = Rsa.PSS (Digestif.SHA1) in
|
||||
"selftest" >:: times ~n @@ fun _ ->
|
||||
let key = gen_rsa ~bits
|
||||
and msg = Mirage_crypto_rng.generate 1024 in
|
||||
let pkey = Rsa.pub_of_priv key in
|
||||
let dgst = Digestif.SHA1.(digest_string msg |> to_raw_string) in
|
||||
let signature = Pss_sha1.sign ~key (`Digest dgst) in
|
||||
Pss_sha1.(verify ~key:pkey (`Message msg) ~signature) |> assert_bool "invert 1" ;
|
||||
Pss_sha1.(verify ~key:pkey (`Digest dgst)
|
||||
~signature:(Pss_sha1.sign ~key (`Message msg)))
|
||||
|> assert_bool "invert 2"
|
||||
|
||||
let rsa_pkcs1_cases =
|
||||
let key () =
|
||||
let n = vz "c8a2069182394a2ab7c3f4190c15589c56a2d4bc42dca675b34cc950e24663048441e8aa593b2bc59e198b8c257e882120c62336e5cc745012c7ffb063eebe53f3c6504cba6cfe51baa3b6d1074b2f398171f4b1982f4d65caf882ea4d56f32ab57d0c44e6ad4e9cf57a4339eb6962406e350c1b15397183fbf1f0353c9fc991"
|
||||
and d = vz "5dfcb111072d29565ba1db3ec48f57645d9d8804ed598a4d470268a89067a2c921dff24ba2e37a3ce834555000dc868ee6588b7493303528b1b3a94f0b71730cf1e86fca5aeedc3afa16f65c0189d810ddcd81049ebbd0391868c50edec958b3a2aaeff6a575897e2f20a3ab5455c1bfa55010ac51a7799b1ff8483644a3d425"
|
||||
and e = vz "10001"
|
||||
in
|
||||
match Rsa.priv_of_exp ~e ~d ~n () with
|
||||
| Error (`Msg m) -> invalid_arg "bad key %s" m
|
||||
| Ok key -> key, Rsa.pub_of_priv key
|
||||
in
|
||||
|
||||
let case ~hash ~msg ~sgn = test_case @@ fun _ ->
|
||||
let msg = vx msg and sgn = vx sgn in
|
||||
let key, public = key () in
|
||||
Rsa.(PKCS1.sign ~hash ~key (`Message msg))
|
||||
|> assert_oct_equal ~msg:"recomputing sig:" sgn ;
|
||||
Rsa.(PKCS1.verify ~hashp:any ~key:public ~signature:sgn (`Message msg))
|
||||
|> assert_bool "sig verification" in
|
||||
|
||||
"FIPS 186-2 Test Vectors (1024 bits)" >::: [
|
||||
|
||||
case ~hash:`SHA1
|
||||
~msg:"e8312742ae23c456ef28a23142c4490895832765dadce02afe5be5d31b0048fbeee2cf218b1747ad4fd81a2e17e124e6af17c3888e6d2d40c00807f423a233cad62ce9eaefb709856c94af166dba08e7a06965d7fc0d8e5cb26559c460e47bc088589d2242c9b3e62da4896fab199e144ec136db8d84ab84bcba04ca3b90c8e5"
|
||||
~sgn:"28928e19eb86f9c00070a59edf6bf8433a45df495cd1c73613c2129840f48c4a2c24f11df79bc5c0782bcedde97dbbb2acc6e512d19f085027cd575038453d04905413e947e6e1dddbeb3535cdb3d8971fe0200506941056f21243503c83eadde053ed866c0e0250beddd927a08212aa8ac0efd61631ef89d8d049efb36bb35f"
|
||||
|
||||
; case ~hash:`SHA1
|
||||
~msg:"4c95073dac19d0256eaadff3505910e431dd50018136afeaf690b7d18069fcc980f6f54135c30acb769bee23a7a72f6ce6d90cbc858c86dbbd64ba48a07c6d7d50c0e9746f97086ad6c68ee38a91bbeeeb2221aa2f2fb4090fd820d4c0ce5ff025ba8adf43ddef89f5f3653de15edcf3aa8038d4686960fc55b2917ec8a8f9a8"
|
||||
~sgn:"53ab600a41c71393a271b0f32f521963087e56ebd7ad040e4ee8aa7c450ad18ac3c6a05d4ae8913e763cfe9623bd9cb1eb4bed1a38200500fa7df3d95dea485f032a0ab0c6589678f9e8391b5c2b1392997ac9f82f1d168878916aace9ac7455808056af8155231a29f42904b7ab87a5d71ed6395ee0a9d024b0ca3d01fd7150"
|
||||
|
||||
; case ~hash:`SHA1
|
||||
~msg:"e075ad4b0f9b5b20376e467a1a35e308793ba38ed983d03887b8b82eda630e68b8618dc45b93de5555d7bcfed23756401e61f5516757de6ec3687a71755fb4a66cfaa3db0c9e69b631485b4c71c762eea229a0469c7357a440950792ba9cd7ae022a36b9a923c2ebd2aa69897f4cceba0e7aee97033d03810725a9b731833f27"
|
||||
~sgn:"642609ce084f479271df596480252e2f892b3e7982dff95994c3eeda787f80f3f6198bbce33ec5515378d4b571d7186078b75b43aed11d342547386c5696eb3799a0b28475e54cd4ca7d036dcd8a11f5e10806f7d3b8cc4fcb3e93e857be958344a34e126809c15b3d33661cf57bf5c338f07acced60f14019335c152d86b3b2"
|
||||
|
||||
; case ~hash:`SHA224
|
||||
~msg:"e567a39ae4e5ef9b6801ea0561b72a5d4b5f385f0532fc9fe10a7570f869ae05c0bdedd6e0e22d4542e9ce826a188cac0731ae39c8f87f9771ef02132e64e2fb27ada8ff54b330dd93ad5e3ef82e0dda646248e35994bda10cf46e5abc98aa7443c03cddeb5ee2ab82d60100b1029631897970275f119d05daa2220a4a0defba"
|
||||
~sgn:"5aa5033381bdd0acce332dd314daf008acaa9e835f832979891d1bda2b55d5eae35c479c06cac5bf33f432c8c0a5549d1d1b29c5e2589024d27800a0c235a61532c203cbc406ac6ecf63f52ae771b97c08e4b108ec916900e5a11b1d48cca86ca5a5a799ed32e99c815cef04cf8eb55223bfd4d9c3449264b60061bc3684bc82"
|
||||
|
||||
; case ~hash:`SHA256
|
||||
~msg:"e567a39ae4e5ef9b6801ea0561b72a5d4b5f385f0532fc9fe10a7570f869ae05c0bdedd6e0e22d4542e9ce826a188cac0731ae39c8f87f9771ef02132e64e2fb27ada8ff54b330dd93ad5e3ef82e0dda646248e35994bda10cf46e5abc98aa7443c03cddeb5ee2ab82d60100b1029631897970275f119d05daa2220a4a0defba"
|
||||
~sgn:"0e7cdd121e40323ca6115d1ec6d1f9561738455f0e9e1cd858e8b566ae2da5e8ee63d8f15c3cdd88027e13406db609369c88ca99b34fa156c7ee62bc5a3923bb5a1edabd45c1a422aafcbb47e0947f35cfef87970b4b713162b21916cafb8c864a3e5b9ffc989401d4eae992312a32c5bc88abbb45f99ac885b54d6b8e61b6ec"
|
||||
|
||||
; case ~hash:`SHA384
|
||||
~msg:"e567a39ae4e5ef9b6801ea0561b72a5d4b5f385f0532fc9fe10a7570f869ae05c0bdedd6e0e22d4542e9ce826a188cac0731ae39c8f87f9771ef02132e64e2fb27ada8ff54b330dd93ad5e3ef82e0dda646248e35994bda10cf46e5abc98aa7443c03cddeb5ee2ab82d60100b1029631897970275f119d05daa2220a4a0defba"
|
||||
~sgn:"1689a8523919ac77cc997ebc59cb908872d88b2855a309ead2779b888b22b4232da9b93bb19b32c1db77ad738c6e43361e9eb6b1a37c49a8f3c7c7ae7e784d19a62138741293e49b1831c0c3617eb43c56706d83314953470636441086419ab9e6fd1ec4f9d5cc6544815d1e02ed96a3ae64c6998b2cf238e79a12164352d12a"
|
||||
|
||||
; case ~hash:`SHA512
|
||||
~msg:"e567a39ae4e5ef9b6801ea0561b72a5d4b5f385f0532fc9fe10a7570f869ae05c0bdedd6e0e22d4542e9ce826a188cac0731ae39c8f87f9771ef02132e64e2fb27ada8ff54b330dd93ad5e3ef82e0dda646248e35994bda10cf46e5abc98aa7443c03cddeb5ee2ab82d60100b1029631897970275f119d05daa2220a4a0defba"
|
||||
~sgn:"bf3ff2c69675f1b8ed421021801fb4ce29a757f7f8869ce436d0d75ab749efc8b903d9f9cb214686147f12f3335fa936689c192f310ae3c5d75493f44b24bc1cd3501584aaa5004b65a8716d1eda7240ad8a529d5a0cf169f4054b450e076ee0d41a0011c557aa69a84a8104c909201d60fe39c79e684347ef4d144ea18f7a4e"
|
||||
]
|
||||
|
||||
let rsa_pss_cases =
|
||||
let key () =
|
||||
let n = vz "bcb47b2e0dafcba81ff2a2b5cb115ca7e757184c9d72bcdcda707a146b3b4e29989ddc660bd694865b932b71ca24a335cf4d339c719183e6222e4c9ea6875acd528a49ba21863fe08147c3a47e41990b51a03f77d22137f8d74c43a5a45f4e9e18a2d15db051dc89385db9cf8374b63a8cc88113710e6d8179075b7dc79ee76b"
|
||||
and d = vz "383a6f19e1ea27fd08c7fbc3bfa684bd6329888c0bbe4c98625e7181f411cfd0853144a3039404dda41bce2e31d588ec57c0e148146f0fa65b39008ba5835f829ba35ae2f155d61b8a12581b99c927fd2f22252c5e73cba4a610db3973e019ee0f95130d4319ed413432f2e5e20d5215cdd27c2164206b3f80edee51938a25c1"
|
||||
and e = vz "10001"
|
||||
in
|
||||
match Rsa.priv_of_exp ~e ~d ~n () with
|
||||
| Error (`Msg m) -> invalid_arg "bad key %s" m
|
||||
| Ok key -> key, Rsa.pub_of_priv key
|
||||
and salt = "6f2841166a64471d4f0b8ed0dbb7db32161da13b"
|
||||
in
|
||||
|
||||
let case (type a) ~(hash : a Digestif.hash) ~msg ~sgn = test_case @@ fun _ ->
|
||||
let module H = (val Digestif.module_of hash) in
|
||||
let module Pss = Rsa.PSS (H) in
|
||||
let msg = vx msg and sgn = vx sgn and salt = vx salt in
|
||||
let key, public = key () in
|
||||
let slen = String.length salt in
|
||||
Pss.sign ~g:(random_is salt) ~slen ~mask:`No ~key (`Message msg)
|
||||
|> assert_oct_equal ~msg:"recomputing sig:" sgn ;
|
||||
Pss.verify ~key:public ~slen ~signature:sgn (`Message msg)
|
||||
|> assert_bool "sig verification" in
|
||||
|
||||
"FIPS 186-2 Test Vectors (1024 bits)" >::: [
|
||||
|
||||
case ~hash:Digestif.sha1
|
||||
~msg:"1248f62a4389f42f7b4bb131053d6c88a994db2075b912ccbe3ea7dc611714f14e075c104858f2f6e6cfd6abdedf015a821d03608bf4eba3169a6725ec422cd9069498b5515a9608ae7cc30e3d2ecfc1db6825f3e996ce9a5092926bc1cf61aa42d7f240e6f7aa0edb38bf81aa929d66bb5d890018088458720d72d569247b0c"
|
||||
~sgn:"682cf53c1145d22a50caa9eb1a9ba70670c5915e0fdfde6457a765de2a8fe12de9794172a78d14e668d498acedad616504bb1764d094607070080592c3a69c343d982bd77865873d35e24822caf43443cc10249af6a1e26ef344f28b9ef6f14e09ad839748e5148bcceb0fd2aa63709cb48975cbf9c7b49abc66a1dc6cb5b31a"
|
||||
|
||||
; case ~hash:Digestif.sha1
|
||||
~msg:"9968809a557bb4f892039ff2b6a0efcd06523624bc3b9ad359a7cf143c4942e874c797b9d37a563d436fe19d5db1aad738caa2617f87f50fc7fcf4361fc85212e89a9465e7f4c361982f64c8c5c0aa5258b9e94f6e934e8dac2ace7cd6095c909de85fe7b973632c384d0ebb165556050d28f236aee70e16b13a432d8a94c62b"
|
||||
~sgn:"8f5ea7037367e0db75670504085790acd6d97d96f51e76df916a0c2e4cd66e1ab51c4cd8e2c3e4ef781f638ad65dc49c8d6d7f6930f80b6ae199ea283a8924925a50edab79bb3f34861ffa8b2f96fdf9f8cad3d3f8f025478c81f316da61b0d6a7f71b9068efdfb33c21983a922f4669280d8e84f963ff885ef56dd3f50381db"
|
||||
|
||||
; case ~hash:Digestif.sha224
|
||||
~msg:"1248f62a4389f42f7b4bb131053d6c88a994db2075b912ccbe3ea7dc611714f14e075c104858f2f6e6cfd6abdedf015a821d03608bf4eba3169a6725ec422cd9069498b5515a9608ae7cc30e3d2ecfc1db6825f3e996ce9a5092926bc1cf61aa42d7f240e6f7aa0edb38bf81aa929d66bb5d890018088458720d72d569247b0c"
|
||||
~sgn:"53d859c9f10abf1c00284a4b55bf2bd84d8e313b4f3c35b8dec7bc3afe39b9b8a155418ead1931895769ce2340be2091f2385bbcf10d9e92bcf5d0e2960d10e792e7d865c64e50d19ffa13e52817d7d8d8db34392c2374a2e9b69184f92a4ad9b1b8bae99ca614d204b65a438e38dbbfc8c7cc44ed5677af70ce6c4f951f0244"
|
||||
|
||||
; case ~hash:Digestif.sha256
|
||||
~msg:"1248f62a4389f42f7b4bb131053d6c88a994db2075b912ccbe3ea7dc611714f14e075c104858f2f6e6cfd6abdedf015a821d03608bf4eba3169a6725ec422cd9069498b5515a9608ae7cc30e3d2ecfc1db6825f3e996ce9a5092926bc1cf61aa42d7f240e6f7aa0edb38bf81aa929d66bb5d890018088458720d72d569247b0c"
|
||||
~sgn:"7b1d37278e549898d4084e2210c4a9961edfe7b5963550cca1904248c8681513539017820f0e9bd074b9f8a067b9fefff7f1fa20bf2d0c75015ff020b2210cc7f79034fedf68e8d44a007abf4dd82c26e8b00393723aea15abfbc22941c8cf79481718c008da713fb8f54cb3fca890bde1137314334b9b0a18515bfa48e5ccd0"
|
||||
|
||||
; case ~hash:Digestif.sha384
|
||||
~msg:"1248f62a4389f42f7b4bb131053d6c88a994db2075b912ccbe3ea7dc611714f14e075c104858f2f6e6cfd6abdedf015a821d03608bf4eba3169a6725ec422cd9069498b5515a9608ae7cc30e3d2ecfc1db6825f3e996ce9a5092926bc1cf61aa42d7f240e6f7aa0edb38bf81aa929d66bb5d890018088458720d72d569247b0c"
|
||||
~sgn:"8f16c807bef3ed6f74ee7ff5c360a5428c6c2f105178b58ff7d073e566dad6e7718d3129c768cd5a9666de2b6c947177b45709dc7cd0f43b0ba6fc75578e1196acc15ca3afe4a78c144cb6885c1cc815f7f98925bc04ad2ff20fc1068b045d9450e2a1dcf5a161ceabba2b0b66c7354fdb80fa1d729e5f976387f24a697a7e56"
|
||||
|
||||
; case ~hash:Digestif.sha512
|
||||
~msg:"1248f62a4389f42f7b4bb131053d6c88a994db2075b912ccbe3ea7dc611714f14e075c104858f2f6e6cfd6abdedf015a821d03608bf4eba3169a6725ec422cd9069498b5515a9608ae7cc30e3d2ecfc1db6825f3e996ce9a5092926bc1cf61aa42d7f240e6f7aa0edb38bf81aa929d66bb5d890018088458720d72d569247b0c"
|
||||
~sgn:"a833ba31634f8773e4fe6ea0c69e1a23766a939d34b32fc78b774b22e46a646c25e6e1062d234ed48b1aba0f830529ff6afc296cc8dc207bbc15391623beac5f6c3db557ca49d0e42c962de95b5ff548cff970f5c73f439cfe82d3907be60240f56b6a4259cc96dfd8fe02a0bfa26e0223f68214428fff0ae40162198cc5cbd1"
|
||||
]
|
||||
|
||||
let suite = [
|
||||
"RSA" >::: [
|
||||
rsa_selftest ~bits:89 100 ;
|
||||
rsa_selftest ~bits:131 100 ;
|
||||
rsa_selftest ~bits:1024 10 ;
|
||||
rsa_selftest ~bits:2048 10 ;
|
||||
] ;
|
||||
|
||||
"RSA-PKCS1-ENC" >::: [
|
||||
rsa_pkcs1_encrypt_selftest ~bits:111 1000 ;
|
||||
rsa_pkcs1_encrypt_selftest ~bits:512 10 ;
|
||||
] ;
|
||||
|
||||
"RSA-PKCS1-SIGN" >::: [
|
||||
rsa_pkcs1_encode_selftest ~bits:111 100 ;
|
||||
rsa_pkcs1_encode_selftest ~bits:512 10 ;
|
||||
rsa_pkcs1_sign_selftest 10;
|
||||
rsa_pkcs1_cases;
|
||||
] ;
|
||||
|
||||
"RSA-OAEP(SHA1)-ENC" >::: [
|
||||
rsa_oaep_encrypt_selftest ~bits:1023 15 ;
|
||||
rsa_oaep_encrypt_selftest ~bits:1024 15 ;
|
||||
rsa_oaep_encrypt_selftest ~bits:1025 15 ;
|
||||
] ;
|
||||
|
||||
"RSA-PSS(SHA1)-END" >::: [
|
||||
rsa_pss_sign_selftest ~bits:511 15 ;
|
||||
rsa_pss_sign_selftest ~bits:512 15 ;
|
||||
rsa_pss_sign_selftest ~bits:513 15 ;
|
||||
rsa_pss_cases
|
||||
] ;
|
||||
|
||||
"RSA-regression" >::: [
|
||||
test_case rsa_priv_of_primes_regression ;
|
||||
test_case rsa_priv_of_primes_regression_62 ;
|
||||
test_case rsa_priv_of_primes_regression_openssl ;
|
||||
] ;
|
||||
]
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
open OUnit2
|
||||
|
||||
let () =
|
||||
Format.printf "accel: %a\n%!"
|
||||
(fun ppf -> List.iter @@ fun x ->
|
||||
Format.fprintf ppf "%s " @@
|
||||
match x with `XOR -> "XOR" | `AES -> "AES" | `GHASH -> "GHASH")
|
||||
Mirage_crypto.accelerated
|
||||
|
||||
let suite =
|
||||
"All" >::: [
|
||||
"Basic" >::: Test_base.suite;
|
||||
"Cipher" >::: Test_cipher.suite;
|
||||
]
|
||||
|
||||
let () =
|
||||
run_test_tt_main suite
|
||||
6
unikernel/duniverse/mirage-crypto/tests/wycheproof/dune
Normal file
6
unikernel/duniverse/mirage-crypto/tests/wycheproof/dune
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
(library
|
||||
(name wycheproof)
|
||||
(libraries yojson ppx_deriving_yojson.runtime)
|
||||
(preprocess
|
||||
(pps ppx_deriving.std ppx_deriving_yojson))
|
||||
(optional))
|
||||
149
unikernel/duniverse/mirage-crypto/tests/wycheproof/wycheproof.ml
Normal file
149
unikernel/duniverse/mirage-crypto/tests/wycheproof/wycheproof.ml
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
type json = Yojson.Safe.t [@@deriving of_yojson]
|
||||
|
||||
let pp_json = Yojson.Safe.pretty_print
|
||||
|
||||
type hex = string [@@deriving eq]
|
||||
|
||||
let pp_hex fmt buf =
|
||||
let n = String.length buf in
|
||||
let bbuf = Bytes.unsafe_of_string buf in
|
||||
for i = n - 1 downto 0 do
|
||||
let byte = Bytes.get_uint8 bbuf i in
|
||||
Format.fprintf fmt "%02x" byte
|
||||
done
|
||||
|
||||
let hex_of_string s =
|
||||
let fold f acc str =
|
||||
let st = ref acc in
|
||||
String.iter (fun c -> st := f !st c) str;
|
||||
!st
|
||||
and digit c =
|
||||
match c with
|
||||
| '0'..'9' -> int_of_char c - 0x30
|
||||
| 'A'..'F' -> int_of_char c - 0x41 + 10
|
||||
| 'a'..'f' -> int_of_char c - 0x61 + 10
|
||||
| _ -> invalid_arg "bad character"
|
||||
in
|
||||
let out = Bytes.create (String.length s / 2) in
|
||||
let _idx, leftover =
|
||||
fold (fun (idx, leftover) c ->
|
||||
let c = digit c in
|
||||
match leftover with
|
||||
| None -> idx, Some (c lsl 4)
|
||||
| Some c' ->
|
||||
Bytes.set_uint8 out idx (c' lor c);
|
||||
succ idx, None)
|
||||
(0, None) s
|
||||
in
|
||||
assert (leftover = None);
|
||||
Bytes.unsafe_to_string out
|
||||
|
||||
let hex_of_yojson json =
|
||||
let padded s = if String.length s mod 2 = 0 then s else "0" ^ s in
|
||||
match [%of_yojson: string] json with
|
||||
| Ok s -> Ok (hex_of_string (padded s))
|
||||
| Error _ as e -> e
|
||||
|
||||
type test_result = Valid | Acceptable | Invalid [@@deriving show]
|
||||
|
||||
let test_result_of_yojson = function
|
||||
| `String "valid" -> Ok Valid
|
||||
| `String "acceptable" -> Ok Acceptable
|
||||
| `String "invalid" -> Ok Invalid
|
||||
| _ -> Error "test_result"
|
||||
|
||||
type ecdh_test = {
|
||||
tcId : int;
|
||||
comment : string;
|
||||
curve : json option; [@yojson.default None]
|
||||
public : hex;
|
||||
private_ : hex; [@yojson.key "private"]
|
||||
shared : hex;
|
||||
result : test_result;
|
||||
flags : string list;
|
||||
}
|
||||
[@@deriving of_yojson, show]
|
||||
|
||||
let has_ignored_flag test ~ignored_flags =
|
||||
List.exists
|
||||
(fun ignored_flag -> List.mem ignored_flag test.flags)
|
||||
ignored_flags
|
||||
|
||||
type ecdh_test_group = {
|
||||
curve : string;
|
||||
tests : ecdh_test list;
|
||||
encoding : json option; [@yojson.default None]
|
||||
type_ : json option; [@yojson.default None] [@yojson.key "type"]
|
||||
}
|
||||
[@@deriving of_yojson, show]
|
||||
|
||||
type ecdsa_key = {
|
||||
curve : string;
|
||||
keySize : int;
|
||||
type_ : json; [@yojson.key "type"]
|
||||
uncompressed : hex;
|
||||
wx : hex;
|
||||
wy : hex;
|
||||
}
|
||||
[@@deriving of_yojson, show]
|
||||
|
||||
type dsa_test = {
|
||||
tcId : int;
|
||||
comment : string;
|
||||
msg : hex;
|
||||
sig_ : hex; [@yojson.key "sig"]
|
||||
result : test_result;
|
||||
flags : string list;
|
||||
}
|
||||
[@@deriving of_yojson, show]
|
||||
|
||||
type ecdsa_test_group = {
|
||||
key : ecdsa_key;
|
||||
keyDer : string;
|
||||
keyPem : string;
|
||||
sha : string;
|
||||
tests : dsa_test list;
|
||||
type_ : json option; [@yojson.default None] [@yojson.key "type"]
|
||||
}
|
||||
[@@deriving of_yojson, show]
|
||||
|
||||
type eddsa_key = {
|
||||
curve : string;
|
||||
keySize : int;
|
||||
pk : hex;
|
||||
sk : hex;
|
||||
type_ : json; [@yojson.key "type"]
|
||||
}
|
||||
[@@deriving of_yojson, show]
|
||||
|
||||
type eddsa_test_group = {
|
||||
jwk : json;
|
||||
key : eddsa_key;
|
||||
keyDer : string;
|
||||
keyPem : string;
|
||||
type_ : json; [@yojson.key "type"]
|
||||
tests : dsa_test list;
|
||||
}
|
||||
[@@deriving of_yojson, show]
|
||||
|
||||
type test_file = {
|
||||
algorithm : json;
|
||||
generatorVersion : json;
|
||||
header : json;
|
||||
notes : json;
|
||||
numberOfTests : json;
|
||||
schema : json;
|
||||
testGroups : json list;
|
||||
}
|
||||
[@@deriving of_yojson, show]
|
||||
|
||||
let get_json = function Ok x -> x | Error s -> failwith s
|
||||
|
||||
let load_file_exn path =
|
||||
Yojson.Safe.from_file path |> [%of_yojson: test_file] |> get_json
|
||||
|
||||
let ecdh_test_group_exn json = [%of_yojson: ecdh_test_group] json |> get_json
|
||||
|
||||
let ecdsa_test_group_exn json = [%of_yojson: ecdsa_test_group] json |> get_json
|
||||
|
||||
let eddsa_test_group_exn json = [%of_yojson: eddsa_test_group] json |> get_json
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
type json
|
||||
|
||||
type hex = string [@@deriving eq]
|
||||
|
||||
val pp_hex : Format.formatter -> hex -> unit
|
||||
|
||||
type test_result = Valid | Acceptable | Invalid [@@deriving show]
|
||||
|
||||
type ecdh_test = {
|
||||
tcId : int;
|
||||
comment : string;
|
||||
curve : json option;
|
||||
public : hex;
|
||||
private_ : hex;
|
||||
shared : hex;
|
||||
result : test_result;
|
||||
flags : string list;
|
||||
}
|
||||
[@@deriving show]
|
||||
|
||||
val has_ignored_flag : ecdh_test -> ignored_flags:string list -> bool
|
||||
|
||||
type ecdh_test_group = {
|
||||
curve : string;
|
||||
tests : ecdh_test list;
|
||||
encoding : json option;
|
||||
type_ : json option;
|
||||
}
|
||||
[@@deriving show]
|
||||
|
||||
type ecdsa_key = {
|
||||
curve : string;
|
||||
keySize : int;
|
||||
type_ : json;
|
||||
uncompressed : hex;
|
||||
wx : hex;
|
||||
wy : hex;
|
||||
}
|
||||
[@@deriving show]
|
||||
|
||||
type dsa_test = {
|
||||
tcId : int;
|
||||
comment : string;
|
||||
msg : hex;
|
||||
sig_ : hex;
|
||||
result : test_result;
|
||||
flags : string list;
|
||||
}
|
||||
[@@deriving show]
|
||||
|
||||
type ecdsa_test_group = {
|
||||
key : ecdsa_key;
|
||||
keyDer : string;
|
||||
keyPem : string;
|
||||
sha : string;
|
||||
tests : dsa_test list;
|
||||
type_ : json option;
|
||||
}
|
||||
[@@deriving show]
|
||||
|
||||
type eddsa_key = {
|
||||
curve : string;
|
||||
keySize : int;
|
||||
pk : hex;
|
||||
sk : hex;
|
||||
type_ : json; [@yojson.key "type"]
|
||||
}
|
||||
[@@deriving of_yojson, show]
|
||||
|
||||
type eddsa_test_group = {
|
||||
jwk : json;
|
||||
key : eddsa_key;
|
||||
keyDer : string;
|
||||
keyPem : string;
|
||||
type_ : json; [@yojson.key "type"]
|
||||
tests : dsa_test list;
|
||||
}
|
||||
[@@deriving of_yojson, show]
|
||||
|
||||
type test_file = {
|
||||
algorithm : json;
|
||||
generatorVersion : json;
|
||||
header : json;
|
||||
notes : json;
|
||||
numberOfTests : json;
|
||||
schema : json;
|
||||
testGroups : json list;
|
||||
}
|
||||
[@@deriving show]
|
||||
|
||||
val load_file_exn : string -> test_file
|
||||
|
||||
val ecdh_test_group_exn : json -> ecdh_test_group
|
||||
|
||||
val ecdsa_test_group_exn : json -> ecdsa_test_group
|
||||
|
||||
val eddsa_test_group_exn : json -> eddsa_test_group
|
||||
5248
unikernel/duniverse/mirage-crypto/tests/x25519_test.json
Normal file
5248
unikernel/duniverse/mirage-crypto/tests/x25519_test.json
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue