Shell: switch to Blake2b (closes #87 #89)

Also drop the dependencies on Cryptokit.
This commit is contained in:
Grégoire Henry 2016-11-25 19:46:50 +01:00
parent daf3343dc1
commit 17475aa743
23 changed files with 138 additions and 99 deletions

View File

@ -23,7 +23,6 @@ PKG cohttp
PKG compiler-libs.optcomp
PKG conduit
PKG config-file
PKG cryptokit
PKG cstruct
PKG dynlink
PKG ezjsonm

View File

@ -121,9 +121,9 @@ UTILS_LIB_IMPLS := \
utils/cli_entries.ml \
utils/compare.ml \
utils/data_encoding.ml \
utils/crypto_box.ml \
utils/time.ml \
utils/hash.ml \
utils/crypto_box.ml \
utils/error_monad_sig.ml \
utils/error_monad.ml \
utils/logging.ml \
@ -133,7 +133,6 @@ UTILS_LIB_IMPLS := \
UTILS_PACKAGES := \
base64 \
calendar \
cryptokit \
cstruct \
ezjsonm \
lwt \

View File

@ -9,7 +9,7 @@
let protocol =
Protocol_hash.of_b48check
"4prgmSgbaeMKbgLtLjpsHaDD9QvG2dbC2bLq2XBmyxd2RJgLFpcAg"
"4p64VagsbXchSF88eaPy5XrkqMLEjBCaSnaGv2vQkhv8e37Nnqmrd"
let () =
Client_version.register protocol @@

View File

@ -9,7 +9,7 @@
let protocol =
Protocol_hash.of_b48check
"2gagXCT66nmJ2mKh3a6Aeysy9CHaHsAJyDEGSyFNeFAxGCJehsKpK"
"2gagsSEvTKAHRjxAamgSdBNkv39VtNCqpaDXrrH4K8R4KQAAHrhe3"
let demo () =
let block = Client_config.block () in

View File

@ -330,7 +330,7 @@ module RPC = struct
let prevalidation_hash =
Block_hash.of_b48check
"eeeeeeeeeeeeeegqJHARhSaNXggmMs8K3tvsgn4rBprkvpFAMVD5d"
"eeeeeeeeeeeeeeefcF2dFpTjGjPAxRM3TqDrKkJf7DdkNHpX3DmaD"
let get_net node = function
| `Head _ | `Prevalidation -> node.global_validator, node.global_net

View File

@ -25,10 +25,11 @@ module Ed25519 = struct
let append_signature key msg =
MBytes.concat msg (sign key msg)
module Public_key_hash = Hash.Make_SHA256(Base48)(struct
module Public_key_hash = Hash.Make_Blake2B(Base48)(struct
let name = "Ed25519.Public_key_hash"
let title = "An Ed25519 public key ID"
let b48check_prefix = Base48.Prefix.ed25519_public_key_hash
let size = Some 20
end)
let hash v =

View File

@ -12,18 +12,18 @@ open Logging.Node.Main
let genesis_block =
Block_hash.of_b48check
"eeHfgnr9QeDNvcMgSfATNeDeec4KG4CkHHkNNJt5B9xdVmsxhsHNR"
"grHGHkVfgJb5gPaRd5AtQsa65g9GyLcXgQsHbSnQ5SD5DEp2ctqck"
let genesis_protocol =
Protocol_hash.of_b48check
"4prgmSgbaeMKbgLtLjpsHaDD9QvG2dbC2bLq2XBmyxd2RJgLFpcAg"
"4p64VagsbXchSF88eaPy5XrkqMLEjBCaSnaGv2vQkhv8e37Nnqmrd"
let test_protocol =
Some (Protocol_hash.of_b48check
"2gagXCT66nmJ2mKh3a6Aeysy9CHaHsAJyDEGSyFNeFAxGCJehsKpK")
"2gagsSEvTKAHRjxAamgSdBNkv39VtNCqpaDXrrH4K8R4KQAAHrhe3")
let genesis_time =
Time.of_notation_exn "2016-08-01T00:00:00Z"
Time.of_notation_exn "2016-11-01T00:00:00Z"
let genesis = {
Store.time = genesis_time ;

View File

@ -1,5 +1,5 @@
{
"hash": "4prgmSgbaeMKbgLtLjpsHaDD9QvG2dbC2bLq2XBmyxd2RJgLFpcAg",
"hash": "4p64VagsbXchSF88eaPy5XrkqMLEjBCaSnaGv2vQkhv8e37Nnqmrd",
"modules": [
"Misc",

View File

@ -133,7 +133,7 @@ let first_endorsement_slots
select_delegate delegate delegate_list max_priority
let check_hash hash stamp_threshold =
let bytes = Block_hash.to_raw hash in
let bytes = Block_hash.to_string hash in
let word = String.get_int64 bytes 0 in
Compare.Uint64.(word < stamp_threshold)

View File

@ -202,9 +202,10 @@ end
module Make_data_set_storage (P : Single_data_description) = struct
module Key = struct
include Hash.Make_minimal_SHA256(struct
include Hash.Make_minimal_Blake2B(struct
let name = P.name
let title = ("A " ^ P.name ^ "key")
let size = None
end)
let prefix = P.key
let length = path_len

View File

@ -18,34 +18,38 @@ module Prefix = struct
let random_state_hash = make 15 (* never used... *)
end
module State_hash = Hash.Make_SHA256(Base48)(struct
module State_hash = Hash.Make_Blake2B(Base48)(struct
let name = "random"
let title = "A random generation state"
let b48check_prefix = Prefix.random_state_hash
let size = None
end)
module State_hash_set = Hash_set(State_hash)
module State_hash_map = Hash_map(State_hash)
module Nonce_hash = Hash.Make_SHA256(Base48)(struct
module Nonce_hash = Hash.Make_Blake2B(Base48)(struct
let name = "cycle_nonce"
let title = "A nonce hash"
let b48check_prefix = Prefix.nonce_hash
let size = None
end)
module Nonce_hash_set = Hash_set(Nonce_hash)
module Nonce_hash_map = Hash_map(Nonce_hash)
module Script_expr_hash = Hash.Make_SHA256(Base48)(struct
module Script_expr_hash = Hash.Make_Blake2B(Base48)(struct
let name = "script_expr"
let title = "A script expression ID"
let b48check_prefix = Prefix.script_expr_hash
let size = None
end)
module Script_expr_hash_set = Hash_set(Script_expr_hash)
module Script_expr_hash_map = Hash_map(Script_expr_hash)
module Contract_hash = Hash.Make_SHA256(Base48)(struct
module Contract_hash = Hash.Make_Blake2B(Base48)(struct
let name = "Contract_hash"
let title = "A contract ID"
let b48check_prefix = Prefix.contract_hash
let size = Some 20
end)
module Contract_hash_set = Hash_set(Contract_hash)
module Contract_hash_map = Hash_map(Contract_hash)

View File

@ -1,4 +1,4 @@
{
"hash": "2gagXCT66nmJ2mKh3a6Aeysy9CHaHsAJyDEGSyFNeFAxGCJehsKpK",
"hash": "2gagsSEvTKAHRjxAamgSdBNkv39VtNCqpaDXrrH4K8R4KQAAHrhe3",
"modules": ["Error", "Services", "Main"]
}

View File

@ -21,10 +21,10 @@ module type MINIMAL_HASH = sig
val size: int (* in bytes *)
val compare: t -> t -> int
val equal: t -> t -> bool
val of_raw: string -> t
val to_raw: t -> string
val of_hex: string -> t
val to_hex: t -> string
val of_string: string -> t
val to_string: t -> string
val to_bytes: t -> MBytes.t
val of_bytes: MBytes.t -> t
val read: MBytes.t -> int -> t
@ -54,12 +54,13 @@ end
(** {2 Building Hashes} *******************************************************)
(** The parameters for creating a new Hash type using
{!Make_SHA256}. Both {!name} and {!title} are only informative,
{!Make_Blake2B}. Both {!name} and {!title} are only informative,
used in error messages and serializers. *)
module type Name = sig
val name : string
val title : string
val size : int option
end
module type PrefixedName = sig
@ -69,8 +70,8 @@ end
(** Builds a new Hash type using Sha256. *)
module Make_minimal_SHA256 (Name : Name) : MINIMAL_HASH
module Make_SHA256
module Make_minimal_Blake2B (Name : Name) : MINIMAL_HASH
module Make_Blake2B
(Register : sig
val register_encoding:
prefix: string ->
@ -109,4 +110,3 @@ module Operation_hash_map : module type of Hash_map (Operation_hash)
module Protocol_hash : HASH
module Protocol_hash_set : Set.S with type elt = Protocol_hash.t
module Protocol_hash_map : module type of Hash_map (Protocol_hash)

View File

@ -18,7 +18,6 @@ depends: [
"calendar"
"cohttp" {>= "0.21" }
"config-file"
"cryptokit"
"git"
"git-unix"
"irmin-watcher" (* for `irmin.unix` *)

View File

@ -83,22 +83,25 @@ let raw_decode ?alphabet s =
String.sub res 0 (String.length res - res_tzeros) ^
String.make zeros '\000'
let sha256 s =
let hash = Cryptokit.Hash.sha256 () in
hash#add_string s;
let computed_hash = hash#result in hash#wipe;
computed_hash
let checksum s =
let bytes = Bytes.of_string s in
let hash =
let open Sodium.Generichash in
let state = init ~size:32 () in
Bytes.update state bytes ;
Bytes.of_hash (final state) in
Bytes.sub_string hash 0 4
(* Prepend a 4 byte cryptographic checksum before encoding string s *)
(* Prepend a 4 bytes cryptographic checksum before encoding string s *)
let safe_encode ?alphabet s =
raw_encode ?alphabet (s ^ String.sub (sha256 (sha256 s)) 0 4)
raw_encode ?alphabet (s ^ checksum s)
let safe_decode ?alphabet s =
let s = raw_decode ?alphabet s in
let len = String.length s in
let msg = String.sub s 0 (len-4)
and msg_hash = String.sub s (len-4) 4 in
if msg_hash <> String.sub (sha256 (sha256 msg)) 0 4 then
if msg_hash <> checksum msg then
invalid_arg "safe_decode" ;
msg

View File

@ -33,6 +33,7 @@ let make_target target =
(* Compare a SHA256 hash to a 256bits-target prefix.
The prefix is a list of "unsigned" int64. *)
let compare_target hash target =
let hash = Hash.Generic_hash.to_string hash in
let rec check offset = function
| [] -> true
| x :: xs ->
@ -46,10 +47,10 @@ let default_target =
let check_proof_of_work pk nonce target =
let hash =
let hash = Cryptokit.Hash.sha256 () in
hash#add_string (Bytes.to_string @@ Sodium.Box.Bytes.of_public_key pk) ;
hash#add_string (Bytes.to_string @@ Sodium.Box.Bytes.of_nonce nonce) ;
let r = hash#result in hash#wipe ; r in
Hash.Generic_hash.hash_bytes [
Sodium.Box.Bigbytes.of_public_key pk ;
Sodium.Box.Bigbytes.of_nonce nonce ;
] in
compare_target hash target
let generate_proof_of_work pk target =

View File

@ -13,6 +13,17 @@ let (>|=) = Lwt.(>|=)
open Utils
let () =
let expected_primitive = "blake2b"
and primitive = Sodium.Generichash.primitive in
if primitive <> expected_primitive then begin
Printf.eprintf
"FATAL ERROR: \
invalid value for Sodium.Generichash.primitive: %S (expected %S)@."
primitive expected_primitive ;
exit 1
end
(*-- Signatures -------------------------------------------------------------*)
module type MINIMAL_HASH = sig
@ -27,10 +38,10 @@ module type MINIMAL_HASH = sig
val size: int (* in bytes *)
val compare: t -> t -> int
val equal: t -> t -> bool
val of_raw: string -> t
val to_raw: t -> string
val of_hex: string -> t
val to_hex: t -> string
val of_string: string -> t
val to_string: t -> string
val to_bytes: t -> MBytes.t
val of_bytes: MBytes.t -> t
val read: MBytes.t -> int -> t
@ -60,6 +71,7 @@ end
module type Name = sig
val name: string
val title: string
val size: int option
end
module type PrefixedName = sig
@ -69,56 +81,61 @@ end
(*-- Type specific Hash builder ---------------------------------------------*)
module Make_minimal_SHA256 (K : Name) = struct
module Make_minimal_Blake2B (K : Name) = struct
type t = string
type t = Sodium.Generichash.hash
include K
let size = 32 (* SHA256 *)
let size =
match K.size with
| None -> 32
| Some x -> x
let of_raw s =
let of_string s =
if String.length s <> size then begin
let msg =
Printf.sprintf "%s.of_raw: wrong string size for %S (%d)"
K.name s (String.length s) in
Printf.sprintf "%s.of_string: wrong string size (%d)"
K.name (String.length s) in
raise (Invalid_argument msg)
end;
s
let to_raw s = s
end ;
Sodium.Generichash.Bytes.to_hash (Bytes.of_string s)
let to_string s = Bytes.to_string (Sodium.Generichash.Bytes.of_hash s)
let of_hex s = of_raw (Hex_encode.hex_decode s)
let to_hex s = Hex_encode.hex_encode s
let of_hex s = of_string (Hex_encode.hex_decode s)
let to_hex s = Hex_encode.hex_encode (to_string s)
let compare = String.compare
let equal : t -> t -> bool = (=)
let compare = Sodium.Generichash.compare
let equal x y = compare x y = 0
let of_bytes b =
let s = MBytes.to_string b in
if String.length s <> size then begin
if MBytes.length b <> size then begin
let msg =
Printf.sprintf "%s.of_bytes: wrong string size for %S (%d)"
K.name s (String.length s) in
Printf.sprintf "%s.of_bytes: wrong string size (%d)"
K.name (MBytes.length b) in
raise (Invalid_argument msg)
end;
s
let to_bytes = MBytes.of_string
end ;
Sodium.Generichash.Bigbytes.to_hash b
let to_bytes = Sodium.Generichash.Bigbytes.of_hash
let read src off = MBytes.substring src off size
let write dst off h = MBytes.blit_from_string h 0 dst off size
let read src off = of_bytes @@ MBytes.sub src off size
let write dst off h = MBytes.blit (to_bytes h) 0 dst off size
let hash_bytes l =
let hash = Cryptokit.Hash.sha256 () in
(* FIXME... bigstring... *)
List.iter (fun b -> hash#add_string (MBytes.to_string b)) l;
let r = hash#result in hash#wipe; r
let open Sodium.Generichash in
let state = init ~size () in
List.iter (Bigbytes.update state) l ;
final state
let hash_string l =
let hash = Cryptokit.Hash.sha256 () in
List.iter (fun b -> hash#add_string b) l;
let r = hash#result in hash#wipe; r
let open Sodium.Generichash in
let state = init ~size () in
List.iter
(fun s -> Bytes.update state (BytesLabels.unsafe_of_string s))
l ;
final state
module Set = Set.Make(struct type t = string let compare = compare end)
module Set = Set.Make(struct type nonrec t = t let compare = compare end)
let fold_read f buf off len init =
let last = off + len * size in
@ -133,12 +150,15 @@ module Make_minimal_SHA256 (K : Name) = struct
in
loop init off
module Map = Map.Make(struct type t = string let compare = compare end)
module Map = Map.Make(struct type nonrec t = t let compare = compare end)
module Table =
(* TODO improve *)
Hashtbl.Make(struct
type t = string
let hash s = Int64.to_int (EndianString.BigEndian.get_int64 s 0)
type nonrec t = t
let hash s =
Int64.to_int
(EndianString.BigEndian.get_int64
(Bytes.unsafe_to_string (Sodium.Generichash.Bytes.of_hash s))
0)
let equal = equal
end)
@ -153,7 +173,7 @@ module Make_minimal_SHA256 (K : Name) = struct
of_hex path
let prefix_path p =
let p = to_hex p in
let p = Hex_encode.hex_encode p in
let len = String.length p in
let p1 = if len >= 2 then String.sub p 0 2 else ""
and p2 = if len >= 4 then String.sub p 2 2 else ""
@ -165,7 +185,7 @@ module Make_minimal_SHA256 (K : Name) = struct
end
module Make_SHA256 (R : sig
module Make_Blake2B (R : sig
val register_encoding:
prefix: string ->
to_raw: ('a -> string) ->
@ -174,7 +194,7 @@ module Make_SHA256 (R : sig
'a Base48.encoding
end) (K : PrefixedName) = struct
include Make_minimal_SHA256(K)
include Make_minimal_Blake2B(K)
(* Serializers *)
@ -183,8 +203,8 @@ module Make_SHA256 (R : sig
let b48check_encoding =
R.register_encoding
~prefix: K.b48check_prefix
~wrap: (fun x -> Hash x)
~of_raw:(fun s -> Some s) ~to_raw
~wrap: (fun s -> Hash s)
~of_raw:(fun h -> Some (of_string h)) ~to_raw:to_string
let of_b48check s =
match Base48.simple_decode b48check_encoding s with
@ -240,7 +260,7 @@ module Hash_table (Hash : HASH)
type t = Hash.t
let equal = Hash.equal
let hash v =
let raw_hash = Hash.to_raw v in
let raw_hash = Hash.to_string v in
let int64_hash = EndianString.BigEndian.get_int64 raw_hash 0 in
Int64.to_int int64_hash
end)
@ -248,10 +268,11 @@ module Hash_table (Hash : HASH)
(*-- Pre-instanciated hashes ------------------------------------------------*)
module Block_hash =
Make_SHA256 (Base48) (struct
Make_Blake2B (Base48) (struct
let name = "Block_hash"
let title = "A Tezos block ID"
let b48check_prefix = Base48.Prefix.block_hash
let size = None
end)
module Block_hash_set = Hash_set (Block_hash)
@ -259,10 +280,11 @@ module Block_hash_map = Hash_map (Block_hash)
module Block_hash_table = Hash_table (Block_hash)
module Operation_hash =
Make_SHA256 (Base48) (struct
Make_Blake2B (Base48) (struct
let name = "Operation_hash"
let title = "A Tezos operation ID"
let b48check_prefix = Base48.Prefix.operation_hash
let size = None
end)
module Operation_hash_set = Hash_set (Operation_hash)
@ -270,12 +292,21 @@ module Operation_hash_map = Hash_map (Operation_hash)
module Operation_hash_table = Hash_table (Operation_hash)
module Protocol_hash =
Make_SHA256 (Base48) (struct
Make_Blake2B (Base48) (struct
let name = "Protocol_hash"
let title = "A Tezos protocol ID"
let b48check_prefix = Base48.Prefix.protocol_hash
let size = None
end)
module Protocol_hash_set = Hash_set (Protocol_hash)
module Protocol_hash_map = Hash_map (Protocol_hash)
module Protocol_hash_table = Hash_table (Protocol_hash)
module Generic_hash =
Make_minimal_Blake2B (struct
let name = "Generic_hash"
let title = ""
let size = None
end)

View File

@ -13,7 +13,7 @@
(** {2 Hash Types} ************************************************************)
(** The signature of an abstract hash type, as produced by functor
{!Make_SHA256}. The {!t} type is abstracted for separating the
{!Make_Blake2B}. The {!t} type is abstracted for separating the
various kinds of hashes in the system at typing time. Each type is
equipped with functions to use it as is of as keys in the database
or in memory sets and maps. *)
@ -30,10 +30,10 @@ module type MINIMAL_HASH = sig
val size: int (* in bytes *)
val compare: t -> t -> int
val equal: t -> t -> bool
val of_raw: string -> t
val to_raw: t -> string
val of_hex: string -> t
val to_hex: t -> string
val of_string: string -> t
val to_string: t -> string
val to_bytes: t -> MBytes.t
val of_bytes: MBytes.t -> t
val read: MBytes.t -> int -> t
@ -63,12 +63,13 @@ end
(** {2 Building Hashes} *******************************************************)
(** The parameters for creating a new Hash type using
{!Make_SHA256}. Both {!name} and {!title} are only informative,
{!Make_Blake2B}. Both {!name} and {!title} are only informative,
used in error messages and serializers. *)
module type Name = sig
val name : string
val title : string
val size : int option
end
module type PrefixedName = sig
@ -77,8 +78,8 @@ module type PrefixedName = sig
end
(** Builds a new Hash type using Sha256. *)
module Make_minimal_SHA256 (Name : Name) : MINIMAL_HASH
module Make_SHA256
module Make_minimal_Blake2B (Name : Name) : MINIMAL_HASH
module Make_Blake2B
(Register : sig
val register_encoding:
prefix: string ->
@ -132,3 +133,4 @@ module Protocol_hash_set : module type of Hash_set (Protocol_hash)
module Protocol_hash_map : module type of Hash_map (Protocol_hash)
module Protocol_hash_table : module type of Hash_table (Protocol_hash)
module Generic_hash : MINIMAL_HASH

View File

@ -28,7 +28,6 @@ PACKAGES := \
cohttp.lwt \
compiler-libs.optcomp \
config-file \
cryptokit \
cstruct \
dynlink \
ezjsonm \

View File

@ -1,6 +1,6 @@
(*
ocamlfind ocamlopt \
-package 'lwt,lwt.unix,lwt.log,ezjsonm,ocplib-endian,config-file,cryptokit,cstruct' \
-package 'lwt,lwt.unix,lwt.log,ezjsonm,ocplib-endian,config-file,cstruct' \
../core/utils.cmx ../core/logs.cmx ../core/mMBytes.cmx ../core/json.cmx \
netbits.cmx p2p.cmx test_p2p.ml -linkpkg \
-o test_p2p && ./test_p2p

View File

@ -18,11 +18,11 @@ let (//) = Filename.concat
let genesis_block =
Block_hash.of_b48check
"eeeeeeeeeeeeeegqJHARhSaNXggmMs8K3tvsgn4rBprkvpFAMVD5d"
"eeeeeeeeeeeeeeefcF2dFpTjGjPAxRM3TqDrKkJf7DdkNHpX3DmaD"
let genesis_protocol =
Protocol_hash.of_b48check
"2gagXCT66nmJ2mKh3a6Aeysy9CHaHsAJyDEGSyFNeFAxGCJehsKpK"
"2gagsSEvTKAHRjxAamgSdBNkv39VtNCqpaDXrrH4K8R4KQAAHrhe3"
let genesis_time =
Time.of_seconds 0L

View File

@ -16,11 +16,11 @@ let (//) = Filename.concat
let genesis_block =
Block_hash.of_b48check
"eeeeeeeeeeeeeegqJHARhSaNXggmMs8K3tvsgn4rBprkvpFAMVD5d"
"eeeeeeeeeeeeeeefcF2dFpTjGjPAxRM3TqDrKkJf7DdkNHpX3DmaD"
let genesis_protocol =
Protocol_hash.of_b48check
"2gagXCT66nmJ2mKh3a6Aeysy9CHaHsAJyDEGSyFNeFAxGCJehsKpK"
"2gagsSEvTKAHRjxAamgSdBNkv39VtNCqpaDXrrH4K8R4KQAAHrhe3"
let genesis_time =
Time.of_seconds 0L

View File

@ -18,11 +18,11 @@ let (//) = Filename.concat
let genesis_block =
Block_hash.of_b48check
"eeeeeeeeeeeeeegqJHARhSaNXggmMs8K3tvsgn4rBprkvpFAMVD5d"
"eeeeeeeeeeeeeeefcF2dFpTjGjPAxRM3TqDrKkJf7DdkNHpX3DmaD"
let genesis_protocol =
Protocol_hash.of_b48check
"2gagXCT66nmJ2mKh3a6Aeysy9CHaHsAJyDEGSyFNeFAxGCJehsKpK"
"2gagsSEvTKAHRjxAamgSdBNkv39VtNCqpaDXrrH4K8R4KQAAHrhe3"
let genesis_time =
Time.of_seconds 0L
@ -89,10 +89,10 @@ let bh2 = Store.Block.hash b2.data
let b3 = lolblock ~operations:[oph1;oph2] "Persil"
let bh3 = Store.Block.hash b3.data
let bh3' =
let raw = Bytes.of_string @@ Block_hash.to_raw bh3 in
let raw = Bytes.of_string @@ Block_hash.to_string bh3 in
Bytes.set raw 31 '\000' ;
Bytes.set raw 30 '\000' ;
Block_hash.of_raw @@ Bytes.to_string raw
Block_hash.of_string @@ Bytes.to_string raw
let check_block s h b =
Block.full_get s h >>= function