Vendors/blake2b: use bigstring

This commit is contained in:
Vincent Bernardoff 2018-04-17 10:37:49 +02:00 committed by Grégoire Henry
parent c1bce70c50
commit 230d495dc6
9 changed files with 56 additions and 82 deletions

View File

@ -38,7 +38,7 @@ module Make_minimal (K : Name) = struct
if String.length s <> size then if String.length s <> size then
None None
else else
Some (Blake2b.Hash (Cstruct.of_string s)) Some (Blake2b.Hash (MBytes.of_string s))
let of_string s = let of_string s =
match of_string_opt s with match of_string_opt s with
| None -> | None ->
@ -52,7 +52,7 @@ module Make_minimal (K : Name) = struct
"%s.of_string: wrong string size (%d)" "%s.of_string: wrong string size (%d)"
K.name (String.length s) K.name (String.length s)
| Some h -> h | Some h -> h
let to_string (Blake2b.Hash h) = Cstruct.to_string h let to_string (Blake2b.Hash h) = MBytes.to_string h
let of_hex s = of_string (Hex.to_string s) let of_hex s = of_string (Hex.to_string s)
let of_hex_opt s = of_string_opt (Hex.to_string s) let of_hex_opt s = of_string_opt (Hex.to_string s)
@ -70,7 +70,7 @@ module Make_minimal (K : Name) = struct
if MBytes.length b <> size then if MBytes.length b <> size then
None None
else else
Some (Blake2b.Hash (Cstruct.of_bigarray b)) Some (Blake2b.Hash b)
let of_bytes_exn b = let of_bytes_exn b =
match of_bytes_opt b with match of_bytes_opt b with
| None -> | None ->
@ -84,21 +84,20 @@ module Make_minimal (K : Name) = struct
| Some x -> Ok x | Some x -> Ok x
| None -> | None ->
generic_error "Failed to deserialize a hash (%s)" K.name generic_error "Failed to deserialize a hash (%s)" K.name
let to_bytes (Blake2b.Hash h) = Cstruct.to_bigarray h let to_bytes (Blake2b.Hash h) = h
(* let read src off = of_bytes_exn @@ MBytes.sub src off size *) (* let read src off = of_bytes_exn @@ MBytes.sub src off size *)
(* let write dst off h = MBytes.blit (to_bytes h) 0 dst off size *) (* let write dst off h = MBytes.blit (to_bytes h) 0 dst off size *)
let hash_bytes ?key l = let hash_bytes ?key l =
let key = Option.map ~f:Cstruct.of_bigarray key in
let state = Blake2b.init ?key size in let state = Blake2b.init ?key size in
List.iter (fun b -> Blake2b.update state (Cstruct.of_bigarray b)) l ; List.iter (fun b -> Blake2b.update state b) l ;
Blake2b.final state Blake2b.final state
let hash_string ?key l = let hash_string ?key l =
let key = Option.map ~f:Cstruct.of_string key in let key = Option.map ~f:Bigstring.of_string key in
let state = Blake2b.init ?key size in let state = Blake2b.init ?key size in
List.iter (fun s -> Blake2b.update state (Cstruct.of_string s)) l ; List.iter (fun s -> Blake2b.update state (MBytes.of_string s)) l ;
Blake2b.final state Blake2b.final state
let path_length = 6 let path_length = 6
@ -129,7 +128,7 @@ module Make_minimal (K : Name) = struct
include Compare.Make(struct include Compare.Make(struct
type nonrec t = t type nonrec t = t
let compare (Blake2b.Hash h1) (Blake2b.Hash h2) = Cstruct.compare h1 h2 let compare (Blake2b.Hash h1) (Blake2b.Hash h2) = MBytes.compare h1 h2
end) end)
end end

View File

@ -29,7 +29,7 @@ module type MINIMAL_HASH = sig
include Compare.S with type t := t include Compare.S with type t := t
val hash_bytes: ?key:Cstruct.buffer -> Cstruct.buffer list -> t val hash_bytes: ?key:MBytes.t -> MBytes.t list -> t
val hash_string: ?key:string -> string list -> t val hash_string: ?key:string -> string list -> t
val zero: t val zero: t

