Vendors: add ocaml-bip39

This commit is contained in:
Vincent Bernardoff 2018-02-08 18:59:43 +01:00 committed by Benjamin Canou
parent 6fa1283240
commit 6096592a22
9 changed files with 2486 additions and 0 deletions

13
vendors/ocaml-bip39/LICENSE.md vendored Normal file
View File

@ -0,0 +1,13 @@
Copyright (c) 2017 Vincent Bernardoff
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

22
vendors/ocaml-bip39/bip39.opam vendored Normal file
View File

@ -0,0 +1,22 @@
opam-version: "1.2"
name: "bip39"
version: "1.0"
maintainer: "Vincent Bernardoff <vb@luminar.eu.org>"
authors: ["Vincent Bernardoff <vb@luminar.eu.org>"]
homepage: "https://github.com/vbmithr/ocaml-bip39"
doc: "https://vbmithr.github.io/ocaml-bip39/doc"
license: "ISC"
dev-repo: "https://github.com/vbmithr/ocaml-bip39.git"
bug-reports: "https://github.com/vbmithr/ocaml-bip39/issues"
tags: []
available: [ ocaml-version >= "4.03.0" ]
build: [ "jbuilder" "build" "-j" jobs "-p" name "@install" ]
depends: [
"jbuilder" {build & >= "1.0+beta17"}
"base" {build & >= "v0.10.0"}
"stdio" {build & >= "v0.10.0"}
"nocrypto" {>= "0.5.4"}
"pbkdf" {>= "0.2.0"}
"hex" { "test" }
"alcotest" { "test" }
]

2048
vendors/ocaml-bip39/gen/english.txt vendored Normal file

File diff suppressed because it is too large Load Diff

140
vendors/ocaml-bip39/src/bip39.ml vendored Normal file
View File

