Vendors/tweetnacl: use bigstring

This commit is contained in:
Vincent Bernardoff 2018-04-17 11:44:01 +02:00 committed by Grégoire Henry
parent 230d495dc6
commit 7c546425d2
10 changed files with 350 additions and 393 deletions

View File

@ -20,26 +20,14 @@ type target = Z.t
module Secretbox = struct module Secretbox = struct
include Secretbox include Secretbox
let of_bytes bytes = let box key msg nonce = box ~key ~msg ~nonce
of_cstruct (Cstruct.of_bigarray bytes)
let of_bytes_exn bytes = let box_open key cmsg nonce = box_open ~key ~cmsg ~nonce
of_cstruct_exn (Cstruct.of_bigarray bytes)
let box key msg nonce =
let msg = Cstruct.of_bigarray msg in
Cstruct.to_bigarray (box ~key ~msg ~nonce)
let box_open key cmsg nonce =
let cmsg = Cstruct.of_bigarray cmsg in
Option.map ~f:Cstruct.to_bigarray (box_open ~key ~cmsg ~nonce)
let box_noalloc key nonce msg = let box_noalloc key nonce msg =
let msg = Cstruct.of_bigarray msg in
box_noalloc ~key ~nonce ~msg box_noalloc ~key ~nonce ~msg
let box_open_noalloc key nonce cmsg = let box_open_noalloc key nonce cmsg =
let cmsg = Cstruct.of_bigarray cmsg in
box_open_noalloc ~key ~nonce ~cmsg box_open_noalloc ~key ~nonce ~cmsg
end end
@ -54,7 +42,7 @@ let () =
Base58.check_encoded_prefix Public_key_hash.b58check_encoding "id" 30 Base58.check_encoded_prefix Public_key_hash.b58check_encoding "id" 30
let hash pk = let hash pk =
Public_key_hash.hash_bytes [Cstruct.to_bigarray (Box.to_cstruct pk)] Public_key_hash.hash_bytes [Box.to_bytes pk]
let zerobytes = Box.zerobytes let zerobytes = Box.zerobytes
let boxzerobytes = Box.boxzerobytes let boxzerobytes = Box.boxzerobytes
@ -63,42 +51,32 @@ let random_keypair () =
let pk, sk = Box.keypair () in let pk, sk = Box.keypair () in
sk, pk, hash pk sk, pk, hash pk
let zero_nonce = Tweetnacl.Nonce.(of_cstruct_exn (Cstruct.create bytes)) let zero_nonce = Tweetnacl.Nonce.(of_bytes_exn (MBytes.init bytes '\x00'))
let random_nonce = Nonce.gen let random_nonce = Nonce.gen
let increment_nonce = Nonce.increment let increment_nonce = Nonce.increment
let box sk pk msg nonce = let box sk pk msg nonce = Box.box ~sk ~pk ~msg ~nonce
let msg = Cstruct.of_bigarray msg in
Cstruct.to_bigarray (Box.box ~sk ~pk ~msg ~nonce)
let box_open sk pk cmsg nonce = let box_open sk pk cmsg nonce = Box.box_open ~sk ~pk ~cmsg ~nonce
let cmsg = Cstruct.of_bigarray cmsg in
Option.map ~f:Cstruct.to_bigarray (Box.box_open ~sk ~pk ~cmsg ~nonce)
let box_noalloc sk pk nonce msg = let box_noalloc sk pk nonce msg =
let msg = Cstruct.of_bigarray msg in
Box.box_noalloc ~sk ~pk ~nonce ~msg Box.box_noalloc ~sk ~pk ~nonce ~msg
let box_open_noalloc sk pk nonce cmsg = let box_open_noalloc sk pk nonce cmsg =
let cmsg = Cstruct.of_bigarray cmsg in
Box.box_open_noalloc ~sk ~pk ~nonce ~cmsg Box.box_open_noalloc ~sk ~pk ~nonce ~cmsg
let precompute sk pk = Box.combine pk sk let precompute sk pk = Box.combine pk sk
let fast_box k msg nonce = let fast_box k msg nonce =
let msg = Cstruct.of_bigarray msg in Box.box_combined ~k ~msg ~nonce
Cstruct.to_bigarray (Box.box_combined ~k ~msg ~nonce)
let fast_box_open k cmsg nonce = let fast_box_open k cmsg nonce =
let cmsg = Cstruct.of_bigarray cmsg in Box.box_open_combined ~k ~cmsg ~nonce
Option.map ~f:Cstruct.to_bigarray (Box.box_open_combined ~k ~cmsg ~nonce)
let fast_box_noalloc k nonce msg = let fast_box_noalloc k nonce msg =
let msg = Cstruct.of_bigarray msg in
Box.box_combined_noalloc ~k ~nonce ~msg Box.box_combined_noalloc ~k ~nonce ~msg
let fast_box_open_noalloc k nonce cmsg = let fast_box_open_noalloc k nonce cmsg =
let cmsg = Cstruct.of_bigarray cmsg in
Box.box_open_combined_noalloc ~k ~nonce ~cmsg Box.box_open_combined_noalloc ~k ~nonce ~cmsg
let compare_target hash target = let compare_target hash target =
@ -128,8 +106,8 @@ let default_target = make_target 24.
let check_proof_of_work pk nonce target = let check_proof_of_work pk nonce target =
let hash = let hash =
Blake2B.hash_bytes [ Blake2B.hash_bytes [
Cstruct.to_bigarray (Box.to_cstruct pk) ; Box.to_bytes pk ;
Cstruct.to_bigarray (Nonce.to_cstruct nonce) ; Nonce.to_bytes nonce ;
] in ] in
compare_target hash target compare_target hash target
@ -146,16 +124,16 @@ let generate_proof_of_work ?max pk target =
loop (Nonce.increment nonce) (cpt + 1) in loop (Nonce.increment nonce) (cpt + 1) in
loop (random_nonce ()) 0 loop (random_nonce ()) 0
let public_key_to_bigarray x = Cstruct.to_bigarray (Box.to_cstruct x) let public_key_to_bigarray = Box.to_bytes
let public_key_of_bigarray x = Box.pk_of_cstruct_exn (Cstruct.of_bigarray x) let public_key_of_bigarray = Box.pk_of_bytes_exn
let public_key_size = Box.pkbytes let public_key_size = Box.pkbytes
let secret_key_to_bigarray x = Cstruct.to_bigarray (Box.to_cstruct x) let secret_key_to_bigarray = Box.to_bytes
let secret_key_of_bigarray x = Box.sk_of_cstruct_exn (Cstruct.of_bigarray x) let secret_key_of_bigarray = Box.sk_of_bytes_exn
let secret_key_size = Box.skbytes let secret_key_size = Box.skbytes
let nonce_to_bigarray x = Cstruct.to_bigarray (Nonce.to_cstruct x) let nonce_to_bigarray = Nonce.to_bytes
let nonce_of_bigarray x = Nonce.of_cstruct_exn (Cstruct.of_bigarray x) let nonce_of_bigarray = Nonce.of_bytes_exn
let nonce_size = Nonce.bytes let nonce_size = Nonce.bytes
let public_key_encoding = let public_key_encoding =

View File