View File

@ -116,25 +116,6 @@ let debug fmt =
if !debug_flag then Format.eprintf fmt if !debug_flag then Format.eprintf fmt
else Format.ifprintf Format.err_formatter fmt else Format.ifprintf Format.err_formatter fmt
let hash_file file =
let open Blake2 in
let buflen = 8092 in
let buf = BytesLabels.create buflen in
let fd = Unix.openfile file [Unix.O_RDONLY] 0o600 in
let state = Blake2b.init 32 in
let loop () =
match Unix.read fd buf 0 buflen with
| 0 -> ()
| nb_read ->
Blake2b.update state
(Cstruct.of_bytes
(if nb_read = buflen then buf else BytesLabels.sub buf ~pos:0 ~len:nb_read))
in
loop () ;
Unix.close fd ;
let Blake2b.Hash h = Blake2b.final state in
Cstruct.to_string h
let mktemp_dir () = let mktemp_dir () =
Filename.get_temp_dir_name () // Filename.get_temp_dir_name () //
Printf.sprintf "tezos-protocol-build-%06X" (Random.int 0xFFFFFF) Printf.sprintf "tezos-protocol-build-%06X" (Random.int 0xFFFFFF)

View File

@ -16,6 +16,7 @@ build: [ "jbuilder" "build" "-j" jobs "-p" name "@install" ]
build-test: [ "jbuilder" "runtest" "-p" name "-j" jobs ] build-test: [ "jbuilder" "runtest" "-p" name "-j" jobs ]
depends: [ depends: [
"jbuilder" {build & >= "1.0+beta16"} "jbuilder" {build & >= "1.0+beta16"}
"cstruct" {>= "3.2.1"} "bigstring" {>= "0.1.1"}
"alcotest" { test } "alcotest" { test }
"hex" {test & >= "1.2.0"}
] ]

View File

