2018-02-04 21:39:34 +04:00
|
|
|
(*---------------------------------------------------------------------------
|
|
|
|
Copyright (c) 2017 Vincent Bernardoff. All rights reserved.
|
|
|
|
Distributed under the ISC license, see terms at the end of the file.
|
|
|
|
---------------------------------------------------------------------------*)
|
|
|
|
|
2018-04-17 13:44:01 +04:00
|
|
|
open EndianBigstring
|
|
|
|
|
2018-02-04 21:39:34 +04:00
|
|
|
module Rand = struct
|
2018-04-17 13:44:01 +04:00
|
|
|
external randombytes : Bigstring.t -> int -> unit =
|
2018-02-04 21:39:34 +04:00
|
|
|
"ml_randombytes" [@@noalloc]
|
|
|
|
|
|
|
|
let gen sz =
|
2018-04-17 13:44:01 +04:00
|
|
|
let buf = Bigstring.create sz in
|
|
|
|
randombytes buf sz ;
|
|
|
|
buf
|
2018-02-04 21:39:34 +04:00
|
|
|
|
2018-04-17 13:44:01 +04:00
|
|
|
let write buf =
|
|
|
|
randombytes buf (Bigstring.length buf)
|
2018-02-04 21:39:34 +04:00
|
|
|
end
|
|
|
|
|
|
|
|
module Hash = struct
|
|
|
|
let bytes = 64
|
|
|
|
|
|
|
|
external sha512 :
|
2018-04-17 13:44:01 +04:00
|
|
|
Bigstring.t -> Bigstring.t -> int -> unit =
|
2018-02-04 21:39:34 +04:00
|
|
|
"ml_crypto_hash" [@@noalloc]
|
|
|
|
|
|
|
|
let sha512 msg =
|
2018-04-17 13:44:01 +04:00
|
|
|
let q = Bigstring.create bytes in
|
|
|
|
sha512 q msg (Bigstring.length msg) ;
|
2018-02-04 21:39:34 +04:00
|
|
|
q
|
|
|
|
end
|
|
|
|
|
2018-04-17 13:44:01 +04:00
|
|
|
let buf_of_z buf z =
|
|
|
|
Bigstring.fill buf '\x00' ;
|
2018-02-04 21:39:34 +04:00
|
|
|
let bits = Z.to_bits z in
|
2018-04-17 13:44:01 +04:00
|
|
|
Bigstring.blit_of_string bits 0 buf 0 (String.length bits)
|
2018-02-04 21:39:34 +04:00
|
|
|
|
2018-04-17 13:44:01 +04:00
|
|
|
let unopt_invalid_arg1 ~msg f buf =
|
|
|
|
match f buf with
|
2018-02-04 21:39:34 +04:00
|
|
|
| Some v -> v
|
|
|
|
| None -> invalid_arg msg
|
|
|
|
|
|
|
|
module Nonce = struct
|
2018-04-17 13:44:01 +04:00
|
|
|
type t = Bigstring.t
|
2018-02-04 21:39:34 +04:00
|
|
|
let bytes = 24
|
|
|
|
|
|
|
|
let gen () =
|
|
|
|
Rand.gen bytes
|
|
|
|
|
|
|
|
let rec incr_byte b step byteno =
|
2018-04-17 13:44:01 +04:00
|
|
|
let res = BigEndian.get_uint16 b byteno + step in
|
2018-02-04 21:39:34 +04:00
|
|
|
let lo = res land 0xffff in
|
|
|
|
let hi = res asr 16 in
|
2018-04-17 13:44:01 +04:00
|
|
|
BigEndian.set_int16 b byteno lo ;
|
2018-02-04 21:39:34 +04:00
|
|
|
if hi = 0 || byteno = 0 then ()
|
|
|
|
else incr_byte b hi (byteno - 2)
|
|
|
|
|
|
|
|
let increment ?(step = 1) nonce =
|
2018-04-17 13:44:01 +04:00
|
|
|
let new_nonce = Bigstring.create 24 in
|
|
|
|
Bigstring.blit nonce 0 new_nonce 0 24 ;
|
2018-02-04 21:39:34 +04:00
|
|
|
incr_byte new_nonce step 22 ;
|
|
|
|
new_nonce
|
|
|
|
|
2018-04-17 13:44:01 +04:00
|
|
|
let of_bytes buf =
|
|
|
|
try Some (Bigstring.sub buf 0 bytes) with _ -> None
|
2018-02-04 21:39:34 +04:00
|
|
|
|
2018-04-17 13:44:01 +04:00
|
|
|
let of_bytes_exn =
|
|
|
|
unopt_invalid_arg1 ~msg:"Box.Nonce.of_bytes_exn" of_bytes
|
2018-02-04 21:39:34 +04:00
|
|
|
|
2018-04-17 13:44:01 +04:00
|
|
|
let to_bytes nonce = nonce
|
2018-02-04 21:39:34 +04:00
|
|
|
end
|
|
|
|
|
|
|
|
module Secretbox = struct
|
2018-04-17 13:44:01 +04:00
|
|
|
type key = Bigstring.t
|
2018-02-04 21:39:34 +04:00
|
|
|
|
|
|
|
let keybytes = 32
|
|
|
|
let zerobytes = 32
|
|
|
|
let boxzerobytes = 16
|
|
|
|
|
|
|
|
let genkey () =
|
|
|
|
Rand.gen 32
|
|
|
|
|
2018-04-17 13:44:01 +04:00
|
|
|
let of_bytes buf =
|
|
|
|
if Bigstring.length buf < keybytes then None
|
|
|
|
else Some (Bigstring.sub buf 0 keybytes)
|
2018-02-04 21:39:34 +04:00
|
|
|
|
2018-04-17 13:44:01 +04:00
|
|
|
let of_bytes_exn =
|
|
|
|
unopt_invalid_arg1 ~msg:"Secret_box.of_bytes_exn" of_bytes
|
2018-02-04 21:39:34 +04:00
|
|
|
|
|
|
|
external secretbox :
|
2018-04-17 13:44:01 +04:00
|
|
|
Bigstring.t -> Bigstring.t ->
|
|
|
|
Bigstring.t -> Bigstring.t -> unit = "ml_secretbox" [@@noalloc]
|
2018-02-04 21:39:34 +04:00
|
|
|
|
|
|
|
external secretbox_open :
|
2018-04-17 13:44:01 +04:00
|
|
|
Bigstring.t -> Bigstring.t ->
|
|
|
|
Bigstring.t -> Bigstring.t -> int = "ml_secretbox_open" [@@noalloc]
|
2018-02-04 21:39:34 +04:00
|
|
|
|
|
|
|
let box ~key ~nonce ~msg =
|
2018-04-17 13:44:01 +04:00
|
|
|
let msglen = Bigstring.length msg in
|
2018-02-04 21:39:34 +04:00
|
|
|
let buflen = msglen + zerobytes in
|
2018-04-17 13:44:01 +04:00
|
|
|
let buf = Bigstring.create buflen in
|
|
|
|
Bigstring.fill buf '\x00' ;
|
|
|
|
Bigstring.blit msg 0 buf zerobytes msglen ;
|
|
|
|
secretbox buf buf nonce key ;
|
|
|
|
Bigstring.sub buf boxzerobytes (buflen - boxzerobytes)
|
2018-02-04 21:39:34 +04:00
|
|
|
|
|
|
|
let box_noalloc ~key ~nonce ~msg =
|
2018-04-17 13:44:01 +04:00
|
|
|
secretbox msg msg nonce key
|
2018-02-04 21:39:34 +04:00
|
|
|
|
|
|
|
let box_open ~key ~nonce ~cmsg =
|
2018-04-17 13:44:01 +04:00
|
|
|
let msglen = Bigstring.length cmsg - boxzerobytes in
|
|
|
|
let buf = Bigstring.create (zerobytes + msglen) in
|
|
|
|
Bigstring.fill buf '\x00' ;
|
|
|
|
Bigstring.blit cmsg 0 buf boxzerobytes (msglen + boxzerobytes) ;
|
|
|
|
match secretbox_open buf buf nonce key with
|
|
|
|
| 0 -> Some (Bigstring.sub buf zerobytes msglen)
|
2018-02-04 21:39:34 +04:00
|
|
|
| _ -> None
|
|
|
|
|
|
|
|
let box_open_noalloc ~key ~nonce ~cmsg =
|
2018-04-17 13:44:01 +04:00
|
|
|
match secretbox_open cmsg cmsg nonce key with
|
2018-02-04 21:39:34 +04:00
|
|
|
| 0 -> true
|
|
|
|
| _ -> false
|
|
|
|
end
|
|
|
|
|
|
|
|
module Box = struct
|
|
|
|
type secret
|
|
|
|
type public
|
|
|
|
type combined
|
|
|
|
type _ key =
|
2018-04-17 13:44:01 +04:00
|
|
|
| Sk : Bigstring.t -> secret key
|
|
|
|
| Pk : Bigstring.t -> public key
|
|
|
|
| Ck : Bigstring.t -> combined key
|
2018-02-04 21:39:34 +04:00
|
|
|
|
|
|
|
let skbytes = 32
|
|
|
|
let pkbytes = 32
|
|
|
|
let beforenmbytes = 32
|
|
|
|
let zerobytes = 32
|
|
|
|
let boxzerobytes = 16
|
|
|
|
|
2018-04-17 13:44:01 +04:00
|
|
|
let to_bytes : type a. a key -> Bigstring.t = function
|
|
|
|
| Pk buf -> buf
|
|
|
|
| Sk buf -> buf
|
|
|
|
| Ck buf -> buf
|
2018-02-04 21:39:34 +04:00
|
|
|
|
2018-04-17 13:44:01 +04:00
|
|
|
let blit_to_bytes :
|
|
|
|
type a. a key -> ?pos:int -> Bigstring.t -> unit = fun key ?(pos=0) buf ->
|
2018-02-04 21:39:34 +04:00
|
|
|
match key with
|
2018-04-17 13:44:01 +04:00
|
|
|
| Pk pk -> Bigstring.blit pk 0 buf pos pkbytes
|
|
|
|
| Sk sk -> Bigstring.blit sk 0 buf pos skbytes
|
|
|
|
| Ck ck -> Bigstring.blit ck 0 buf pos beforenmbytes
|
2018-02-04 21:39:34 +04:00
|
|
|
|
|
|
|
let equal :
|
|
|
|
type a. a key -> a key -> bool = fun a b -> match a, b with
|
2018-04-17 13:44:01 +04:00
|
|
|
| Pk a, Pk b -> Bigstring.equal a b
|
|
|
|
| Sk a, Sk b -> Bigstring.equal a b
|
|
|
|
| Ck a, Ck b -> Bigstring.equal a b
|
|
|
|
|
|
|
|
let sk_of_bytes buf =
|
|
|
|
try Some (Sk (Bigstring.sub buf 0 skbytes)) with _ -> None
|
|
|
|
let pk_of_bytes buf =
|
|
|
|
try Some (Pk (Bigstring.sub buf 0 pkbytes)) with _ -> None
|
|
|
|
let ck_of_bytes buf =
|
|
|
|
try Some (Ck (Bigstring.sub buf 0 beforenmbytes)) with _ -> None
|
|
|
|
|
|
|
|
let sk_of_bytes_exn =
|
|
|
|
unopt_invalid_arg1 ~msg:"Box.sk_of_bytes_exn" sk_of_bytes
|
|
|
|
let pk_of_bytes_exn =
|
|
|
|
unopt_invalid_arg1 ~msg:"Box.pk_of_bytes_exn" pk_of_bytes
|
|
|
|
let ck_of_bytes_exn =
|
|
|
|
unopt_invalid_arg1 ~msg:"Box.ck_of_bytes_exn" ck_of_bytes
|
2018-02-04 21:39:34 +04:00
|
|
|
|
|
|
|
external keypair :
|
2018-04-17 13:44:01 +04:00
|
|
|
Bigstring.t -> Bigstring.t -> unit =
|
2018-02-04 21:39:34 +04:00
|
|
|
"ml_crypto_box_keypair" [@@noalloc]
|
|
|
|
|
|
|
|
let keypair () =
|
2018-04-17 13:44:01 +04:00
|
|
|
let sk = Bigstring.create skbytes in
|
|
|
|
let pk = Bigstring.create pkbytes in
|
|
|
|
keypair pk sk ;
|
2018-02-04 21:39:34 +04:00
|
|
|
Pk pk, Sk sk
|
|
|
|
|
|
|
|
external box_stub :
|
2018-04-17 13:44:01 +04:00
|
|
|
Bigstring.t -> Bigstring.t -> Bigstring.t ->
|
|
|
|
Bigstring.t -> Bigstring.t -> unit =
|
2018-02-04 21:39:34 +04:00
|
|
|
"ml_crypto_box" [@@noalloc]
|
|
|
|
|
|
|
|
let box ~pk:(Pk pk) ~sk:(Sk sk) ~nonce ~msg =
|
2018-04-17 13:44:01 +04:00
|
|
|
let msglen = Bigstring.length msg in
|
2018-02-04 21:39:34 +04:00
|
|
|
let buflen = msglen + zerobytes in
|
2018-04-17 13:44:01 +04:00
|
|
|
let buf = Bigstring.create buflen in
|
|
|
|
Bigstring.fill buf '\x00' ;
|
|
|
|
Bigstring.blit msg 0 buf zerobytes msglen ;
|
|
|
|
box_stub buf buf nonce pk sk ;
|
|
|
|
Bigstring.sub buf boxzerobytes (buflen - boxzerobytes)
|
2018-02-04 21:39:34 +04:00
|
|
|
|
|
|
|
let box_noalloc ~pk:(Pk pk) ~sk:(Sk sk) ~nonce ~msg =
|
2018-04-17 13:44:01 +04:00
|
|
|
box_stub msg msg nonce pk sk
|
2018-02-04 21:39:34 +04:00
|
|
|
|
|
|
|
external box_open_stub :
|
2018-04-17 13:44:01 +04:00
|
|
|
Bigstring.t -> Bigstring.t -> Bigstring.t ->
|
|
|
|
Bigstring.t -> Bigstring.t -> int =
|
2018-02-04 21:39:34 +04:00
|
|
|
"ml_crypto_box_open" [@@noalloc]
|
|
|
|
|
|
|
|
let box_open ~pk:(Pk pk) ~sk:(Sk sk) ~nonce ~cmsg =
|
2018-04-17 13:44:01 +04:00
|
|
|
let msglen = Bigstring.length cmsg - boxzerobytes in
|
|
|
|
let buf = Bigstring.create (zerobytes + msglen) in
|
|
|
|
Bigstring.fill buf '\x00' ;
|
|
|
|
Bigstring.blit cmsg 0 buf boxzerobytes (msglen + boxzerobytes) ;
|
|
|
|
match box_open_stub buf buf nonce pk sk with
|
|
|
|
| 0 -> Some (Bigstring.sub buf zerobytes msglen)
|
2018-02-04 21:39:34 +04:00
|
|
|
| _ -> None
|
|
|
|
|
|
|
|
let box_open_noalloc ~pk:(Pk pk) ~sk:(Sk sk) ~nonce ~cmsg =
|
2018-04-17 13:44:01 +04:00
|
|
|
match box_open_stub cmsg cmsg nonce pk sk with
|
2018-02-04 21:39:34 +04:00
|
|
|
| 0 -> true
|
|
|
|
| _ -> false
|
|
|
|
|
|
|
|
external box_beforenm :
|
2018-04-17 13:44:01 +04:00
|
|
|
Bigstring.t -> Bigstring.t -> Bigstring.t -> unit =
|
2018-02-04 21:39:34 +04:00
|
|
|
"ml_crypto_box_beforenm" [@@noalloc]
|
|
|
|
|
|
|
|
let combine (Pk pk) (Sk sk) =
|
2018-04-17 13:44:01 +04:00
|
|
|
let combined = Bigstring.create beforenmbytes in
|
|
|
|
box_beforenm combined pk sk ;
|
2018-02-04 21:39:34 +04:00
|
|
|
Ck combined
|
|
|
|
|
|
|
|
external box_afternm :
|
2018-04-17 13:44:01 +04:00
|
|
|
Bigstring.t -> Bigstring.t ->
|
|
|
|
Bigstring.t -> Bigstring.t -> unit =
|
2018-02-04 21:39:34 +04:00
|
|
|
"ml_crypto_box_afternm" [@@noalloc]
|
|
|
|
|
|
|
|
let box_combined ~k:(Ck k) ~nonce ~msg =
|
2018-04-17 13:44:01 +04:00
|
|
|
let msglen = Bigstring.length msg in
|
2018-02-04 21:39:34 +04:00
|
|
|
let buflen = msglen + zerobytes in
|
2018-04-17 13:44:01 +04:00
|
|
|
let buf = Bigstring.create buflen in
|
|
|
|
Bigstring.fill buf '\x00' ;
|
|
|
|
Bigstring.blit msg 0 buf zerobytes msglen ;
|
|
|
|
box_afternm buf buf nonce k ;
|
|
|
|
Bigstring.sub buf boxzerobytes (buflen - boxzerobytes)
|
2018-02-04 21:39:34 +04:00
|
|
|
|
|
|
|
let box_combined_noalloc ~k:(Ck k) ~nonce ~msg =
|
2018-04-17 13:44:01 +04:00
|
|
|
box_afternm msg msg nonce k
|
2018-02-04 21:39:34 +04:00
|
|
|
|
|
|
|
external box_open_afternm :
|
2018-04-17 13:44:01 +04:00
|
|
|
Bigstring.t -> Bigstring.t ->
|
|
|
|
Bigstring.t -> Bigstring.t -> int =
|
2018-02-04 21:39:34 +04:00
|
|
|
"ml_crypto_box_open_afternm" [@@noalloc]
|
|
|
|
|
|
|
|
let box_open_combined ~k:(Ck k) ~nonce ~cmsg =
|
2018-04-17 13:44:01 +04:00
|
|
|
let msglen = Bigstring.length cmsg - boxzerobytes in
|
2018-02-04 21:39:34 +04:00
|
|
|
let buflen = msglen + zerobytes in
|
2018-04-17 13:44:01 +04:00
|
|
|
let buf = Bigstring.create buflen in
|
|
|
|
Bigstring.fill buf '\x00' ;
|
|
|
|
Bigstring.blit cmsg 0 buf boxzerobytes (msglen + boxzerobytes) ;
|
|
|
|
match box_open_afternm buf buf nonce k with
|
|
|
|
| 0 -> Some (Bigstring.sub buf zerobytes msglen)
|
2018-02-04 21:39:34 +04:00
|
|
|
| _ -> None
|
|
|
|
|
|
|
|
let box_open_combined_noalloc ~k:(Ck k) ~nonce ~cmsg =
|
2018-04-17 13:44:01 +04:00
|
|
|
match box_open_afternm cmsg cmsg nonce k with
|
2018-02-04 21:39:34 +04:00
|
|
|
| 0 -> true
|
|
|
|
| _ -> false
|
|
|
|
end
|
|
|
|
|
|
|
|
module Sign = struct
|
|
|
|
type secret
|
|
|
|
type extended
|
|
|
|
type public
|
|
|
|
type _ key =
|
2018-04-17 13:44:01 +04:00
|
|
|
| Sk : Bigstring.t -> secret key
|
|
|
|
| Ek : Bigstring.t -> extended key
|
|
|
|
| Pk : Bigstring.t -> public key
|
2018-02-04 21:39:34 +04:00
|
|
|
|
|
|
|
let bytes = 64
|
|
|
|
let pkbytes = 32
|
|
|
|
let skbytes = 64
|
|
|
|
let ekbytes = 64
|
|
|
|
let seedbytes = 32
|
|
|
|
|
2018-04-17 13:44:01 +04:00
|
|
|
let sk_of_bytes buf =
|
|
|
|
try Some (Sk (Bigstring.sub buf 0 skbytes)) with _ -> None
|
|
|
|
let ek_of_bytes buf =
|
|
|
|
try Some (Ek (Bigstring.sub buf 0 ekbytes)) with _ -> None
|
|
|
|
let pk_of_bytes buf =
|
|
|
|
try Some (Pk (Bigstring.sub buf 0 pkbytes)) with _ -> None
|
|
|
|
|
|
|
|
let sk_of_bytes_exn =
|
|
|
|
unopt_invalid_arg1 ~msg:"Sign.sk_of_bytes_exn" sk_of_bytes
|
|
|
|
let ek_of_bytes_exn =
|
|
|
|
unopt_invalid_arg1 ~msg:"Sign.ek_of_bytes_exn" ek_of_bytes
|
|
|
|
let pk_of_bytes_exn =
|
|
|
|
unopt_invalid_arg1 ~msg:"Sign.pk_of_bytes_exn" pk_of_bytes
|
|
|
|
|
|
|
|
let to_bytes : type a. a key -> Bigstring.t = function
|
|
|
|
| Pk buf -> buf
|
|
|
|
| Sk buf -> buf
|
|
|
|
| Ek buf -> buf
|
|
|
|
|
|
|
|
let seed (Sk buf) = Bigstring.sub buf 0 seedbytes
|
|
|
|
|
|
|
|
let blit_to_bytes :
|
|
|
|
type a. a key -> ?pos:int -> Bigstring.t -> unit = fun key ?(pos=0) buf ->
|
2018-02-04 21:39:34 +04:00
|
|
|
match key with
|
2018-04-17 13:44:01 +04:00
|
|
|
| Pk pk -> Bigstring.blit pk 0 buf pos pkbytes
|
|
|
|
| Sk sk -> Bigstring.blit sk 0 buf pos skbytes
|
|
|
|
| Ek ek -> Bigstring.blit ek 0 buf pos ekbytes
|
2018-02-04 21:39:34 +04:00
|
|
|
|
|
|
|
let equal :
|
|
|
|
type a. a key -> a key -> bool = fun a b -> match a, b with
|
2018-04-17 13:44:01 +04:00
|
|
|
| Pk a, Pk b -> Bigstring.equal a b
|
|
|
|
| Sk a, Sk b -> Bigstring.equal a b
|
|
|
|
| Ek a, Ek b -> Bigstring.equal a b
|
2018-02-04 21:39:34 +04:00
|
|
|
|
|
|
|
external keypair :
|
2018-04-17 13:44:01 +04:00
|
|
|
Bigstring.t -> Bigstring.t -> unit =
|
2018-02-04 21:39:34 +04:00
|
|
|
"ml_crypto_sign_keypair" [@@noalloc]
|
|
|
|
|
|
|
|
external keypair_seed :
|
2018-04-17 13:44:01 +04:00
|
|
|
Bigstring.t -> Bigstring.t -> unit =
|
2018-02-04 21:39:34 +04:00
|
|
|
"ml_crypto_sign_keypair_seed" [@@noalloc]
|
|
|
|
|
|
|
|
let keypair ?seed () =
|
2018-04-17 13:44:01 +04:00
|
|
|
let pk = Bigstring.create pkbytes in
|
|
|
|
let sk = Bigstring.create skbytes in
|
2018-02-04 21:39:34 +04:00
|
|
|
begin match seed with
|
2018-04-17 13:44:01 +04:00
|
|
|
| None -> keypair pk sk
|
|
|
|
| Some buf ->
|
2018-05-03 17:35:54 +04:00
|
|
|
if Bigstring.length buf < seedbytes then
|
|
|
|
invalid_arg "Sign.keypair: seed must be at least 32 bytes long" ;
|
|
|
|
Bigstring.blit buf 0 sk 0 pkbytes ;
|
|
|
|
keypair_seed pk sk
|
2018-02-04 21:39:34 +04:00
|
|
|
end ;
|
|
|
|
Pk pk, Sk sk
|
|
|
|
|
|
|
|
let extended (Sk sk) =
|
2018-04-17 13:44:01 +04:00
|
|
|
let buf = Hash.sha512 (Bigstring.sub sk 0 pkbytes) in
|
|
|
|
BigEndian.(set_int8 buf 0 (get_uint8 buf 0 land 248)) ;
|
|
|
|
BigEndian.(set_int8 buf 31 (get_uint8 buf 31 land 127)) ;
|
|
|
|
BigEndian.(set_int8 buf 31 (get_uint8 buf 31 lor 64)) ;
|
|
|
|
Ek buf
|
2018-02-04 21:39:34 +04:00
|
|
|
|
|
|
|
external sign :
|
2018-04-17 13:44:01 +04:00
|
|
|
Bigstring.t -> Bigstring.t -> unit =
|
2018-02-04 21:39:34 +04:00
|
|
|
"ml_crypto_sign" [@@noalloc]
|
|
|
|
|
|
|
|
external sign_extended :
|
2018-04-17 13:44:01 +04:00
|
|
|
Bigstring.t -> Bigstring.t -> unit =
|
2018-02-04 21:39:34 +04:00
|
|
|
"ml_crypto_sign_extended" [@@noalloc]
|
|
|
|
|
|
|
|
let sign ~key:(Sk sk) msg =
|
2018-04-17 13:44:01 +04:00
|
|
|
let msglen = Bigstring.length msg in
|
|
|
|
let buf = Bigstring.create (bytes + msglen) in
|
|
|
|
Bigstring.blit msg 0 buf bytes msglen ;
|
|
|
|
sign buf sk ;
|
|
|
|
buf
|
2018-02-04 21:39:34 +04:00
|
|
|
|
|
|
|
let sign_extended ~key:(Ek ek) msg =
|
2018-04-17 13:44:01 +04:00
|
|
|
let msglen = Bigstring.length msg in
|
|
|
|
let buf = Bigstring.create (bytes + msglen) in
|
|
|
|
Bigstring.blit msg 0 buf bytes msglen ;
|
|
|
|
sign_extended buf ek ;
|
|
|
|
buf
|
2018-02-04 21:39:34 +04:00
|
|
|
|
|
|
|
let detached ~key msg =
|
2018-04-17 13:44:01 +04:00
|
|
|
Bigstring.sub (sign ~key msg) 0 bytes
|
2018-02-04 21:39:34 +04:00
|
|
|
|
|
|
|
let detached_extended ~key msg =
|
2018-04-17 13:44:01 +04:00
|
|
|
Bigstring.sub (sign_extended ~key msg) 0 bytes
|
2018-02-04 21:39:34 +04:00
|
|
|
|
|
|
|
external verify :
|
2018-04-17 13:44:01 +04:00
|
|
|
Bigstring.t -> Bigstring.t -> Bigstring.t -> int =
|
2018-02-04 21:39:34 +04:00
|
|
|
"ml_crypto_sign_open" [@@noalloc]
|
|
|
|
|
|
|
|
let verify ~key:(Pk pk) smsg =
|
2018-04-17 13:44:01 +04:00
|
|
|
let msg = Bigstring.(create (length smsg)) in
|
|
|
|
match verify msg smsg pk with
|
|
|
|
| -1 -> None
|
|
|
|
| len -> Some (Bigstring.sub msg 0 len)
|
2018-02-04 21:39:34 +04:00
|
|
|
|
|
|
|
let verify_detached ~key ~signature msg =
|
2018-04-17 13:44:01 +04:00
|
|
|
let msglen = Bigstring.length msg in
|
|
|
|
let buf = Bigstring.create (bytes + msglen) in
|
|
|
|
Bigstring.blit signature 0 buf 0 bytes ;
|
|
|
|
Bigstring.blit msg 0 buf bytes msglen ;
|
|
|
|
match verify ~key buf with
|
2018-02-04 21:39:34 +04:00
|
|
|
| None -> false
|
|
|
|
| Some _ -> true
|
|
|
|
|
|
|
|
external add :
|
2018-04-17 13:44:01 +04:00
|
|
|
Bigstring.t -> Bigstring.t -> unit =
|
2018-02-04 21:39:34 +04:00
|
|
|
"ml_add" [@@noalloc]
|
|
|
|
|
|
|
|
let add (Pk p) (Pk q) =
|
2018-04-17 13:44:01 +04:00
|
|
|
let buf = Bigstring.create pkbytes in
|
|
|
|
Bigstring.blit p 0 buf 0 pkbytes ;
|
|
|
|
add buf q ;
|
|
|
|
Pk buf
|
2018-02-04 21:39:34 +04:00
|
|
|
|
|
|
|
external mult :
|
2018-04-17 13:44:01 +04:00
|
|
|
Bigstring.t -> Bigstring.t -> Bigstring.t -> unit =
|
2018-02-04 21:39:34 +04:00
|
|
|
"ml_scalarmult" [@@noalloc]
|
|
|
|
|
|
|
|
external base :
|
2018-04-17 13:44:01 +04:00
|
|
|
Bigstring.t -> Bigstring.t -> unit =
|
2018-02-04 21:39:34 +04:00
|
|
|
"ml_scalarbase" [@@noalloc]
|
|
|
|
|
|
|
|
let mult (Pk q) s =
|
2018-04-17 13:44:01 +04:00
|
|
|
let r = Bigstring.create pkbytes in
|
|
|
|
let scalar = Bigstring.create pkbytes in
|
|
|
|
buf_of_z scalar s ;
|
|
|
|
mult r q scalar ;
|
2018-02-04 21:39:34 +04:00
|
|
|
Pk r
|
|
|
|
|
|
|
|
let base_direct s =
|
2018-04-17 13:44:01 +04:00
|
|
|
let buf = Bigstring.create pkbytes in
|
|
|
|
base buf s ;
|
|
|
|
buf
|
2018-02-04 21:39:34 +04:00
|
|
|
|
|
|
|
let base s =
|
2018-04-17 13:44:01 +04:00
|
|
|
let r = Bigstring.create pkbytes in
|
|
|
|
let scalar = Bigstring.create pkbytes in
|
|
|
|
buf_of_z scalar s ;
|
|
|
|
base r scalar ;
|
2018-02-04 21:39:34 +04:00
|
|
|
Pk r
|
|
|
|
|
|
|
|
let public : type a. a key -> public key = function
|
|
|
|
| Pk _ as pk -> pk
|
2018-04-17 13:44:01 +04:00
|
|
|
| Sk buf -> Pk (Bigstring.sub buf 32 32)
|
|
|
|
| Ek buf -> Pk (base_direct (Bigstring.sub buf 0 32))
|
2018-02-04 21:39:34 +04:00
|
|
|
end
|
|
|
|
|
|
|
|
(*---------------------------------------------------------------------------
|
|
|
|
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.
|
|
|
|
---------------------------------------------------------------------------*)
|