@ -28,11 +28,11 @@ module Public_key = struct
let name = "Ed25519.Public_key" let name = "Ed25519.Public_key"
let title = "Ed25519 public key" let title = "Ed25519 public key"
let to_string s = Cstruct.to_string (Sign.to_cstruct s) let to_string s = MBytes.to_string (Sign.to_bytes s)
let of_string_opt s = Sign.pk_of_cstruct (Cstruct.of_string s) let of_string_opt s = Sign.pk_of_bytes (MBytes.of_string s)
let to_bytes pk = Cstruct.to_bigarray (Sign.to_cstruct pk) let to_bytes = Sign.to_bytes
let of_bytes_opt s = Sign.pk_of_cstruct (Cstruct.of_bigarray s) let of_bytes_opt = Sign.pk_of_bytes
let size = Sign.pkbytes let size = Sign.pkbytes
@ -51,13 +51,12 @@ module Public_key = struct
Base58.check_encoded_prefix b58check_encoding "edpk" 54 Base58.check_encoded_prefix b58check_encoding "edpk" 54
let hash v = let hash v =
Public_key_hash.hash_bytes Public_key_hash.hash_bytes [ Sign.to_bytes v ]
[ Cstruct.to_bigarray (Sign.to_cstruct v) ]
include Compare.Make(struct include Compare.Make(struct
type nonrec t = t type nonrec t = t
let compare a b = let compare a b =
Cstruct.compare (Sign.to_cstruct a) (Sign.to_cstruct b) MBytes.compare (Sign.to_bytes a) (Sign.to_bytes b)
end) end)
include Helpers.MakeRaw(struct include Helpers.MakeRaw(struct
@ -102,12 +101,11 @@ module Secret_key = struct
let size = Sign.seedbytes let size = Sign.seedbytes
let to_bytes x = Cstruct.to_bigarray (Sign.seed x) let to_bytes = Sign.seed
let of_bytes_opt s = let of_bytes_opt s =
let s = Cstruct.of_bigarray s in match MBytes.length s with
match Cstruct.len s with
| 32 -> let _pk, sk = Sign.keypair ~seed:s () in Some sk | 32 -> let _pk, sk = Sign.keypair ~seed:s () in Some sk
| 64 -> Sign.sk_of_cstruct s | 64 -> Sign.sk_of_bytes s
| _ -> None | _ -> None
let to_string s = MBytes.to_string (to_bytes s) let to_string s = MBytes.to_string (to_bytes s)
@ -122,9 +120,9 @@ module Secret_key = struct
Base58.register_encoding Base58.register_encoding
~prefix: Base58.Prefix.ed25519_seed ~prefix: Base58.Prefix.ed25519_seed
~length: size ~length: size
~to_raw: (fun sk -> Cstruct.to_string (Sign.seed sk)) ~to_raw: (fun sk -> MBytes.to_string (Sign.seed sk))
~of_raw: (fun buf -> ~of_raw: (fun buf ->
let seed = Cstruct.of_string buf in let seed = MBytes.of_string buf in
match Sign.keypair ~seed () with match Sign.keypair ~seed () with
| exception _ -> None | exception _ -> None
| _pk, sk -> Some sk) | _pk, sk -> Some sk)
@ -134,8 +132,8 @@ module Secret_key = struct
Base58.register_encoding Base58.register_encoding
~prefix: Base58.Prefix.ed25519_secret_key ~prefix: Base58.Prefix.ed25519_secret_key
~length: Sign.skbytes ~length: Sign.skbytes
~to_raw: (fun sk -> Cstruct.to_string (Sign.to_cstruct sk)) ~to_raw: (fun sk -> MBytes.to_string (Sign.to_bytes sk))
~of_raw: (fun buf -> Sign.sk_of_cstruct (Cstruct.of_string buf)) ~of_raw: (fun buf -> Sign.sk_of_bytes (MBytes.of_string buf))
~wrap: (fun x -> Data x) ~wrap: (fun x -> Data x)
let of_b58check_opt s = let of_b58check_opt s =
@ -167,7 +165,7 @@ module Secret_key = struct
include Compare.Make(struct include Compare.Make(struct
type nonrec t = t type nonrec t = t
let compare a b = let compare a b =
Cstruct.compare (Sign.to_cstruct a) (Sign.to_cstruct b) MBytes.compare (Sign.to_bytes a) (Sign.to_bytes b)
end) end)
include Helpers.MakeRaw(struct include Helpers.MakeRaw(struct
@ -262,13 +260,10 @@ let pp ppf t = Format.fprintf ppf "%s" (to_b58check t)
let zero = MBytes.init size '\000' let zero = MBytes.init size '\000'
let sign key msg = let sign key msg = Sign.detached ~key msg
Cstruct.(to_bigarray (Sign.detached ~key (of_bigarray msg)))
let check public_key signature msg = let check public_key signature msg =
Sign.verify_detached ~key:public_key Sign.verify_detached ~key:public_key ~signature msg
~signature:(Cstruct.of_bigarray signature)
(Cstruct.of_bigarray msg)
let append key msg = let append key msg =
MBytes.concat msg (sign key msg) MBytes.concat msg (sign key msg)
@ -278,7 +273,7 @@ let concat msg signature =
module Seed = struct module Seed = struct
type t = Cstruct.t type t = Bigstring.t
let generate () = Rand.gen 32 let generate () = Rand.gen 32
let extract = Sign.seed let extract = Sign.seed

View File

@ -7,8 +7,7 @@
(* *) (* *)
(**************************************************************************) (**************************************************************************)
let generate len = let generate = Tweetnacl.Rand.gen
Cstruct.to_bigarray (Tweetnacl.Rand.gen len)
let generate_into ?(pos=0) ?len buf = let generate_into ?(pos=0) ?len buf =
let buflen = MBytes.length buf in let buflen = MBytes.length buf in
@ -18,6 +17,5 @@ let generate_into ?(pos=0) ?len buf =
if pos < 0 || len < 0 || pos + len > buflen then if pos < 0 || len < 0 || pos + len > buflen then
invalid_arg (Printf.sprintf "Rand.generate_into: \ invalid_arg (Printf.sprintf "Rand.generate_into: \
invalid slice (pos=%d len=%d)" pos len) ; invalid slice (pos=%d len=%d)" pos len) ;
let cs = Cstruct.of_bigarray buf in let buf = MBytes.sub buf pos len in
let cs = Cstruct.sub cs pos len in Tweetnacl.Rand.write buf
Tweetnacl.Rand.write cs

View File

@ -264,7 +264,7 @@ let append key msg =
concat msg signature concat msg signature
let generate_key () = let generate_key () =
let sk = Key.read_sk_exn context (Cstruct.to_bigarray (Tweetnacl.Rand.gen 32)) in let sk = Key.read_sk_exn context (Tweetnacl.Rand.gen 32) in
let pk = Key.neuterize_exn context sk in let pk = Key.neuterize_exn context sk in
let pkh = Public_key.hash pk in let pkh = Public_key.hash pk in
(pkh, pk, sk) (pkh, pk, sk)

View File

@ -3,5 +3,6 @@
(library (library
((name tweetnacl) ((name tweetnacl)
(public_name tweetnacl) (public_name tweetnacl)
(libraries (hex cstruct zarith)) (libraries (bigstring ocplib-endian.bigstring zarith))
(c_names (tweetnacl_stubs)))) (c_names (tweetnacl_stubs))
(c_flags (-O3))))

View File

@ -3,74 +3,76 @@
Distributed under the ISC license, see terms at the end of the file. Distributed under the ISC license, see terms at the end of the file.
---------------------------------------------------------------------------*) ---------------------------------------------------------------------------*)
open EndianBigstring
module Rand = struct module Rand = struct
external randombytes : Cstruct.buffer -> int -> unit = external randombytes : Bigstring.t -> int -> unit =
"ml_randombytes" [@@noalloc] "ml_randombytes" [@@noalloc]
let gen sz = let gen sz =
let cs = Cstruct.create_unsafe sz in let buf = Bigstring.create sz in
randombytes (Cstruct.to_bigarray cs) sz ; randombytes buf sz ;
cs buf
let write cs = let write buf =
Cstruct.(randombytes (to_bigarray cs) (len cs)) randombytes buf (Bigstring.length buf)
end end
module Hash = struct module Hash = struct
let bytes = 64 let bytes = 64
external sha512 : external sha512 :
Cstruct.buffer -> Cstruct.buffer -> int -> unit = Bigstring.t -> Bigstring.t -> int -> unit =
"ml_crypto_hash" [@@noalloc] "ml_crypto_hash" [@@noalloc]
let sha512 msg = let sha512 msg =
let q = Cstruct.create_unsafe bytes in let q = Bigstring.create bytes in
sha512 q.buffer msg.Cstruct.buffer (Cstruct.len msg) ; sha512 q msg (Bigstring.length msg) ;
q q
end end
let cs_of_z cs z = let buf_of_z buf z =
Cstruct.memset cs 0 ; Bigstring.fill buf '\x00' ;
let bits = Z.to_bits z in let bits = Z.to_bits z in
Cstruct.blit_from_string bits 0 cs 0 (String.length bits) Bigstring.blit_of_string bits 0 buf 0 (String.length bits)
let unopt_invalid_arg1 ~msg f cs = let unopt_invalid_arg1 ~msg f buf =
match f cs with match f buf with
| Some v -> v | Some v -> v
| None -> invalid_arg msg | None -> invalid_arg msg
module Nonce = struct module Nonce = struct
type t = Cstruct.t type t = Bigstring.t
let bytes = 24 let bytes = 24
let gen () = let gen () =
Rand.gen bytes Rand.gen bytes
let rec incr_byte b step byteno = let rec incr_byte b step byteno =
let res = Cstruct.BE.get_uint16 b byteno + step in let res = BigEndian.get_uint16 b byteno + step in
let lo = res land 0xffff in let lo = res land 0xffff in
let hi = res asr 16 in let hi = res asr 16 in
Cstruct.BE.set_uint16 b byteno lo ; BigEndian.set_int16 b byteno lo ;
if hi = 0 || byteno = 0 then () if hi = 0 || byteno = 0 then ()
else incr_byte b hi (byteno - 2) else incr_byte b hi (byteno - 2)
let increment ?(step = 1) nonce = let increment ?(step = 1) nonce =
let new_nonce = Cstruct.create_unsafe 24 in let new_nonce = Bigstring.create 24 in
Cstruct.blit nonce 0 new_nonce 0 24 ; Bigstring.blit nonce 0 new_nonce 0 24 ;
incr_byte new_nonce step 22 ; incr_byte new_nonce step 22 ;
new_nonce new_nonce
let of_cstruct cs = let of_bytes buf =
try Some (Cstruct.sub cs 0 bytes) with _ -> None try Some (Bigstring.sub buf 0 bytes) with _ -> None
let of_cstruct_exn = let of_bytes_exn =
unopt_invalid_arg1 ~msg:"Box.Nonce.of_cstruct_exn" of_cstruct unopt_invalid_arg1 ~msg:"Box.Nonce.of_bytes_exn" of_bytes
let to_cstruct nonce = nonce let to_bytes nonce = nonce
end end
module Secretbox = struct module Secretbox = struct
type key = Cstruct.t type key = Bigstring.t
let keybytes = 32 let keybytes = 32
let zerobytes = 32 let zerobytes = 32
@ -79,46 +81,44 @@ module Secretbox = struct
let genkey () = let genkey () =
Rand.gen 32 Rand.gen 32
let of_cstruct cs = let of_bytes buf =
if Cstruct.len cs < keybytes then None if Bigstring.length buf < keybytes then None
else Some (Cstruct.sub cs 0 keybytes) else Some (Bigstring.sub buf 0 keybytes)
let of_cstruct_exn = let of_bytes_exn =
unopt_invalid_arg1 ~msg:"Secret_box.of_cstruct_exn" of_cstruct unopt_invalid_arg1 ~msg:"Secret_box.of_bytes_exn" of_bytes
external secretbox : external secretbox :
Cstruct.buffer -> Cstruct.buffer -> Bigstring.t -> Bigstring.t ->
Cstruct.buffer -> Cstruct.buffer -> unit = "ml_secretbox" [@@noalloc] Bigstring.t -> Bigstring.t -> unit = "ml_secretbox" [@@noalloc]
external secretbox_open : external secretbox_open :
Cstruct.buffer -> Cstruct.buffer -> Bigstring.t -> Bigstring.t ->
Cstruct.buffer -> Cstruct.buffer -> int = "ml_secretbox_open" [@@noalloc] Bigstring.t -> Bigstring.t -> int = "ml_secretbox_open" [@@noalloc]
let box ~key ~nonce ~msg = let box ~key ~nonce ~msg =
let msglen = Cstruct.len msg in let msglen = Bigstring.length msg in
let buflen = msglen + zerobytes in let buflen = msglen + zerobytes in
let buf = Cstruct.create buflen in let buf = Bigstring.create buflen in
Cstruct.blit msg 0 buf zerobytes msglen ; Bigstring.fill buf '\x00' ;
secretbox Bigstring.blit msg 0 buf zerobytes msglen ;
buf.buffer buf.buffer nonce.Cstruct.buffer key.Cstruct.buffer ; secretbox buf buf nonce key ;
Cstruct.sub buf boxzerobytes (buflen - boxzerobytes) Bigstring.sub buf boxzerobytes (buflen - boxzerobytes)
let box_noalloc ~key ~nonce ~msg = let box_noalloc ~key ~nonce ~msg =
secretbox secretbox msg msg nonce key
msg.Cstruct.buffer msg.buffer nonce.Cstruct.buffer key.Cstruct.buffer
let box_open ~key ~nonce ~cmsg = let box_open ~key ~nonce ~cmsg =
let msglen = Cstruct.len cmsg - boxzerobytes in let msglen = Bigstring.length cmsg - boxzerobytes in
let buf = Cstruct.create (zerobytes + msglen) in let buf = Bigstring.create (zerobytes + msglen) in
Cstruct.blit cmsg 0 buf boxzerobytes (msglen + boxzerobytes) ; Bigstring.fill buf '\x00' ;
match secretbox_open buf.buffer buf.buffer Bigstring.blit cmsg 0 buf boxzerobytes (msglen + boxzerobytes) ;
nonce.Cstruct.buffer key.Cstruct.buffer with match secretbox_open buf buf nonce key with
| 0 -> Some (Cstruct.sub buf zerobytes msglen) | 0 -> Some (Bigstring.sub buf zerobytes msglen)
| _ -> None | _ -> None
let box_open_noalloc ~key ~nonce ~cmsg = let box_open_noalloc ~key ~nonce ~cmsg =
match secretbox_open cmsg.Cstruct.buffer cmsg.buffer match secretbox_open cmsg cmsg nonce key with
nonce.Cstruct.buffer key.Cstruct.buffer with
| 0 -> true | 0 -> true
| _ -> false | _ -> false
end end
@ -128,9 +128,9 @@ module Box = struct
type public type public
type combined type combined
type _ key = type _ key =
| Sk : Cstruct.t -> secret key | Sk : Bigstring.t -> secret key
| Pk : Cstruct.t -> public key | Pk : Bigstring.t -> public key
| Ck : Cstruct.t -> combined key | Ck : Bigstring.t -> combined key
let skbytes = 32 let skbytes = 32
let pkbytes = 32 let pkbytes = 32
@ -138,136 +138,127 @@ module Box = struct
let zerobytes = 32 let zerobytes = 32
let boxzerobytes = 16 let boxzerobytes = 16
let to_cstruct : type a. a key -> Cstruct.t = function let to_bytes : type a. a key -> Bigstring.t = function
| Pk cs -> cs | Pk buf -> buf
| Sk cs -> cs | Sk buf -> buf
| Ck cs -> cs | Ck buf -> buf
let blit_to_cstruct : let blit_to_bytes :
type a. a key -> ?pos:int -> Cstruct.t -> unit = fun key ?(pos=0) cs -> type a. a key -> ?pos:int -> Bigstring.t -> unit = fun key ?(pos=0) buf ->
match key with match key with
| Pk pk -> Cstruct.blit pk 0 cs pos pkbytes | Pk pk -> Bigstring.blit pk 0 buf pos pkbytes
| Sk sk -> Cstruct.blit sk 0 cs pos skbytes | Sk sk -> Bigstring.blit sk 0 buf pos skbytes
| Ck ck -> Cstruct.blit ck 0 cs pos beforenmbytes | Ck ck -> Bigstring.blit ck 0 buf pos beforenmbytes
let pp : type a. Format.formatter -> a key -> unit = fun ppf -> function
| Pk cs -> Format.fprintf ppf "P %a" Hex.pp (Hex.of_cstruct cs)
| Sk cs -> Format.fprintf ppf "S %a" Hex.pp (Hex.of_cstruct cs)
| Ck cs -> Format.fprintf ppf "C %a" Hex.pp (Hex.of_cstruct cs)
let show t = Format.asprintf "%a" pp t
let equal : let equal :
type a. a key -> a key -> bool = fun a b -> match a, b with type a. a key -> a key -> bool = fun a b -> match a, b with
| Pk a, Pk b -> Cstruct.equal a b | Pk a, Pk b -> Bigstring.equal a b
| Sk a, Sk b -> Cstruct.equal a b | Sk a, Sk b -> Bigstring.equal a b
| Ck a, Ck b -> Cstruct.equal a b | Ck a, Ck b -> Bigstring.equal a b
let sk_of_cstruct cs = let sk_of_bytes buf =
try Some (Sk (Cstruct.sub cs 0 skbytes)) with _ -> None try Some (Sk (Bigstring.sub buf 0 skbytes)) with _ -> None
let pk_of_cstruct cs = let pk_of_bytes buf =
try Some (Pk (Cstruct.sub cs 0 pkbytes)) with _ -> None try Some (Pk (Bigstring.sub buf 0 pkbytes)) with _ -> None
let ck_of_cstruct cs = let ck_of_bytes buf =
try Some (Ck (Cstruct.sub cs 0 beforenmbytes)) with _ -> None try Some (Ck (Bigstring.sub buf 0 beforenmbytes)) with _ -> None
let sk_of_cstruct_exn = let sk_of_bytes_exn =
unopt_invalid_arg1 ~msg:"Box.sk_of_cstruct_exn" sk_of_cstruct unopt_invalid_arg1 ~msg:"Box.sk_of_bytes_exn" sk_of_bytes
let pk_of_cstruct_exn = let pk_of_bytes_exn =
unopt_invalid_arg1 ~msg:"Box.pk_of_cstruct_exn" pk_of_cstruct unopt_invalid_arg1 ~msg:"Box.pk_of_bytes_exn" pk_of_bytes
let ck_of_cstruct_exn = let ck_of_bytes_exn =
unopt_invalid_arg1 ~msg:"Box.ck_of_cstruct_exn" ck_of_cstruct unopt_invalid_arg1 ~msg:"Box.ck_of_bytes_exn" ck_of_bytes
external keypair : external keypair :
Cstruct.buffer -> Cstruct.buffer -> unit = Bigstring.t -> Bigstring.t -> unit =
"ml_crypto_box_keypair" [@@noalloc] "ml_crypto_box_keypair" [@@noalloc]
let keypair () = let keypair () =
let sk = Cstruct.create skbytes in let sk = Bigstring.create skbytes in
let pk = Cstruct.create pkbytes in let pk = Bigstring.create pkbytes in
keypair pk.buffer sk.buffer ; keypair pk sk ;
Pk pk, Sk sk Pk pk, Sk sk
external box_stub : external box_stub :
Cstruct.buffer -> Cstruct.buffer -> Cstruct.buffer -> Bigstring.t -> Bigstring.t -> Bigstring.t ->
Cstruct.buffer -> Cstruct.buffer -> unit = Bigstring.t -> Bigstring.t -> unit =
"ml_crypto_box" [@@noalloc] "ml_crypto_box" [@@noalloc]
let box ~pk:(Pk pk) ~sk:(Sk sk) ~nonce ~msg = let box ~pk:(Pk pk) ~sk:(Sk sk) ~nonce ~msg =
let msglen = Cstruct.len msg in let msglen = Bigstring.length msg in
let buflen = msglen + zerobytes in let buflen = msglen + zerobytes in
let buf = Cstruct.create buflen in let buf = Bigstring.create buflen in
Cstruct.blit msg 0 buf zerobytes msglen ; Bigstring.fill buf '\x00' ;
box_stub Bigstring.blit msg 0 buf zerobytes msglen ;
buf.buffer buf.buffer nonce.Cstruct.buffer pk.buffer sk.buffer ; box_stub buf buf nonce pk sk ;
Cstruct.sub buf boxzerobytes (buflen - boxzerobytes) Bigstring.sub buf boxzerobytes (buflen - boxzerobytes)
let box_noalloc ~pk:(Pk pk) ~sk:(Sk sk) ~nonce ~msg = let box_noalloc ~pk:(Pk pk) ~sk:(Sk sk) ~nonce ~msg =
box_stub box_stub msg msg nonce pk sk
msg.Cstruct.buffer msg.buffer nonce.Cstruct.buffer pk.buffer sk.buffer
external box_open_stub : external box_open_stub :
Cstruct.buffer -> Cstruct.buffer -> Cstruct.buffer -> Bigstring.t -> Bigstring.t -> Bigstring.t ->
Cstruct.buffer -> Cstruct.buffer -> int = Bigstring.t -> Bigstring.t -> int =
"ml_crypto_box_open" [@@noalloc] "ml_crypto_box_open" [@@noalloc]
let box_open ~pk:(Pk pk) ~sk:(Sk sk) ~nonce ~cmsg = let box_open ~pk:(Pk pk) ~sk:(Sk sk) ~nonce ~cmsg =
let msglen = Cstruct.len cmsg - boxzerobytes in let msglen = Bigstring.length cmsg - boxzerobytes in
let buf = Cstruct.create (zerobytes + msglen) in let buf = Bigstring.create (zerobytes + msglen) in
Cstruct.blit cmsg 0 buf boxzerobytes (msglen + boxzerobytes) ; Bigstring.fill buf '\x00' ;
match box_open_stub buf.buffer buf.buffer Bigstring.blit cmsg 0 buf boxzerobytes (msglen + boxzerobytes) ;
nonce.Cstruct.buffer pk.buffer sk.buffer with match box_open_stub buf buf nonce pk sk with
| 0 -> Some (Cstruct.sub buf zerobytes msglen) | 0 -> Some (Bigstring.sub buf zerobytes msglen)
| _ -> None | _ -> None
let box_open_noalloc ~pk:(Pk pk) ~sk:(Sk sk) ~nonce ~cmsg = let box_open_noalloc ~pk:(Pk pk) ~sk:(Sk sk) ~nonce ~cmsg =
match box_open_stub cmsg.Cstruct.buffer cmsg.buffer match box_open_stub cmsg cmsg nonce pk sk with
nonce.Cstruct.buffer pk.buffer sk.buffer with
| 0 -> true | 0 -> true
| _ -> false | _ -> false
external box_beforenm : external box_beforenm :
Cstruct.buffer -> Cstruct.buffer -> Cstruct.buffer -> unit = Bigstring.t -> Bigstring.t -> Bigstring.t -> unit =
"ml_crypto_box_beforenm" [@@noalloc] "ml_crypto_box_beforenm" [@@noalloc]
let combine (Pk pk) (Sk sk) = let combine (Pk pk) (Sk sk) =
let combined = Cstruct.create_unsafe beforenmbytes in let combined = Bigstring.create beforenmbytes in
box_beforenm combined.buffer pk.buffer sk.buffer ; box_beforenm combined pk sk ;
Ck combined Ck combined
external box_afternm : external box_afternm :
Cstruct.buffer -> Cstruct.buffer -> Bigstring.t -> Bigstring.t ->
Cstruct.buffer -> Cstruct.buffer -> unit = Bigstring.t -> Bigstring.t -> unit =
"ml_crypto_box_afternm" [@@noalloc] "ml_crypto_box_afternm" [@@noalloc]
let box_combined ~k:(Ck k) ~nonce ~msg = let box_combined ~k:(Ck k) ~nonce ~msg =
let msglen = Cstruct.len msg in let msglen = Bigstring.length msg in
let buflen = msglen + zerobytes in let buflen = msglen + zerobytes in
let buf = Cstruct.create buflen in let buf = Bigstring.create buflen in
Cstruct.blit msg 0 buf zerobytes msglen ; Bigstring.fill buf '\x00' ;
box_afternm buf.buffer buf.buffer nonce.Cstruct.buffer k.buffer ; Bigstring.blit msg 0 buf zerobytes msglen ;
Cstruct.sub buf boxzerobytes (buflen - boxzerobytes) box_afternm buf buf nonce k ;
Bigstring.sub buf boxzerobytes (buflen - boxzerobytes)
let box_combined_noalloc ~k:(Ck k) ~nonce ~msg = let box_combined_noalloc ~k:(Ck k) ~nonce ~msg =
box_afternm msg.Cstruct.buffer msg.buffer nonce.Cstruct.buffer k.buffer box_afternm msg msg nonce k
external box_open_afternm : external box_open_afternm :
Cstruct.buffer -> Cstruct.buffer -> Bigstring.t -> Bigstring.t ->
Cstruct.buffer -> Cstruct.buffer -> int = Bigstring.t -> Bigstring.t -> int =
"ml_crypto_box_open_afternm" [@@noalloc] "ml_crypto_box_open_afternm" [@@noalloc]
let box_open_combined ~k:(Ck k) ~nonce ~cmsg = let box_open_combined ~k:(Ck k) ~nonce ~cmsg =
let msglen = Cstruct.len cmsg - boxzerobytes in let msglen = Bigstring.length cmsg - boxzerobytes in
let buflen = msglen + zerobytes in let buflen = msglen + zerobytes in
let buf = Cstruct.create buflen in let buf = Bigstring.create buflen in
Cstruct.blit cmsg 0 buf boxzerobytes (msglen + boxzerobytes) ; Bigstring.fill buf '\x00' ;
match box_open_afternm buf.buffer buf.buffer Bigstring.blit cmsg 0 buf boxzerobytes (msglen + boxzerobytes) ;
nonce.Cstruct.buffer k.buffer with match box_open_afternm buf buf nonce k with
| 0 -> Some (Cstruct.sub buf zerobytes msglen) | 0 -> Some (Bigstring.sub buf zerobytes msglen)
| _ -> None | _ -> None
let box_open_combined_noalloc ~k:(Ck k) ~nonce ~cmsg = let box_open_combined_noalloc ~k:(Ck k) ~nonce ~cmsg =
match box_open_afternm cmsg.Cstruct.buffer cmsg.buffer match box_open_afternm cmsg cmsg nonce k with
nonce.Cstruct.buffer k.buffer with
| 0 -> true | 0 -> true
| _ -> false | _ -> false
end end
@ -277,9 +268,9 @@ module Sign = struct
type extended type extended
type public type public
type _ key = type _ key =
| Sk : Cstruct.t -> secret key | Sk : Bigstring.t -> secret key
| Ek : Cstruct.t -> extended key | Ek : Bigstring.t -> extended key
| Pk : Cstruct.t -> public key | Pk : Bigstring.t -> public key
let bytes = 64 let bytes = 64
let pkbytes = 32 let pkbytes = 32
@ -287,169 +278,156 @@ module Sign = struct
let ekbytes = 64 let ekbytes = 64
let seedbytes = 32 let seedbytes = 32
let sk_of_cstruct cs = let sk_of_bytes buf =
try Some (Sk (Cstruct.sub cs 0 skbytes)) with _ -> None try Some (Sk (Bigstring.sub buf 0 skbytes)) with _ -> None
let ek_of_cstruct cs = let ek_of_bytes buf =
try Some (Ek (Cstruct.sub cs 0 ekbytes)) with _ -> None try Some (Ek (Bigstring.sub buf 0 ekbytes)) with _ -> None
let pk_of_cstruct cs = let pk_of_bytes buf =
try Some (Pk (Cstruct.sub cs 0 pkbytes)) with _ -> None try Some (Pk (Bigstring.sub buf 0 pkbytes)) with _ -> None
let sk_of_cstruct_exn = let sk_of_bytes_exn =
unopt_invalid_arg1 ~msg:"Sign.sk_of_cstruct_exn" sk_of_cstruct unopt_invalid_arg1 ~msg:"Sign.sk_of_bytes_exn" sk_of_bytes
let ek_of_cstruct_exn = let ek_of_bytes_exn =
unopt_invalid_arg1 ~msg:"Sign.ek_of_cstruct_exn" ek_of_cstruct unopt_invalid_arg1 ~msg:"Sign.ek_of_bytes_exn" ek_of_bytes
let pk_of_cstruct_exn = let pk_of_bytes_exn =
unopt_invalid_arg1 ~msg:"Sign.pk_of_cstruct_exn" pk_of_cstruct unopt_invalid_arg1 ~msg:"Sign.pk_of_bytes_exn" pk_of_bytes
let to_cstruct : type a. a key -> Cstruct.t = function let to_bytes : type a. a key -> Bigstring.t = function
| Pk cs -> cs | Pk buf -> buf
| Sk cs -> cs | Sk buf -> buf
| Ek cs -> cs | Ek buf -> buf
let seed (Sk cs) = Cstruct.sub cs 0 seedbytes let seed (Sk buf) = Bigstring.sub buf 0 seedbytes
let blit_to_cstruct : let blit_to_bytes :
type a. a key -> ?pos:int -> Cstruct.t -> unit = fun key ?(pos=0) cs -> type a. a key -> ?pos:int -> Bigstring.t -> unit = fun key ?(pos=0) buf ->
match key with match key with
| Pk pk -> Cstruct.blit pk 0 cs pos pkbytes | Pk pk -> Bigstring.blit pk 0 buf pos pkbytes
| Sk sk -> Cstruct.blit sk 0 cs pos skbytes | Sk sk -> Bigstring.blit sk 0 buf pos skbytes
| Ek ek -> Cstruct.blit ek 0 cs pos ekbytes | Ek ek -> Bigstring.blit ek 0 buf pos ekbytes
let pp : type a. Format.formatter -> a key -> unit = fun ppf -> function
| Pk cs -> Format.fprintf ppf "P %a" Hex.pp (Hex.of_cstruct cs)
| Sk cs -> Format.fprintf ppf "S %a" Hex.pp (Hex.of_cstruct cs)
| Ek cs -> Format.fprintf ppf "E %a" Hex.pp (Hex.of_cstruct cs)
let show t = Format.asprintf "%a" pp t
let equal : let equal :
type a. a key -> a key -> bool = fun a b -> match a, b with type a. a key -> a key -> bool = fun a b -> match a, b with
| Pk a, Pk b -> Cstruct.equal a b | Pk a, Pk b -> Bigstring.equal a b
| Sk a, Sk b -> Cstruct.equal a b | Sk a, Sk b -> Bigstring.equal a b
| Ek a, Ek b -> Cstruct.equal a b | Ek a, Ek b -> Bigstring.equal a b
external keypair : external keypair :
Cstruct.buffer -> Cstruct.buffer -> unit = Bigstring.t -> Bigstring.t -> unit =
"ml_crypto_sign_keypair" [@@noalloc] "ml_crypto_sign_keypair" [@@noalloc]
external keypair_seed : external keypair_seed :
Cstruct.buffer -> Cstruct.buffer -> unit = Bigstring.t -> Bigstring.t -> unit =
"ml_crypto_sign_keypair_seed" [@@noalloc] "ml_crypto_sign_keypair_seed" [@@noalloc]
let keypair ?seed () = let keypair ?seed () =
let pk = Cstruct.create_unsafe pkbytes in let pk = Bigstring.create pkbytes in
let sk = Cstruct.create_unsafe skbytes in let sk = Bigstring.create skbytes in
begin match seed with begin match seed with
| None -> | None -> keypair pk sk
Cstruct.(keypair (to_bigarray pk) (to_bigarray sk)) | Some buf ->
| Some cs -> if Bigstring.length buf < seedbytes then
if Cstruct.len cs < seedbytes then invalid_arg "Sign.keypair: seed must be at least 32 bytes long" ;
invalid_arg "Sign.keypair: seed must be at least 32 bytes long" ; Bigstring.blit buf 0 sk 0 pkbytes ;
Cstruct.blit cs 0 sk 0 pkbytes ; keypair_seed pk sk
Cstruct.(keypair_seed (to_bigarray pk) (to_bigarray sk))
end ; end ;
Pk pk, Sk sk Pk pk, Sk sk
let extended (Sk sk) = let extended (Sk sk) =
let cs = Hash.sha512 (Cstruct.sub sk 0 pkbytes) in let buf = Hash.sha512 (Bigstring.sub sk 0 pkbytes) in
Cstruct.(set_uint8 cs 0 (get_uint8 cs 0 land 248)) ; BigEndian.(set_int8 buf 0 (get_uint8 buf 0 land 248)) ;
Cstruct.(set_uint8 cs 31 (get_uint8 cs 31 land 127)) ; BigEndian.(set_int8 buf 31 (get_uint8 buf 31 land 127)) ;
Cstruct.(set_uint8 cs 31 (get_uint8 cs 31 lor 64)) ; BigEndian.(set_int8 buf 31 (get_uint8 buf 31 lor 64)) ;
Ek cs Ek buf
external sign : external sign :
Cstruct.buffer -> Cstruct.buffer -> unit = Bigstring.t -> Bigstring.t -> unit =
"ml_crypto_sign" [@@noalloc] "ml_crypto_sign" [@@noalloc]
external sign_extended : external sign_extended :
Cstruct.buffer -> Cstruct.buffer -> unit = Bigstring.t -> Bigstring.t -> unit =
"ml_crypto_sign_extended" [@@noalloc] "ml_crypto_sign_extended" [@@noalloc]
let sign ~key:(Sk sk) msg = let sign ~key:(Sk sk) msg =
let msglen = Cstruct.len msg in let msglen = Bigstring.length msg in
let cs = Cstruct.create_unsafe (bytes + msglen) in let buf = Bigstring.create (bytes + msglen) in
Cstruct.blit msg 0 cs bytes msglen ; Bigstring.blit msg 0 buf bytes msglen ;
Cstruct.(sign (to_bigarray cs) (to_bigarray sk)) ; sign buf sk ;
cs buf
let sign_extended ~key:(Ek ek) msg = let sign_extended ~key:(Ek ek) msg =
let msglen = Cstruct.len msg in let msglen = Bigstring.length msg in
let cs = Cstruct.create_unsafe (bytes + msglen) in let buf = Bigstring.create (bytes + msglen) in
Cstruct.blit msg 0 cs bytes msglen ; Bigstring.blit msg 0 buf bytes msglen ;
Cstruct.(sign_extended (to_bigarray cs) (to_bigarray ek)) ; sign_extended buf ek ;
cs buf
let detached ~key msg = let detached ~key msg =
Cstruct.sub (sign ~key msg) 0 bytes Bigstring.sub (sign ~key msg) 0 bytes
let detached_extended ~key msg = let detached_extended ~key msg =
Cstruct.sub (sign_extended ~key msg) 0 bytes Bigstring.sub (sign_extended ~key msg) 0 bytes
external verify : external verify :
Cstruct.buffer -> Cstruct.buffer -> Cstruct.buffer -> Cstruct.buffer -> int = Bigstring.t -> Bigstring.t -> Bigstring.t -> int =
"ml_crypto_sign_open" [@@noalloc] "ml_crypto_sign_open" [@@noalloc]
let verify ~key:(Pk pk) smsg = let verify ~key:(Pk pk) smsg =
let mlen = Cstruct.create_unsafe 8 in let msg = Bigstring.(create (length smsg)) in
let msg = Cstruct.(create (len smsg)) in match verify msg smsg pk with
let ret = Cstruct.(verify | -1 -> None
(to_bigarray msg) (to_bigarray mlen) | len -> Some (Bigstring.sub msg 0 len)
(to_bigarray smsg) (to_bigarray pk)) in
match ret with
| 0 ->
let len = Cstruct.LE.get_uint64 mlen 0 |> Int64.to_int in
Some (Cstruct.sub msg 0 len)
| _ -> None
let verify_detached ~key ~signature msg = let verify_detached ~key ~signature msg =
let cs = Cstruct.create_unsafe (bytes + Cstruct.len msg) in let msglen = Bigstring.length msg in
Cstruct.blit signature 0 cs 0 bytes ; let buf = Bigstring.create (bytes + msglen) in
Cstruct.blit msg 0 cs bytes (Cstruct.len msg) ; Bigstring.blit signature 0 buf 0 bytes ;
match verify ~key cs with Bigstring.blit msg 0 buf bytes msglen ;
match verify ~key buf with
| None -> false | None -> false
| Some _ -> true | Some _ -> true
external add : external add :
Cstruct.buffer -> Cstruct.buffer -> unit = Bigstring.t -> Bigstring.t -> unit =
"ml_add" [@@noalloc] "ml_add" [@@noalloc]
let add (Pk p) (Pk q) = let add (Pk p) (Pk q) =
let cs = Cstruct.create_unsafe pkbytes in let buf = Bigstring.create pkbytes in
Cstruct.blit p 0 cs 0 pkbytes ; Bigstring.blit p 0 buf 0 pkbytes ;
Cstruct.(add (to_bigarray cs) (to_bigarray q)) ; add buf q ;
Pk cs Pk buf
external mult : external mult :
Cstruct.buffer -> Cstruct.buffer -> Cstruct.buffer -> unit = Bigstring.t -> Bigstring.t -> Bigstring.t -> unit =
"ml_scalarmult" [@@noalloc] "ml_scalarmult" [@@noalloc]
external base : external base :
Cstruct.buffer -> Cstruct.buffer -> unit = Bigstring.t -> Bigstring.t -> unit =
"ml_scalarbase" [@@noalloc] "ml_scalarbase" [@@noalloc]
let mult (Pk q) s = let mult (Pk q) s =
let r = Cstruct.create_unsafe pkbytes in let r = Bigstring.create pkbytes in
let scalar = Cstruct.create_unsafe pkbytes in let scalar = Bigstring.create pkbytes in
cs_of_z scalar s ; buf_of_z scalar s ;
Cstruct.(mult (to_bigarray r) (to_bigarray q) (to_bigarray scalar)) ; mult r q scalar ;
Pk r Pk r
let base_direct s = let base_direct s =
let cs = Cstruct.create_unsafe pkbytes in let buf = Bigstring.create pkbytes in
Cstruct.(base (to_bigarray cs) (to_bigarray s)) ; base buf s ;
cs buf
let base s = let base s =
let r = Cstruct.create_unsafe pkbytes in let r = Bigstring.create pkbytes in
let scalar = Cstruct.create_unsafe pkbytes in let scalar = Bigstring.create pkbytes in
cs_of_z scalar s ; buf_of_z scalar s ;
Cstruct.(base (to_bigarray r) (to_bigarray scalar)) ; base r scalar ;
Pk r Pk r
let public : type a. a key -> public key = function let public : type a. a key -> public key = function
| Pk _ as pk -> pk | Pk _ as pk -> pk
| Sk cs -> Pk (Cstruct.sub cs 32 32) | Sk buf -> Pk (Bigstring.sub buf 32 32)
| Ek cs -> Pk (base_direct (Cstruct.sub cs 0 32)) | Ek buf -> Pk (base_direct (Bigstring.sub buf 0 32))
end end
(*--------------------------------------------------------------------------- (*---------------------------------------------------------------------------

View File

@ -4,12 +4,12 @@
---------------------------------------------------------------------------*) ---------------------------------------------------------------------------*)
module Rand : sig module Rand : sig
val gen : int -> Cstruct.t val gen : int -> Bigstring.t
val write : Cstruct.t -> unit val write : Bigstring.t -> unit
end end
module Hash : sig module Hash : sig
val sha512 : Cstruct.t -> Cstruct.t val sha512 : Bigstring.t -> Bigstring.t
end end
module Nonce : sig module Nonce : sig
@ -17,9 +17,9 @@ module Nonce : sig
val bytes : int val bytes : int
val gen : unit -> t val gen : unit -> t
val increment : ?step:int -> t -> t val increment : ?step:int -> t -> t
val of_cstruct : Cstruct.t -> t option val of_bytes : Bigstring.t -> t option
val of_cstruct_exn : Cstruct.t -> t val of_bytes_exn : Bigstring.t -> t
val to_cstruct : t -> Cstruct.t val to_bytes : t -> Bigstring.t
end end
module Secretbox : sig module Secretbox : sig
@ -30,14 +30,14 @@ module Secretbox : sig
val boxzerobytes : int val boxzerobytes : int
val genkey : unit -> key val genkey : unit -> key
val of_cstruct : Cstruct.t -> key option val of_bytes : Bigstring.t -> key option
val of_cstruct_exn : Cstruct.t -> key val of_bytes_exn : Bigstring.t -> key
val box : key:key -> nonce:Nonce.t -> msg:Cstruct.t -> Cstruct.t val box : key:key -> nonce:Nonce.t -> msg:Bigstring.t -> Bigstring.t
val box_open : key:key -> nonce:Nonce.t -> cmsg:Cstruct.t -> Cstruct.t option val box_open : key:key -> nonce:Nonce.t -> cmsg:Bigstring.t -> Bigstring.t option
val box_noalloc : key:key -> nonce:Nonce.t -> msg:Cstruct.t -> unit val box_noalloc : key:key -> nonce:Nonce.t -> msg:Bigstring.t -> unit
val box_open_noalloc : key:key -> nonce:Nonce.t -> cmsg:Cstruct.t -> bool val box_open_noalloc : key:key -> nonce:Nonce.t -> cmsg:Bigstring.t -> bool
end end
module Box : sig module Box : sig
@ -53,46 +53,44 @@ module Box : sig
val zerobytes : int val zerobytes : int
val boxzerobytes : int val boxzerobytes : int
val pp : Format.formatter -> _ key -> unit
val show : _ key -> string
val equal : 'a key -> 'a key -> bool val equal : 'a key -> 'a key -> bool
val to_cstruct : _ key -> Cstruct.t val to_bytes : _ key -> Bigstring.t
val blit_to_cstruct : _ key -> ?pos:int -> Cstruct.t -> unit val blit_to_bytes : _ key -> ?pos:int -> Bigstring.t -> unit
val sk_of_cstruct : Cstruct.t -> secret key option val sk_of_bytes : Bigstring.t -> secret key option
val pk_of_cstruct : Cstruct.t -> public key option val pk_of_bytes : Bigstring.t -> public key option
val ck_of_cstruct : Cstruct.t -> combined key option val ck_of_bytes : Bigstring.t -> combined key option
val sk_of_cstruct_exn : Cstruct.t -> secret key val sk_of_bytes_exn : Bigstring.t -> secret key
val pk_of_cstruct_exn : Cstruct.t -> public key val pk_of_bytes_exn : Bigstring.t -> public key
val ck_of_cstruct_exn : Cstruct.t -> combined key val ck_of_bytes_exn : Bigstring.t -> combined key
val keypair : unit -> public key * secret key val keypair : unit -> public key * secret key
val box : val box :
pk:public key -> sk:secret key -> pk:public key -> sk:secret key ->
nonce:Nonce.t -> msg:Cstruct.t -> Cstruct.t nonce:Nonce.t -> msg:Bigstring.t -> Bigstring.t
val box_open : val box_open :
pk:public key -> sk:secret key -> pk:public key -> sk:secret key ->
nonce:Nonce.t -> cmsg:Cstruct.t -> Cstruct.t option nonce:Nonce.t -> cmsg:Bigstring.t -> Bigstring.t option
val box_noalloc : val box_noalloc :
pk:public key -> sk:secret key -> pk:public key -> sk:secret key ->
nonce:Nonce.t -> msg:Cstruct.t -> unit nonce:Nonce.t -> msg:Bigstring.t -> unit
val box_open_noalloc : val box_open_noalloc :
pk:public key -> sk:secret key -> pk:public key -> sk:secret key ->
nonce:Nonce.t -> cmsg:Cstruct.t -> bool nonce:Nonce.t -> cmsg:Bigstring.t -> bool
val combine : public key -> secret key -> combined key val combine : public key -> secret key -> combined key
val box_combined : val box_combined :
k:combined key -> nonce:Nonce.t -> msg:Cstruct.t -> Cstruct.t k:combined key -> nonce:Nonce.t -> msg:Bigstring.t -> Bigstring.t
val box_open_combined : val box_open_combined :
k:combined key -> nonce:Nonce.t -> cmsg:Cstruct.t -> Cstruct.t option k:combined key -> nonce:Nonce.t -> cmsg:Bigstring.t -> Bigstring.t option
val box_combined_noalloc : val box_combined_noalloc :
k:combined key -> nonce:Nonce.t -> msg:Cstruct.t -> unit k:combined key -> nonce:Nonce.t -> msg:Bigstring.t -> unit
val box_open_combined_noalloc : val box_open_combined_noalloc :
k:combined key -> nonce:Nonce.t -> cmsg:Cstruct.t -> bool k:combined key -> nonce:Nonce.t -> cmsg:Bigstring.t -> bool
end end
module Sign : sig module Sign : sig
@ -107,34 +105,32 @@ module Sign : sig
val ekbytes : int val ekbytes : int
val seedbytes : int val seedbytes : int
val pp : Format.formatter -> _ key -> unit val to_bytes : _ key -> Bigstring.t
val show : _ key -> string val blit_to_bytes : _ key -> ?pos:int -> Bigstring.t -> unit
val to_cstruct : _ key -> Cstruct.t
val blit_to_cstruct : _ key -> ?pos:int -> Cstruct.t -> unit
val sk_of_cstruct : Cstruct.t -> secret key option val sk_of_bytes : Bigstring.t -> secret key option
val ek_of_cstruct : Cstruct.t -> extended key option val ek_of_bytes : Bigstring.t -> extended key option
val pk_of_cstruct : Cstruct.t -> public key option val pk_of_bytes : Bigstring.t -> public key option
val sk_of_cstruct_exn : Cstruct.t -> secret key val sk_of_bytes_exn : Bigstring.t -> secret key
val ek_of_cstruct_exn : Cstruct.t -> extended key val ek_of_bytes_exn : Bigstring.t -> extended key
val pk_of_cstruct_exn : Cstruct.t -> public key val pk_of_bytes_exn : Bigstring.t -> public key
val keypair : ?seed:Cstruct.t -> unit -> public key * secret key val keypair : ?seed:Bigstring.t -> unit -> public key * secret key
val equal : 'a key -> 'a key -> bool val equal : 'a key -> 'a key -> bool
val extended : secret key -> extended key val extended : secret key -> extended key
val seed : secret key -> Cstruct.t val seed : secret key -> Bigstring.t
val public : _ key -> public key val public : _ key -> public key
val sign : key:secret key -> Cstruct.t -> Cstruct.t val sign : key:secret key -> Bigstring.t -> Bigstring.t
val sign_extended : key:extended key -> Cstruct.t -> Cstruct.t val sign_extended : key:extended key -> Bigstring.t -> Bigstring.t
val detached : key:secret key -> Cstruct.t -> Cstruct.t val detached : key:secret key -> Bigstring.t -> Bigstring.t
val detached_extended : key:extended key -> Cstruct.t -> Cstruct.t val detached_extended : key:extended key -> Bigstring.t -> Bigstring.t
val verify : key:public key -> Cstruct.t -> Cstruct.t option val verify : key:public key -> Bigstring.t -> Bigstring.t option
val verify_detached : key:public key -> signature:Cstruct.t -> Cstruct.t -> bool val verify_detached : key:public key -> signature:Bigstring.t -> Bigstring.t -> bool
val add : public key -> public key -> public key val add : public key -> public key -> public key
val mult : public key -> Z.t -> public key val mult : public key -> Z.t -> public key

View File

@ -1033,12 +1033,14 @@ CAMLprim value ml_crypto_sign_extended(value sm, value d) {
return Val_unit; return Val_unit;
} }
CAMLprim value ml_crypto_sign_open(value m, value mlen, value sm, value pk) { CAMLprim value ml_crypto_sign_open(value m, value sm, value pk) {
return Val_int(crypto_sign_open(Caml_ba_data_val(m), i64 mlen;
Caml_ba_data_val(mlen), int ret = crypto_sign_open(Caml_ba_data_val(m),
Caml_ba_data_val(sm), &mlen,
Caml_ba_array_val(sm)->dim[0], Caml_ba_data_val(sm),
Caml_ba_data_val(pk))); Caml_ba_array_val(sm)->dim[0],
Caml_ba_data_val(pk));
return (ret == -1 ? Val_long(-1) : Val_long(mlen));
} }
CAMLprim value ml_crypto_sign_keypair(value pk, value sk) { CAMLprim value ml_crypto_sign_keypair(value pk, value sk) {

View File

@ -1,12 +1,17 @@
open Tweetnacl open Tweetnacl
let msg = "Voulez-vous coucher avec moi, ce soir ?" |> Cstruct.of_string let pp_bigstring ppf buf =
let msglen = Cstruct.len msg Format.fprintf ppf "%a" Hex.pp (Hex.of_cstruct (Cstruct.of_bigarray buf))
let bigstring = Alcotest.testable pp_bigstring Bigstring.equal
let msg = Bigstring.of_string "Voulez-vous coucher avec moi, ce soir ?"
let msglen = Bigstring.length msg
let sha512 () = let sha512 () =
let resp = `Hex "7941f442d956f124d77ee1d1f0ba3db100751090462cdce4aed5fcd240529097bc666bf9c424becde760910df652c7aefec50b02d7f6efe666f79e5242fb755b" in let resp = `Hex "7941f442d956f124d77ee1d1f0ba3db100751090462cdce4aed5fcd240529097bc666bf9c424becde760910df652c7aefec50b02d7f6efe666f79e5242fb755b" in
let digest = Hash.sha512 msg in let digest = Hash.sha512 msg in
assert (resp = (Hex.of_cstruct digest)) assert (resp = (Hex.of_cstruct (Cstruct.of_bigarray digest)))
let keypair () = let keypair () =
let seed = Rand.gen 32 in let seed = Rand.gen 32 in
@ -19,16 +24,15 @@ let sign () =
let pk, sk = Sign.keypair () in let pk, sk = Sign.keypair () in
let signed_msg = Sign.sign ~key:sk msg in let signed_msg = Sign.sign ~key:sk msg in
match Sign.verify ~key:pk signed_msg with match Sign.verify ~key:pk signed_msg with
| None -> failwith "Impossible to verify" | None -> assert false
| Some verified_msg -> | Some verified_msg ->
assert (Hex.of_cstruct msg = Alcotest.check bigstring "sign" msg verified_msg
Hex.of_cstruct (Cstruct.sub verified_msg Sign.bytes msglen))
let sign_detached () = let sign_detached () =
let pk, sk = Sign.keypair () in let pk, sk = Sign.keypair () in
let signature = Sign.detached ~key:sk msg in let signature = Sign.detached ~key:sk msg in
match Sign.verify_detached ~key:pk ~signature msg with match Sign.verify_detached ~key:pk ~signature msg with
| false -> failwith "Impossible to verify" | false -> assert false
| true -> () | true -> ()
let sign_extended () = let sign_extended () =
@ -36,34 +40,33 @@ let sign_extended () =
let ek = Sign.extended sk in let ek = Sign.extended sk in
let signed_msg = Sign.sign_extended ~key:ek msg in let signed_msg = Sign.sign_extended ~key:ek msg in
match Sign.verify ~key:pk signed_msg with match Sign.verify ~key:pk signed_msg with
| None -> failwith "Impossible to verify" | None -> assert false
| Some verified_msg -> | Some verified_msg ->
assert (Hex.of_cstruct msg = Alcotest.check bigstring "sign_extended" msg verified_msg
Hex.of_cstruct (Cstruct.sub verified_msg Sign.bytes msglen))
let sign_extended_detached () = let sign_extended_detached () =
let pk, sk = Sign.keypair () in let pk, sk = Sign.keypair () in
let ek = Sign.extended sk in let ek = Sign.extended sk in
let signature = Sign.detached_extended ~key:ek msg in let signature = Sign.detached_extended ~key:ek msg in
match Sign.verify_detached ~key:pk ~signature msg with match Sign.verify_detached ~key:pk ~signature msg with
| false -> failwith "Impossible to verify" | false -> assert false
| true -> () | true -> ()
let public () = let public () =
let pk, sk = Sign.keypair () in let pk, sk = Sign.keypair () in
let pk' = Sign.to_cstruct pk in let pk' = Sign.to_bytes pk in
let ek = Sign.extended sk in let ek = Sign.extended sk in
let ppk = Sign.(public pk |> to_cstruct) in let ppk = Sign.(to_bytes (public pk)) in
let psk = Sign.(public sk |> to_cstruct) in let psk = Sign.(to_bytes (public sk)) in
let pek = Sign.(public ek |> to_cstruct) in let pek = Sign.(to_bytes (public ek)) in
assert (Cstruct.equal pk' ppk) ; Alcotest.check bigstring "public" pk' ppk ;
assert (Cstruct.equal pk' psk) ; Alcotest.check bigstring "public" pk' psk ;
assert (Cstruct.equal pk' pek) Alcotest.check bigstring "public" pk' pek
let base () = let base () =
let pk, sk = Sign.keypair () in let pk, sk = Sign.keypair () in
let ek = Sign.(extended sk |> to_cstruct) in let ek = Sign.(to_bytes (extended sk)) in
let z = Z.of_bits Cstruct.(sub ek 0 32 |> to_string) in let z = Z.of_bits Bigstring.(to_string (sub ek 0 32)) in
let pk' = Sign.base z in let pk' = Sign.base z in
assert (Sign.equal pk pk') assert (Sign.equal pk pk')
@ -105,23 +108,25 @@ let secretbox () =
let key = genkey () in let key = genkey () in
let nonce = Nonce.gen () in let nonce = Nonce.gen () in
let cmsg = box ~key ~nonce ~msg in let cmsg = box ~key ~nonce ~msg in
assert (Cstruct.len cmsg = msglen + boxzerobytes) ; assert (Bigstring.length cmsg = msglen + boxzerobytes) ;
begin match box_open ~key ~nonce ~cmsg with begin match box_open ~key ~nonce ~cmsg with
| None -> assert false | None -> assert false
| Some msg' -> assert Cstruct.(equal msg msg') | Some msg' -> Alcotest.check bigstring "secretbox" msg msg'
end end
let secretbox_noalloc () = let secretbox_noalloc () =
let open Secretbox in let open Secretbox in
let buflen = msglen + zerobytes in let buflen = msglen + zerobytes in
let buf = Cstruct.create buflen in let buf = Bigstring.create buflen in
Cstruct.blit msg 0 buf zerobytes msglen ; Bigstring.fill buf '\x00' ;
Bigstring.blit msg 0 buf zerobytes msglen ;
let key = genkey () in let key = genkey () in
let nonce = Nonce.gen () in let nonce = Nonce.gen () in
box_noalloc ~key ~nonce ~msg:buf ; box_noalloc ~key ~nonce ~msg:buf ;
let res = box_open_noalloc ~key ~nonce ~cmsg:buf in let res = box_open_noalloc ~key ~nonce ~cmsg:buf in
assert res ; assert res ;
assert Cstruct.(equal msg (sub buf zerobytes msglen)) Alcotest.check
bigstring "secretbox_noalloc" msg (Bigstring.sub buf zerobytes msglen)
let secretbox = [ let secretbox = [
"secretbox", `Quick, secretbox ; "secretbox", `Quick, secretbox ;
@ -131,36 +136,39 @@ let secretbox = [
let box () = let box () =
let open Box in let open Box in
let pk, sk = keypair () in let pk, sk = keypair () in
let ck = combine pk sk in let k = combine pk sk in
let nonce = Nonce.gen () in let nonce = Nonce.gen () in
let cmsg = box ~pk ~sk ~nonce ~msg in let cmsg = box ~pk ~sk ~nonce ~msg in
assert (Cstruct.len cmsg = msglen + boxzerobytes) ; assert (Bigstring.length cmsg = msglen + boxzerobytes) ;
begin match box_open ~pk ~sk ~nonce ~cmsg with begin match box_open ~pk ~sk ~nonce ~cmsg with
| None -> assert false | None -> assert false
| Some msg' -> assert Cstruct.(equal msg msg') | Some msg' -> Alcotest.check bigstring "box" msg msg'
end ; end ;
let cmsg = box_combined ~k:ck ~nonce ~msg in let cmsg = box_combined ~k ~nonce ~msg in
begin match box_open_combined ~k:ck ~nonce ~cmsg with begin match box_open_combined ~k ~nonce ~cmsg with
| None -> assert false | None -> assert false
| Some msg' -> assert Cstruct.(equal msg msg') | Some msg' -> Alcotest.check bigstring "box" msg msg'
end end
let box_noalloc () = let box_noalloc () =
let open Box in let open Box in
let buflen = msglen + zerobytes in let buflen = msglen + zerobytes in
let buf = Cstruct.create buflen in let buf = Bigstring.create buflen in
Cstruct.blit msg 0 buf zerobytes msglen ; Bigstring.fill buf '\x00' ;
Bigstring.blit msg 0 buf zerobytes msglen ;
let pk, sk = keypair () in let pk, sk = keypair () in
let ck = combine pk sk in let k = combine pk sk in
let nonce = Nonce.gen () in let nonce = Nonce.gen () in
box_noalloc ~pk ~sk ~nonce ~msg:buf ; box_noalloc ~pk ~sk ~nonce ~msg:buf ;
let res = box_open_noalloc ~pk ~sk ~nonce ~cmsg:buf in let res = box_open_noalloc ~pk ~sk ~nonce ~cmsg:buf in
assert res ; assert res ;
assert Cstruct.(equal msg (sub buf zerobytes msglen)) ; Alcotest.check bigstring
box_combined_noalloc ~k:ck ~nonce ~msg:buf ; "box_noalloc" msg (Bigstring.sub buf zerobytes msglen) ;
let res = box_open_combined_noalloc ~k:ck ~nonce ~cmsg:buf in box_combined_noalloc ~k ~nonce ~msg:buf ;
let res = box_open_combined_noalloc ~k ~nonce ~cmsg:buf in
assert res ; assert res ;
assert Cstruct.(equal msg (sub buf zerobytes msglen)) Alcotest.check bigstring
"box_noalloc" msg (Bigstring.sub buf zerobytes msglen)
let box = [ let box = [
"box", `Quick, box ; "box", `Quick, box ;

View File

@ -16,8 +16,9 @@ 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"}
"hex" {>= "1.2.0"} "bigstring" {>= "0.1.1"}
"cstruct" {>= "3.2.1"} "ocplib-endian" {>= "1.0"}
"zarith" {>= "1.7" } "zarith" {>= "1.7"}
"alcotest" { test } "alcotest" {test & >= "0.8.1"}
"hex" {test & >= "1.2.0"}
] ]