@ -4,32 +4,32 @@
---------------------------------------------------------------------------*) ---------------------------------------------------------------------------*)
module Blake2b = struct module Blake2b = struct
type t = Cstruct.t type t = Bigstring.t
external sizeof_state : unit -> int = external sizeof_state : unit -> int =
"sizeof_blake2b_state" [@@noalloc] "sizeof_blake2b_state" [@@noalloc]
let bytes = sizeof_state () let bytes = sizeof_state ()
external init : Cstruct.buffer -> int -> int = external init : Bigstring.t -> int -> int =
"ml_blake2b_init" [@@noalloc] "ml_blake2b_init" [@@noalloc]
external outlen : Cstruct.buffer -> int = external outlen : Bigstring.t -> int =
"blake2b_state_outlen" [@@noalloc] "blake2b_state_outlen" [@@noalloc]
let outlen t = outlen t.Cstruct.buffer let outlen t = outlen t
external init_key : Cstruct.buffer -> int -> Cstruct.buffer -> int = external init_key : Bigstring.t -> int -> Bigstring.t -> int =
"ml_blake2b_init_key" [@@noalloc] "ml_blake2b_init_key" [@@noalloc]
external update : Cstruct.buffer -> Cstruct.buffer -> int = external update : Bigstring.t -> Bigstring.t -> int =
"ml_blake2b_update" [@@noalloc] "ml_blake2b_update" [@@noalloc]
external final : Cstruct.buffer -> Cstruct.buffer -> int = external final : Bigstring.t -> Bigstring.t -> int =
"ml_blake2b_final" [@@noalloc] "ml_blake2b_final" [@@noalloc]
external direct : external direct :
Cstruct.buffer -> Cstruct.buffer -> Cstruct.buffer -> int = Bigstring.t -> Bigstring.t -> Bigstring.t -> int =
"ml_blake2b" [@@noalloc] "ml_blake2b" [@@noalloc]
let or_fail ~msg f = let or_fail ~msg f =
@ -40,37 +40,33 @@ module Blake2b = struct
let init ?key size = let init ?key size =
if size < 1 || size > 64 then if size < 1 || size > 64 then
invalid_arg "Blake2b.init: size must be between 1 and 64" ; invalid_arg "Blake2b.init: size must be between 1 and 64" ;
let t = Cstruct.create_unsafe bytes in let t = Bigstring.create bytes in
begin match key with begin match key with
| Some key -> | Some key ->
or_fail ~msg:"Blake2b.init" or_fail ~msg:"Blake2b.init"
(fun () -> init_key t.buffer size key.Cstruct.buffer) (fun () -> init_key t size key)
| None -> | None ->
or_fail ~msg:"Blake2b.init" or_fail ~msg:"Blake2b.init"
(fun () -> init t.buffer size) (fun () -> init t size)
end ; end ;
t t
let update t buf = let update t buf =
or_fail ~msg:"Blake2b.update" or_fail ~msg:"Blake2b.update" (fun () -> update t buf)
(fun () -> update t.Cstruct.buffer buf.Cstruct.buffer)
type hash = Hash of Cstruct.t type hash = Hash of Bigstring.t
let final t = let final t =
let len = outlen t in let len = outlen t in
let buf = Cstruct.create_unsafe len in let buf = Bigstring.create len in
or_fail ~msg:"Blake2b.final" or_fail ~msg:"Blake2b.final" (fun () -> final t buf) ;
(fun () -> final t.Cstruct.buffer buf.Cstruct.buffer) ;
Hash buf Hash buf
let direct ?(key=Cstruct.create_unsafe 0) inbuf len = let direct ?(key=Bigstring.create 0) inbuf len =
if len < 1 || len > 64 then if len < 1 || len > 64 then
invalid_arg "Blake2b.direct: size must be between 1 and 64" ; invalid_arg "Blake2b.direct: size must be between 1 and 64" ;
let outbuf = Cstruct.create len in let outbuf = Bigstring.create len in
or_fail ~msg:"Blake2b.direct" or_fail ~msg:"Blake2b.direct" (fun () -> direct outbuf inbuf key) ;
(fun () -> direct outbuf.Cstruct.buffer
inbuf.Cstruct.buffer key.buffer) ;
Hash outbuf Hash outbuf
end end

View File

@ -5,20 +5,20 @@
module Blake2b : sig module Blake2b : sig
type t type t
type hash = Hash of Cstruct.t type hash = Hash of Bigstring.t
val init : ?key:Cstruct.t -> int -> t val init : ?key:Bigstring.t -> int -> t
(** [init ?key size] is a blake2b context for hashes of size [size], (** [init ?key size] is a blake2b context for hashes of size [size],
using [key] if present. *) using [key] if present. *)
val update : t -> Cstruct.t -> unit val update : t -> Bigstring.t -> unit
(** [update t buf] updates [t] with the data in [buf]. *) (** [update t buf] updates [t] with the data in [buf]. *)
val final : t -> hash val final : t -> hash
(** [final t] is the blake2b hash of all data updated in [t] so (** [final t] is the blake2b hash of all data updated in [t] so
far. *) far. *)
val direct : ?key:Cstruct.t -> Cstruct.t -> int -> hash val direct : ?key:Bigstring.t -> Bigstring.t -> int -> hash
(** [direct ?key inbuf len] is the blake2b hash of length [len], (** [direct ?key inbuf len] is the blake2b hash of length [len],
using [key] is present. *) using [key] is present. *)
end end

View File

@ -3,5 +3,6 @@
(library (library
((name blake2) ((name blake2)
(public_name blake2) (public_name blake2)
(libraries (cstruct)) (libraries (bigstring))
(c_names (blake2b-ref)))) (c_names (blake2b-ref))
(c_flags (-O3))))

View File