@ -0,0 +1,140 @@
(*---------------------------------------------------------------------------
Copyright (c) 2017 Vincent Bernardoff. All rights reserved.
Distributed under the ISC license, see terms at the end of the file.
---------------------------------------------------------------------------*)
open StdLabels
let acceptable_num_words = [12 ; 15 ; 18 ; 21 ; 24]
type entropy = {
bytes : Cstruct.t ;
length : int ;
digest_length : int ;
num_words : int ;
}
let entropy_of_bytes bytes =
match Cstruct.len bytes with
| 16 -> Some { bytes ; length = 16 ; digest_length = 4 ; num_words = 12 }
| 20 -> Some { bytes ; length = 20 ; digest_length = 5 ; num_words = 15 }
| 24 -> Some { bytes ; length = 24 ; digest_length = 6 ; num_words = 18 }
| 28 -> Some { bytes ; length = 28 ; digest_length = 7 ; num_words = 21 }
| 32 -> Some { bytes ; length = 32 ; digest_length = 8 ; num_words = 24 }
| _ -> None
type t = int list
let index_of_word word =
let index = ref (-1) in
try
List.iteri English.words ~f:begin fun i w ->
if String.compare word w = 0 then (index := i ; raise Exit)
end ;
None
with Exit -> Some !index
let of_words words =
try
List.fold_right words ~init:(0, []) ~f:begin fun word (count, acc) ->
match index_of_word word with
| Some i -> (succ count, i :: acc)
| _ -> raise Exit
end |> fun (count, x) ->
if List.(mem count ~set:acceptable_num_words) then Some x
else None
with Exit -> None
let of_indices idxs =
try
List.fold_right idxs ~init:(0, []) ~f:begin fun i (count, acc) ->
if i < 0 || i > 2047 then raise Exit
else (succ count, i :: acc)
end |> fun (count, x) ->
if List.(mem count ~set:acceptable_num_words) then Some x
else None
with Exit -> None
let to_words = List.map ~f:(List.nth English.words)
let to_indices t = t
let pp ppf t =
let open Format in
let words = to_words t in
let pp_mnemonic =
pp_print_list
~pp_sep:(fun fmt () -> fprintf fmt " ")
pp_print_string in
fprintf ppf "%a" pp_mnemonic words
let show t =
Format.asprintf "%a" pp t
let int_of_bits bits =
snd @@ List.fold_right bits ~init:(0, 0) ~f:begin fun b (i, res) ->
succ i, if b then res lor (1 lsl i) else res
end
let bits_of_char c =
let b = Char.code c in
let res = ref [] in
for i = 0 to 7 do
res := (b land (1 lsl i) <> 0) :: !res
done ;
!res
let bits_of_bytes bytes =
let acc = ref [] in
String.iter bytes ~f:begin fun c ->
acc := List.rev_append (bits_of_char c) !acc
end ;
List.rev !acc
let list_sub l n =
let rec inner acc n l =
if n > 0 then match l with
| h :: tl -> inner (h :: acc) (pred n) tl
| _ -> invalid_arg "Bip39.list_sub"
else List.rev acc
in inner [] n l
let pack l pack_len =
let rec inner (sub_acc_len, sub_acc, acc) = function
| [] -> if sub_acc <> [] then List.rev sub_acc :: acc else acc
| h :: tl ->
if sub_acc_len = pack_len then
inner (1, [h], List.rev sub_acc :: acc) tl
else inner (succ sub_acc_len, h :: sub_acc, acc) tl
in
List.rev (inner (0, [], []) l)
let of_entropy entropy =
match entropy_of_bytes entropy with
| None -> invalid_arg "Bip39.of_entropy: wrong entropy length"
| Some { bytes ; digest_length ; _ } ->
let digest = Cstruct.get_char (Nocrypto.Hash.SHA256.digest entropy) 0 in
let digest = list_sub (bits_of_char digest) digest_length in
let entropy = bits_of_bytes (Cstruct.to_string bytes) @ digest in
List.map (pack entropy 11) ~f:int_of_bits
let to_seed ?(passphrase="") t =
let words = to_words t in
let password = Cstruct.of_string (String.concat ~sep:" " words) in
let salt = Cstruct.of_string ("mnemonic" ^ passphrase) in
Pbkdf.pbkdf2 ~prf:`SHA512 ~password ~salt ~count:2048 ~dk_len:64l
(*---------------------------------------------------------------------------
Copyright (c) 2017 Vincent Bernardoff
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
---------------------------------------------------------------------------*)

56
vendors/ocaml-bip39/src/bip39.mli vendored Normal file
View File

@ -0,0 +1,56 @@
(*---------------------------------------------------------------------------
Copyright (c) 2017 Vincent Bernardoff. All rights reserved.
Distributed under the ISC license, see terms at the end of the file.
---------------------------------------------------------------------------*)
type t
(** Abstract type of a mnemonic *)
val pp : Format.formatter -> t -> unit
val show : t -> string
val index_of_word : string -> int option
(** [find_index word] is [Some i] where is is the index of [word] in
the BIP39 word list, or [None] if no such word is in the list. *)
val of_indices : int list -> t option
(** [of_indices idxs] is [Some mnemonic] if indices are all in range
[0-2047] or [None] otherwise. *)
val to_indices : t -> int list
(** [to_indices t] is the list of indices corresponding to [t]. *)
val of_words : string list -> t option
(** [of_words words] is [Some mnemonic] if [words] is a list
containing a valids number of valid english words. *)
val to_words : t -> string list
(** [to_words mnemonic] is the list of words corresponding to
[mnemonic]. *)
val of_entropy : Cstruct.t -> t
(** [of_entropy bytes] is the mnemonic derived from [bytes].
@raises [Invalid_argument] is [List.length bytes] is not in { 16,
20, 24, 28, 32 }. *)
val to_seed : ?passphrase:string -> t -> Cstruct.t
(** [to_seed ?passphrase mnemonic] is 64 bytes derived from a BIP39
mnemonic [mnemonic], using the optional passphrase [passphrase] if
provided. *)
(*---------------------------------------------------------------------------
Copyright (c) 2017 Vincent Bernardoff
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
---------------------------------------------------------------------------*)

44
vendors/ocaml-bip39/src/generator.ml vendored Normal file
View File

@ -0,0 +1,44 @@
(*---------------------------------------------------------------------------
Copyright (c) 2017 Vincent Bernardoff. All rights reserved.
Distributed under the ISC license, see terms at the end of the file.
---------------------------------------------------------------------------*)
open Base
open Stdio
let pp_print_quoted_string ppf str =
let open Caml.Format in
fprintf ppf "\"%s\"" str
let pp_print_quoted_string_list ppf strs =
let open Caml.Format in
pp_print_list ~pp_sep:(fun ppf () -> pp_print_string ppf ";")
pp_print_quoted_string ppf strs
let gen ml =
let txt = "../gen/" ^ (Caml.Filename.remove_extension ml) ^ ".txt" in
let words = In_channel.read_lines txt in
Out_channel.with_file
~binary:false ~append:false ~fail_if_exists:false ml ~f:begin fun oc ->
let ppf = Caml.Format.formatter_of_out_channel oc in
Caml.Format.fprintf ppf "let words = [%a]@." pp_print_quoted_string_list words
end
let () =
Array.to_list Caml.Sys.argv |> List.tl_exn |> List.iter ~f:gen
(*---------------------------------------------------------------------------
Copyright (c) 2017 Vincent Bernardoff
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
---------------------------------------------------------------------------*)

17
vendors/ocaml-bip39/src/jbuild vendored Normal file
View File

@ -0,0 +1,17 @@
(jbuild_version 1)
(library
((name bip39)
(public_name bip39)
(modules (english bip39))
(libraries (nocrypto pbkdf))))
(rule
((targets (english.ml))
(deps (generator.exe (files_recursively_in ../gen)))
(action (run ${<} ${@}))))
(executable
((name generator)
(modules (generator))
(libraries (stdio))))

8
vendors/ocaml-bip39/test/jbuild vendored Normal file
View File

@ -0,0 +1,8 @@
(executable
((name test)
(libraries (bip39 hex alcotest))))
(alias
((name runtest-bip39)
(deps (test.exe))
(action (run ${<}))))

138
vendors/ocaml-bip39/test/test.ml vendored Normal file
View File

@ -0,0 +1,138 @@
open Alcotest
type vector = {
entropy : Hex.t ;
words : string ;
seed : Hex.t ;
}
let vectors = [
{ entropy = `Hex "00000000000000000000000000000000" ;
words = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about" ;
seed = `Hex "c55257c360c07c72029aebc1b53c05ed0362ada38ead3e3e9efa3708e53495531f09a6987599d18264c1e1c92f2cf141630c7a3c4ab7c81b2f001698e7463b04" ;
} ;
{ entropy = `Hex "7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f" ;
words = "legal winner thank year wave sausage worth useful legal winner thank yellow" ;
seed = `Hex "2e8905819b8723fe2c1d161860e5ee1830318dbf49a83bd451cfb8440c28bd6fa457fe1296106559a3c80937a1c1069be3a3a5bd381ee6260e8d9739fce1f607" ;
} ;
{ entropy = `Hex "80808080808080808080808080808080" ;
words = "letter advice cage absurd amount doctor acoustic avoid letter advice cage above" ;
seed = `Hex "d71de856f81a8acc65e6fc851a38d4d7ec216fd0796d0a6827a3ad6ed5511a30fa280f12eb2e47ed2ac03b5c462a0358d18d69fe4f985ec81778c1b370b652a8" ;
} ;
{ entropy = `Hex "ffffffffffffffffffffffffffffffff" ;
words = "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong" ;
seed = `Hex "ac27495480225222079d7be181583751e86f571027b0497b5b5d11218e0a8a13332572917f0f8e5a589620c6f15b11c61dee327651a14c34e18231052e48c069" ;
} ;
{ entropy = `Hex "000000000000000000000000000000000000000000000000" ;
words = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon agent" ;
seed = `Hex "035895f2f481b1b0f01fcf8c289c794660b289981a78f8106447707fdd9666ca06da5a9a565181599b79f53b844d8a71dd9f439c52a3d7b3e8a79c906ac845fa" ;
} ;
{ entropy = `Hex "7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f" ;
words = "legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal will" ;
seed = `Hex "f2b94508732bcbacbcc020faefecfc89feafa6649a5491b8c952cede496c214a0c7b3c392d168748f2d4a612bada0753b52a1c7ac53c1e93abd5c6320b9e95dd" ;
} ;
{ entropy = `Hex "808080808080808080808080808080808080808080808080" ;
words = "letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter always" ;
seed = `Hex "107d7c02a5aa6f38c58083ff74f04c607c2d2c0ecc55501dadd72d025b751bc27fe913ffb796f841c49b1d33b610cf0e91d3aa239027f5e99fe4ce9e5088cd65" ;
} ;
{ entropy = `Hex "ffffffffffffffffffffffffffffffffffffffffffffffff" ;
words = "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo when" ;
seed = `Hex "0cd6e5d827bb62eb8fc1e262254223817fd068a74b5b449cc2f667c3f1f985a76379b43348d952e2265b4cd129090758b3e3c2c49103b5051aac2eaeb890a528" ;
} ;
{ entropy = `Hex "0000000000000000000000000000000000000000000000000000000000000000" ;
words = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art" ;
seed = `Hex "bda85446c68413707090a52022edd26a1c9462295029f2e60cd7c4f2bbd3097170af7a4d73245cafa9c3cca8d561a7c3de6f5d4a10be8ed2a5e608d68f92fcc8" ;
} ;
{ entropy = `Hex "7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f" ;
words = "legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth title" ;
seed = `Hex "bc09fca1804f7e69da93c2f2028eb238c227f2e9dda30cd63699232578480a4021b146ad717fbb7e451ce9eb835f43620bf5c514db0f8add49f5d121449d3e87" ;
} ;
{ entropy = `Hex "8080808080808080808080808080808080808080808080808080808080808080" ;
words = "letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic bless" ;
seed = `Hex "c0c519bd0e91a2ed54357d9d1ebef6f5af218a153624cf4f2da911a0ed8f7a09e2ef61af0aca007096df430022f7a2b6fb91661a9589097069720d015e4e982f" ;
} ;
{ entropy = `Hex "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" ;
words = "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo vote" ;
seed = `Hex "dd48c104698c30cfe2b6142103248622fb7bb0ff692eebb00089b32d22484e1613912f0a5b694407be899ffd31ed3992c456cdf60f5d4564b8ba3f05a69890ad" ;
} ;
{ entropy = `Hex "9e885d952ad362caeb4efe34a8e91bd2" ;
words = "ozone drill grab fiber curtain grace pudding thank cruise elder eight picnic" ;
seed = `Hex "274ddc525802f7c828d8ef7ddbcdc5304e87ac3535913611fbbfa986d0c9e5476c91689f9c8a54fd55bd38606aa6a8595ad213d4c9c9f9aca3fb217069a41028" ;
} ;
{ entropy = `Hex "6610b25967cdcca9d59875f5cb50b0ea75433311869e930b" ;
words = "gravity machine north sort system female filter attitude volume fold club stay feature office ecology stable narrow fog" ;
seed = `Hex "628c3827a8823298ee685db84f55caa34b5cc195a778e52d45f59bcf75aba68e4d7590e101dc414bc1bbd5737666fbbef35d1f1903953b66624f910feef245ac" ;
} ;
{ entropy = `Hex "68a79eaca2324873eacc50cb9c6eca8cc68ea5d936f98787c60c7ebc74e6ce7c" ;
words = "hamster diagram private dutch cause delay private meat slide toddler razor book happy fancy gospel tennis maple dilemma loan word shrug inflict delay length" ;
seed = `Hex "64c87cde7e12ecf6704ab95bb1408bef047c22db4cc7491c4271d170a1b213d20b385bc1588d9c7b38f1b39d415665b8a9030c9ec653d75e65f847d8fc1fc440" ;
} ;
{ entropy = `Hex "c0ba5a8e914111210f2bd131f3d5e08d" ;
words = "scheme spot photo card baby mountain device kick cradle pact join borrow" ;
seed = `Hex "ea725895aaae8d4c1cf682c1bfd2d358d52ed9f0f0591131b559e2724bb234fca05aa9c02c57407e04ee9dc3b454aa63fbff483a8b11de949624b9f1831a9612" ;
} ;
{ entropy = `Hex "6d9be1ee6ebd27a258115aad99b7317b9c8d28b6d76431c3" ;
words = "horn tenant knee talent sponsor spell gate clip pulse soap slush warm silver nephew swap uncle crack brave" ;
seed = `Hex "fd579828af3da1d32544ce4db5c73d53fc8acc4ddb1e3b251a31179cdb71e853c56d2fcb11aed39898ce6c34b10b5382772db8796e52837b54468aeb312cfc3d" ;
} ;
{ entropy = `Hex "9f6a2878b2520799a44ef18bc7df394e7061a224d2c33cd015b157d746869863" ;
words = "panda eyebrow bullet gorilla call smoke muffin taste mesh discover soft ostrich alcohol speed nation flash devote level hobby quick inner drive ghost inside" ;
seed = `Hex "72be8e052fc4919d2adf28d5306b5474b0069df35b02303de8c1729c9538dbb6fc2d731d5f832193cd9fb6aeecbc469594a70e3dd50811b5067f3b88b28c3e8d" ;
} ;
{ entropy = `Hex "23db8160a31d3e0dca3688ed941adbf3" ;
words = "cat swing flag economy stadium alone churn speed unique patch report train" ;
seed = `Hex "deb5f45449e615feff5640f2e49f933ff51895de3b4381832b3139941c57b59205a42480c52175b6efcffaa58a2503887c1e8b363a707256bdd2b587b46541f5" ;
} ;
{ entropy = `Hex "8197a4a47f0425faeaa69deebc05ca29c0a5b5cc76ceacc0" ;
words = "light rule cinnamon wrap drastic word pride squirrel upgrade then income fatal apart sustain crack supply proud access" ;
seed = `Hex "4cbdff1ca2db800fd61cae72a57475fdc6bab03e441fd63f96dabd1f183ef5b782925f00105f318309a7e9c3ea6967c7801e46c8a58082674c860a37b93eda02" ;
} ;
{ entropy = `Hex "066dca1a2bb7e8a1db2832148ce9933eea0f3ac9548d793112d9a95c9407efad" ;
words = "all hour make first leader extend hole alien behind guard gospel lava path output census museum junior mass reopen famous sing advance salt reform" ;
seed = `Hex "26e975ec644423f4a4c4f4215ef09b4bd7ef924e85d1d17c4cf3f136c2863cf6df0a475045652c57eb5fb41513ca2a2d67722b77e954b4b3fc11f7590449191d" ;
} ;
{ entropy = `Hex "f30f8c1da665478f49b001d94c5fc452" ;
words = "vessel ladder alter error federal sibling chat ability sun glass valve picture" ;
seed = `Hex "2aaa9242daafcee6aa9d7269f17d4efe271e1b9a529178d7dc139cd18747090bf9d60295d0ce74309a78852a9caadf0af48aae1c6253839624076224374bc63f" ;
} ;
{ entropy = `Hex "c10ec20dc3cd9f652c7fac2f1230f7a3c828389a14392f05" ;
words = "scissors invite lock maple supreme raw rapid void congress muscle digital elegant little brisk hair mango congress clump" ;
seed = `Hex "7b4a10be9d98e6cba265566db7f136718e1398c71cb581e1b2f464cac1ceedf4f3e274dc270003c670ad8d02c4558b2f8e39edea2775c9e232c7cb798b069e88" ;
} ;
{ entropy = `Hex "f585c11aec520db57dd353c69554b21a89b20fb0650966fa0a9d6f74fd989d8f" ;
words = "void come effort suffer camp survey warrior heavy shoot primary clutch crush open amazing screen patrol group space point ten exist slush involve unfold" ;
seed = `Hex "01f5bced59dec48e362f2c45b5de68b9fd6c92c6634f44d6d40aab69056506f0e35524a518034ddc1192e1dacd32c1ed3eaa3c3b131c88ed8e7e54c49a5d0998" ;
} ;
]
let pp_diff ppf (l1, l2) =
match List.length l1, List.length l2 with
| n, m when n <> m ->
Format.fprintf ppf "Mnemonic size differs: %d vs %d" n m ;
| _ ->
ignore @@ ListLabels.fold_left2 l1 l2 ~init:0 ~f:begin fun i w1 w2 ->
if w1 <> w2 then begin
Format.fprintf ppf "At position %d, words differ: %s <> %s"
i w1 w2
end ;
succ i
end
let vectors () =
ListLabels.iteri vectors ~f:begin fun i { entropy ; words ; seed } ->
let words = String.split_on_char ' ' words in
let mnemonic = Bip39.of_entropy (Cstruct.of_string (Hex.to_string entropy)) in
let words_computed = Bip39.to_words mnemonic in
assert (words = words_computed) ;
let seed_computed = Bip39.to_seed ~passphrase:"TREZOR" mnemonic in
assert ((Hex.to_cstruct seed) = seed_computed)
end
let basic = [
"vectors", `Quick, vectors ;
]
let () =
Alcotest.run "bip39" [
"basic", basic ;
]