@ -2,7 +2,7 @@
(executable (executable
((name test) ((name test)
(libraries (blake2 alcotest)))) (libraries (blake2 hex alcotest))))
(alias (alias
((name runtest-blake2) ((name runtest-blake2)

View File

@ -2,44 +2,40 @@
open Blake2 open Blake2
type vector = { type vector = {
data_in : string list ; data_in : Bigstring.t list ;
data_key : string option ; data_key : Bigstring.t option ;
data_out : string ; data_out : Bigstring.t ;
} }
let hex s =
Cstruct.to_bigarray (Hex.to_cstruct (`Hex s))
let vectors = [ let vectors = [
{ data_in = [ "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" ] ; { data_in = [ hex "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" ] ;
data_key = None ; data_key = None ;
data_out = "1c077e279de6548523502b6df800ffdab5e2c3e9442eb838f58c295f3b147cef9d701c41c321283f00c71affa0619310399126295b78dd4d1a74572ef9ed5135" ; data_out = hex "1c077e279de6548523502b6df800ffdab5e2c3e9442eb838f58c295f3b147cef9d701c41c321283f00c71affa0619310399126295b78dd4d1a74572ef9ed5135" ;
} ; } ;
{ data_in = [ "000102030405060708090a0b0c0d0e0f101112131415" ; "161718"; "191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" ] ; { data_in = [ hex "000102030405060708090a0b0c0d0e0f101112131415" ; hex "161718"; hex "191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" ] ;
data_key = None ; data_key = None ;
data_out = "1c077e279de6548523502b6df800ffdab5e2c3e9442eb838f58c295f3b147cef9d701c41c321283f00c71affa0619310399126295b78dd4d1a74572ef9ed5135" ; data_out = hex "1c077e279de6548523502b6df800ffdab5e2c3e9442eb838f58c295f3b147cef9d701c41c321283f00c71affa0619310399126295b78dd4d1a74572ef9ed5135" ;
} ; } ;
{ data_in = [ "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3" ] ; { data_in = [ hex "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3" ] ;
data_key = Some ("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f") ; data_key = Some (hex "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f") ;
data_out = "b39614268fdd8781515e2cfebf89b4d5402bab10c226e6344e6b9ae000fb0d6c79cb2f3ec80e80eaeb1980d2f8698916bd2e9f747236655116649cd3ca23a837" ; data_out = hex "b39614268fdd8781515e2cfebf89b4d5402bab10c226e6344e6b9ae000fb0d6c79cb2f3ec80e80eaeb1980d2f8698916bd2e9f747236655116649cd3ca23a837" ;
} ; } ;
] ]
let test_update { data_in ; data_key ; data_out } = let test_update { data_in ; data_key ; data_out } =
let key = let d = Blake2b.init ?key:data_key (Bigstring.length data_out) in
match data_key with None -> None | Some s -> Some (Cstruct.of_hex s) in List.iter (Blake2b.update d) data_in ;
let data_out = Cstruct.of_hex data_out in
let d = Blake2b.init ?key (Cstruct.len data_out) in
List.iter (fun s -> Blake2b.update d (Cstruct.of_hex s)) data_in ;
let Blake2b.Hash h = Blake2b.final d in let Blake2b.Hash h = Blake2b.final d in
assert Cstruct.(equal data_out h) assert Bigstring.(equal data_out h)
let test_direct { data_in ; data_key ; data_out } = let test_direct { data_in ; data_key ; data_out } =
let key =
match data_key with None -> None | Some s -> Some (Cstruct.of_hex s) in
let data_out = Cstruct.of_hex data_out in
let Blake2b.Hash h = let Blake2b.Hash h =
Blake2b.direct ?key Blake2b.direct ?key:data_key
(Cstruct.of_hex (String.concat "" data_in)) (Bigstring.concat "" data_in) (Bigstring.length data_out) in
(Cstruct.len data_out) in assert Bigstring.(equal data_out h)
assert Cstruct.(equal data_out h)
let update_tests = let update_tests =
List.mapi List.mapi