2018-04-05 19:35:35 +04:00
|
|
|
(**************************************************************************)
|
|
|
|
(* *)
|
|
|
|
(* Copyright (c) 2014 - 2018. *)
|
|
|
|
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
|
|
|
|
(* *)
|
|
|
|
(* All rights reserved. No warranty, explicit or implicit, provided. *)
|
|
|
|
(* *)
|
|
|
|
(**************************************************************************)
|
|
|
|
|
|
|
|
open Error_monad
|
|
|
|
|
|
|
|
type public_key_hash =
|
|
|
|
| Ed25519 of Ed25519.Public_key_hash.t
|
|
|
|
| Secp256k1 of Secp256k1.Public_key_hash.t
|
2018-06-05 21:27:58 +04:00
|
|
|
| P256 of P256.Public_key_hash.t
|
2018-04-05 19:35:35 +04:00
|
|
|
|
|
|
|
type public_key =
|
|
|
|
| Ed25519 of Ed25519.Public_key.t
|
|
|
|
| Secp256k1 of Secp256k1.Public_key.t
|
2018-06-05 21:27:58 +04:00
|
|
|
| P256 of P256.Public_key.t
|
2018-04-05 19:35:35 +04:00
|
|
|
|
|
|
|
type secret_key =
|
|
|
|
| Ed25519 of Ed25519.Secret_key.t
|
|
|
|
| Secp256k1 of Secp256k1.Secret_key.t
|
2018-06-05 21:27:58 +04:00
|
|
|
| P256 of P256.Secret_key.t
|
2018-04-05 19:35:35 +04:00
|
|
|
|
2018-05-25 17:50:31 +04:00
|
|
|
type watermark =
|
2018-06-27 19:00:24 +04:00
|
|
|
| Block_header of Chain_id.t
|
|
|
|
| Endorsement of Chain_id.t
|
2018-05-25 17:50:31 +04:00
|
|
|
| Generic_operation
|
|
|
|
| Custom of MBytes.t
|
|
|
|
|
2018-04-05 19:35:35 +04:00
|
|
|
module Public_key_hash = struct
|
|
|
|
|
|
|
|
type t = public_key_hash =
|
|
|
|
| Ed25519 of Ed25519.Public_key_hash.t
|
|
|
|
| Secp256k1 of Secp256k1.Public_key_hash.t
|
2018-06-05 21:27:58 +04:00
|
|
|
| P256 of P256.Public_key_hash.t
|
2018-04-05 19:35:35 +04:00
|
|
|
|
|
|
|
let name = "Signature.Public_key_hash"
|
2018-06-05 21:27:58 +04:00
|
|
|
let title = "A Ed25519, Secp256k1, or P256 public key hash"
|
2018-04-05 19:35:35 +04:00
|
|
|
|
|
|
|
type Base58.data += Data of t (* unused *)
|
|
|
|
let b58check_encoding = (* unused *)
|
|
|
|
Base58.register_encoding
|
|
|
|
~prefix: "\255\255"
|
|
|
|
~length: 2
|
|
|
|
~to_raw: (fun _ -> assert false)
|
|
|
|
~of_raw: (fun _ -> assert false)
|
|
|
|
~wrap: (fun x -> Data x)
|
|
|
|
|
|
|
|
let raw_encoding =
|
|
|
|
let open Data_encoding in
|
2018-05-29 16:57:59 +04:00
|
|
|
def "public_key_hash" ~description:title @@
|
2018-04-05 19:35:35 +04:00
|
|
|
union [
|
|
|
|
case (Tag 0) Ed25519.Public_key_hash.encoding
|
2018-06-01 01:19:43 +04:00
|
|
|
~title:"Ed25519"
|
2018-04-05 19:35:35 +04:00
|
|
|
(function Ed25519 x -> Some x | _ -> None)
|
|
|
|
(function x -> Ed25519 x);
|
|
|
|
case (Tag 1) Secp256k1.Public_key_hash.encoding
|
2018-06-01 01:19:43 +04:00
|
|
|
~title:"Secp256k1"
|
2018-04-05 19:35:35 +04:00
|
|
|
(function Secp256k1 x -> Some x | _ -> None)
|
2018-06-05 21:27:58 +04:00
|
|
|
(function x -> Secp256k1 x) ;
|
|
|
|
case (Tag 2)
|
|
|
|
~title:"P256" P256.Public_key_hash.encoding
|
|
|
|
(function P256 x -> Some x | _ -> None)
|
|
|
|
(function x -> P256 x)
|
2018-04-05 19:35:35 +04:00
|
|
|
]
|
|
|
|
|
|
|
|
let to_bytes s =
|
2018-05-12 21:54:57 +04:00
|
|
|
Data_encoding.Binary.to_bytes_exn raw_encoding s
|
2018-04-05 19:35:35 +04:00
|
|
|
let of_bytes_opt s =
|
|
|
|
Data_encoding.Binary.of_bytes raw_encoding s
|
|
|
|
let to_string s = MBytes.to_string (to_bytes s)
|
|
|
|
let of_string_opt s = of_bytes_opt (MBytes.of_string s)
|
|
|
|
|
|
|
|
let size = 1 + Ed25519.size
|
|
|
|
|
2018-04-19 18:50:31 +04:00
|
|
|
let zero = Ed25519 Ed25519.Public_key_hash.zero
|
|
|
|
|
2018-04-05 19:35:35 +04:00
|
|
|
include Helpers.MakeRaw(struct
|
|
|
|
type nonrec t = t
|
|
|
|
let name = name
|
|
|
|
let of_bytes_opt = of_bytes_opt
|
|
|
|
let of_string_opt = of_string_opt
|
|
|
|
let to_string = to_string
|
|
|
|
end)
|
|
|
|
|
|
|
|
let of_b58check_opt s =
|
|
|
|
match Base58.decode s with
|
|
|
|
| Some Ed25519.Public_key_hash.Data pkh -> Some (Ed25519 pkh)
|
|
|
|
| Some Secp256k1.Public_key_hash.Data pkh -> Some (Secp256k1 pkh)
|
2018-06-05 21:27:58 +04:00
|
|
|
| Some P256.Public_key_hash.Data pkh -> Some (P256 pkh)
|
2018-04-05 19:35:35 +04:00
|
|
|
| _ -> None
|
|
|
|
|
|
|
|
let of_b58check_exn s =
|
|
|
|
match of_b58check_opt s with
|
|
|
|
| Some x -> x
|
|
|
|
| None -> Format.kasprintf Pervasives.failwith "Unexpected data (%s)" name
|
|
|
|
let of_b58check s =
|
|
|
|
match of_b58check_opt s with
|
|
|
|
| Some x -> Ok x
|
|
|
|
| None ->
|
|
|
|
generic_error
|
|
|
|
"Failed to read a b58check_encoding data (%s): %S"
|
|
|
|
name s
|
|
|
|
|
|
|
|
let to_b58check = function
|
|
|
|
| Ed25519 pkh -> Ed25519.Public_key_hash.to_b58check pkh
|
|
|
|
| Secp256k1 pkh -> Secp256k1.Public_key_hash.to_b58check pkh
|
2018-06-05 21:27:58 +04:00
|
|
|
| P256 pkh -> P256.Public_key_hash.to_b58check pkh
|
2018-04-05 19:35:35 +04:00
|
|
|
|
|
|
|
let to_short_b58check = function
|
|
|
|
| Ed25519 pkh -> Ed25519.Public_key_hash.to_short_b58check pkh
|
|
|
|
| Secp256k1 pkh -> Secp256k1.Public_key_hash.to_short_b58check pkh
|
2018-06-05 21:27:58 +04:00
|
|
|
| P256 pkh -> P256.Public_key_hash.to_short_b58check pkh
|
2018-04-05 19:35:35 +04:00
|
|
|
|
|
|
|
let to_path key l = match key with
|
|
|
|
| Ed25519 h -> "ed25519" :: Ed25519.Public_key_hash.to_path h l
|
|
|
|
| Secp256k1 h -> "secp256k1" :: Secp256k1.Public_key_hash.to_path h l
|
2018-06-05 21:27:58 +04:00
|
|
|
| P256 h -> "p256" :: P256.Public_key_hash.to_path h l
|
2018-04-05 19:35:35 +04:00
|
|
|
|
|
|
|
let of_path = function
|
|
|
|
| "ed25519" :: q -> begin
|
|
|
|
match Ed25519.Public_key_hash.of_path q with
|
|
|
|
| Some pkh -> Some (Ed25519 pkh)
|
|
|
|
| None -> None
|
|
|
|
end
|
|
|
|
| "secp256k1" :: q -> begin
|
|
|
|
match Secp256k1.Public_key_hash.of_path q with
|
|
|
|
| Some pkh -> Some (Secp256k1 pkh)
|
|
|
|
| None -> None
|
|
|
|
end
|
2018-06-05 21:27:58 +04:00
|
|
|
| "p256" :: q -> begin
|
|
|
|
match P256.Public_key_hash.of_path q with
|
|
|
|
| Some pkh -> Some (P256 pkh)
|
|
|
|
| None -> None
|
|
|
|
end
|
2018-04-05 19:35:35 +04:00
|
|
|
| _ -> assert false (* FIXME classification des erreurs *)
|
2018-06-05 21:27:58 +04:00
|
|
|
|
2018-04-05 19:35:35 +04:00
|
|
|
let of_path_exn = function
|
|
|
|
| "ed25519" :: q -> Ed25519 (Ed25519.Public_key_hash.of_path_exn q)
|
|
|
|
| "secp256k1" :: q -> Secp256k1 (Secp256k1.Public_key_hash.of_path_exn q)
|
2018-06-05 21:27:58 +04:00
|
|
|
| "p256" :: q -> P256 (P256.Public_key_hash.of_path_exn q)
|
2018-04-05 19:35:35 +04:00
|
|
|
| _ -> assert false (* FIXME classification des erreurs *)
|
|
|
|
|
|
|
|
let path_length =
|
|
|
|
let l1 = Ed25519.Public_key_hash.path_length
|
|
|
|
and l2 = Secp256k1.Public_key_hash.path_length in
|
|
|
|
assert Compare.Int.(l1 = l2) ;
|
|
|
|
1 + l1
|
|
|
|
|
|
|
|
let prefix_path _ = assert false (* unused *)
|
|
|
|
|
|
|
|
let hash = Hashtbl.hash
|
|
|
|
|
|
|
|
include Compare.Make(struct
|
|
|
|
type nonrec t = t
|
|
|
|
let compare a b =
|
|
|
|
match (a, b) with
|
|
|
|
| Ed25519 x, Ed25519 y ->
|
|
|
|
Ed25519.Public_key_hash.compare x y
|
|
|
|
| Secp256k1 x, Secp256k1 y ->
|
|
|
|
Secp256k1.Public_key_hash.compare x y
|
2018-06-05 21:27:58 +04:00
|
|
|
| P256 x, P256 y ->
|
|
|
|
P256.Public_key_hash.compare x y
|
|
|
|
| _ -> Pervasives.compare a b
|
2018-04-05 19:35:35 +04:00
|
|
|
end)
|
|
|
|
|
|
|
|
include Helpers.MakeEncoder(struct
|
|
|
|
type nonrec t = t
|
|
|
|
let name = name
|
|
|
|
let title = title
|
|
|
|
let raw_encoding = raw_encoding
|
|
|
|
let of_b58check = of_b58check
|
|
|
|
let of_b58check_opt = of_b58check_opt
|
|
|
|
let of_b58check_exn = of_b58check_exn
|
|
|
|
let to_b58check = to_b58check
|
|
|
|
let to_short_b58check = to_short_b58check
|
|
|
|
end)
|
|
|
|
|
|
|
|
include Helpers.MakeIterator(struct
|
|
|
|
type nonrec t = t
|
|
|
|
let hash = hash
|
|
|
|
let compare = compare
|
|
|
|
let equal = equal
|
|
|
|
let encoding = encoding
|
|
|
|
end)
|
|
|
|
|
2018-04-22 02:43:07 +04:00
|
|
|
let rpc_arg =
|
|
|
|
RPC_arg.like
|
|
|
|
rpc_arg
|
|
|
|
~descr:"A Secp256k1 of a Ed25519 public key hash (Base58Check-encoded)"
|
|
|
|
"pkh"
|
|
|
|
|
2018-04-05 19:35:35 +04:00
|
|
|
end
|
|
|
|
|
|
|
|
module Public_key = struct
|
|
|
|
|
|
|
|
type t = public_key =
|
|
|
|
| Ed25519 of Ed25519.Public_key.t
|
|
|
|
| Secp256k1 of Secp256k1.Public_key.t
|
2018-06-05 21:27:58 +04:00
|
|
|
| P256 of P256.Public_key.t
|
2018-04-05 19:35:35 +04:00
|
|
|
|
|
|
|
let name = "Signature.Public_key"
|
2018-06-05 21:27:58 +04:00
|
|
|
let title = "A Ed25519, Secp256k1, or P256 public key"
|
2018-04-05 19:35:35 +04:00
|
|
|
|
|
|
|
let hash pk =
|
|
|
|
match pk with
|
|
|
|
| Ed25519 pk -> Public_key_hash.Ed25519 (Ed25519.Public_key.hash pk)
|
|
|
|
| Secp256k1 pk -> Public_key_hash.Secp256k1 (Secp256k1.Public_key.hash pk)
|
2018-06-05 21:27:58 +04:00
|
|
|
| P256 pk -> Public_key_hash.P256 (P256.Public_key.hash pk)
|
2018-04-05 19:35:35 +04:00
|
|
|
|
|
|
|
include Compare.Make(struct
|
|
|
|
type nonrec t = t
|
|
|
|
let compare a b = match (a, b) with
|
2018-06-05 21:27:58 +04:00
|
|
|
| Ed25519 x, Ed25519 y -> Ed25519.Public_key.compare x y
|
|
|
|
| Secp256k1 x, Secp256k1 y -> Secp256k1.Public_key.compare x y
|
|
|
|
| P256 x, P256 y -> P256.Public_key.compare x y
|
|
|
|
| _ -> Pervasives.compare a b
|
2018-04-05 19:35:35 +04:00
|
|
|
end)
|
|
|
|
|
|
|
|
type Base58.data += Data of t (* unused *)
|
|
|
|
let b58check_encoding = (* unused *)
|
|
|
|
Base58.register_encoding
|
|
|
|
~prefix: "\255\255"
|
|
|
|
~length: 2
|
|
|
|
~to_raw: (fun _ -> assert false)
|
|
|
|
~of_raw: (fun _ -> assert false)
|
|
|
|
~wrap: (fun x -> Data x)
|
|
|
|
|
|
|
|
let of_b58check_opt s =
|
|
|
|
match Base58.decode s with
|
|
|
|
| Some (Ed25519.Public_key.Data public_key) -> Some (Ed25519 public_key)
|
|
|
|
| Some (Secp256k1.Public_key.Data public_key) -> Some (Secp256k1 public_key)
|
2018-06-05 21:27:58 +04:00
|
|
|
| Some (P256.Public_key.Data public_key) -> Some (P256 public_key)
|
2018-04-05 19:35:35 +04:00
|
|
|
| _ -> None
|
|
|
|
|
|
|
|
let of_b58check_exn s =
|
|
|
|
match of_b58check_opt s with
|
|
|
|
| Some x -> x
|
|
|
|
| None -> Format.kasprintf Pervasives.failwith "Unexpected data (%s)" name
|
|
|
|
let of_b58check s =
|
|
|
|
match of_b58check_opt s with
|
|
|
|
| Some x -> Ok x
|
|
|
|
| None ->
|
|
|
|
generic_error
|
|
|
|
"Failed to read a b58check_encoding data (%s): %S"
|
|
|
|
name s
|
|
|
|
|
|
|
|
let to_b58check = function
|
|
|
|
| Ed25519 pk -> Ed25519.Public_key.to_b58check pk
|
|
|
|
| Secp256k1 pk -> Secp256k1.Public_key.to_b58check pk
|
2018-06-05 21:27:58 +04:00
|
|
|
| P256 pk -> P256.Public_key.to_b58check pk
|
2018-04-05 19:35:35 +04:00
|
|
|
|
|
|
|
let to_short_b58check = function
|
|
|
|
| Ed25519 pk -> Ed25519.Public_key.to_short_b58check pk
|
|
|
|
| Secp256k1 pk -> Secp256k1.Public_key.to_short_b58check pk
|
2018-06-05 21:27:58 +04:00
|
|
|
| P256 pk -> P256.Public_key.to_short_b58check pk
|
2018-04-05 19:35:35 +04:00
|
|
|
|
|
|
|
include Helpers.MakeEncoder(struct
|
|
|
|
type nonrec t = t
|
|
|
|
let name = name
|
|
|
|
let title = title
|
|
|
|
let raw_encoding =
|
|
|
|
let open Data_encoding in
|
2018-05-29 16:57:59 +04:00
|
|
|
def "public_key" ~description:title @@
|
2018-04-05 19:35:35 +04:00
|
|
|
union [
|
|
|
|
case (Tag 0) Ed25519.Public_key.encoding
|
2018-06-01 01:19:43 +04:00
|
|
|
~title:"Ed25519"
|
2018-04-05 19:35:35 +04:00
|
|
|
(function Ed25519 x -> Some x | _ -> None)
|
|
|
|
(function x -> Ed25519 x);
|
|
|
|
case (Tag 1) Secp256k1.Public_key.encoding
|
2018-06-01 01:19:43 +04:00
|
|
|
~title:"Secp256k1"
|
2018-04-05 19:35:35 +04:00
|
|
|
(function Secp256k1 x -> Some x | _ -> None)
|
2018-06-05 21:27:58 +04:00
|
|
|
(function x -> Secp256k1 x) ;
|
|
|
|
case
|
|
|
|
~title:"P256" (Tag 2) P256.Public_key.encoding
|
|
|
|
(function P256 x -> Some x | _ -> None)
|
|
|
|
(function x -> P256 x)
|
2018-04-05 19:35:35 +04:00
|
|
|
]
|
|
|
|
let of_b58check = of_b58check
|
|
|
|
let of_b58check_opt = of_b58check_opt
|
|
|
|
let of_b58check_exn = of_b58check_exn
|
|
|
|
let to_b58check = to_b58check
|
|
|
|
let to_short_b58check = to_short_b58check
|
|
|
|
end)
|
|
|
|
|
|
|
|
let pp ppf t = Format.fprintf ppf "%s" (to_b58check t)
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
module Secret_key = struct
|
|
|
|
|
|
|
|
type t = secret_key =
|
|
|
|
| Ed25519 of Ed25519.Secret_key.t
|
|
|
|
| Secp256k1 of Secp256k1.Secret_key.t
|
2018-06-05 21:27:58 +04:00
|
|
|
| P256 of P256.Secret_key.t
|
2018-04-05 19:35:35 +04:00
|
|
|
|
|
|
|
let name = "Signature.Secret_key"
|
2018-06-05 21:27:58 +04:00
|
|
|
let title = "A Ed25519, Secp256k1 or P256 secret key"
|
2018-04-05 19:35:35 +04:00
|
|
|
|
|
|
|
let to_public_key = function
|
|
|
|
| Ed25519 sk -> Public_key.Ed25519 (Ed25519.Secret_key.to_public_key sk)
|
|
|
|
| Secp256k1 sk -> Public_key.Secp256k1 (Secp256k1.Secret_key.to_public_key sk)
|
2018-06-05 21:27:58 +04:00
|
|
|
| P256 sk -> Public_key.P256 (P256.Secret_key.to_public_key sk)
|
2018-04-05 19:35:35 +04:00
|
|
|
|
|
|
|
include Compare.Make(struct
|
|
|
|
type nonrec t = t
|
|
|
|
let compare a b = match (a, b) with
|
2018-06-05 21:27:58 +04:00
|
|
|
| Ed25519 x, Ed25519 y -> Ed25519.Secret_key.compare x y
|
|
|
|
| Secp256k1 x, Secp256k1 y -> Secp256k1.Secret_key.compare x y
|
|
|
|
| P256 x, P256 y -> P256.Secret_key.compare x y
|
|
|
|
| _ -> Pervasives.compare a b
|
2018-04-05 19:35:35 +04:00
|
|
|
end)
|
|
|
|
|
|
|
|
type Base58.data += Data of t (* unused *)
|
|
|
|
let b58check_encoding = (* unused *)
|
|
|
|
Base58.register_encoding
|
|
|
|
~prefix: "\255\255"
|
|
|
|
~length: 2
|
|
|
|
~to_raw: (fun _ -> assert false)
|
|
|
|
~of_raw: (fun _ -> assert false)
|
|
|
|
~wrap: (fun x -> Data x)
|
|
|
|
|
|
|
|
let of_b58check_opt b =
|
|
|
|
match Base58.decode b with
|
|
|
|
| Some (Ed25519.Secret_key.Data sk) -> Some (Ed25519 sk)
|
|
|
|
| Some (Secp256k1.Secret_key.Data sk) -> Some (Secp256k1 sk)
|
2018-06-05 21:27:58 +04:00
|
|
|
| Some (P256.Secret_key.Data sk) -> Some (P256 sk)
|
2018-04-05 19:35:35 +04:00
|
|
|
| _ -> None
|
|
|
|
|
|
|
|
let of_b58check_exn s =
|
|
|
|
match of_b58check_opt s with
|
|
|
|
| Some x -> x
|
|
|
|
| None -> Format.kasprintf Pervasives.failwith "Unexpected data (%s)" name
|
|
|
|
let of_b58check s =
|
|
|
|
match of_b58check_opt s with
|
|
|
|
| Some x -> Ok x
|
|
|
|
| None ->
|
|
|
|
generic_error
|
|
|
|
"Failed to read a b58check_encoding data (%s): %S"
|
|
|
|
name s
|
|
|
|
|
|
|
|
let to_b58check = function
|
|
|
|
| Ed25519 sk -> Ed25519.Secret_key.to_b58check sk
|
|
|
|
| Secp256k1 sk -> Secp256k1.Secret_key.to_b58check sk
|
2018-06-05 21:27:58 +04:00
|
|
|
| P256 sk -> P256.Secret_key.to_b58check sk
|
2018-04-05 19:35:35 +04:00
|
|
|
|
|
|
|
let to_short_b58check = function
|
|
|
|
| Ed25519 sk -> Ed25519.Secret_key.to_short_b58check sk
|
|
|
|
| Secp256k1 sk -> Secp256k1.Secret_key.to_short_b58check sk
|
2018-06-05 21:27:58 +04:00
|
|
|
| P256 sk -> P256.Secret_key.to_short_b58check sk
|
2018-04-05 19:35:35 +04:00
|
|
|
|
|
|
|
include Helpers.MakeEncoder(struct
|
|
|
|
type nonrec t = t
|
|
|
|
let name = name
|
|
|
|
let title = title
|
|
|
|
let raw_encoding =
|
|
|
|
let open Data_encoding in
|
2018-05-29 16:57:59 +04:00
|
|
|
def "secret_key" ~description:title @@
|
2018-04-05 19:35:35 +04:00
|
|
|
union [
|
|
|
|
case (Tag 0) Ed25519.Secret_key.encoding
|
2018-06-01 01:19:43 +04:00
|
|
|
~title:"Ed25519"
|
2018-04-05 19:35:35 +04:00
|
|
|
(function Ed25519 x -> Some x | _ -> None)
|
|
|
|
(function x -> Ed25519 x);
|
|
|
|
case (Tag 1) Secp256k1.Secret_key.encoding
|
2018-06-01 01:19:43 +04:00
|
|
|
~title:"Secp256k1"
|
2018-04-05 19:35:35 +04:00
|
|
|
(function Secp256k1 x -> Some x | _ -> None)
|
2018-06-05 21:27:58 +04:00
|
|
|
(function x -> Secp256k1 x) ;
|
|
|
|
case (Tag 2)
|
|
|
|
~title:"P256" P256.Secret_key.encoding
|
|
|
|
(function P256 x -> Some x | _ -> None)
|
|
|
|
(function x -> P256 x)
|
2018-04-05 19:35:35 +04:00
|
|
|
]
|
|
|
|
let of_b58check = of_b58check
|
|
|
|
let of_b58check_opt = of_b58check_opt
|
|
|
|
let of_b58check_exn = of_b58check_exn
|
|
|
|
let to_b58check = to_b58check
|
|
|
|
let to_short_b58check = to_short_b58check
|
|
|
|
end)
|
|
|
|
|
|
|
|
let pp ppf t = Format.fprintf ppf "%s" (to_b58check t)
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
type t =
|
|
|
|
| Ed25519 of Ed25519.t
|
|
|
|
| Secp256k1 of Secp256k1.t
|
2018-06-05 21:27:58 +04:00
|
|
|
| P256 of P256.t
|
2018-04-05 19:35:35 +04:00
|
|
|
| Unknown of MBytes.t
|
|
|
|
|
|
|
|
let name = "Signature"
|
2018-06-05 21:27:58 +04:00
|
|
|
let title = "A Ed25519, Secp256k1 or P256 signature"
|
2018-04-05 19:35:35 +04:00
|
|
|
|
2018-06-05 21:27:58 +04:00
|
|
|
let size =
|
|
|
|
assert (Ed25519.size = Secp256k1.size && Secp256k1.size = P256.size) ;
|
|
|
|
Ed25519.size
|
2018-04-05 19:35:35 +04:00
|
|
|
|
|
|
|
let to_bytes = function
|
|
|
|
| Ed25519 b -> Ed25519.to_bytes b
|
|
|
|
| Secp256k1 b -> Secp256k1.to_bytes b
|
2018-06-05 21:27:58 +04:00
|
|
|
| P256 b -> P256.to_bytes b
|
|
|
|
| Unknown b -> b
|
2018-04-05 19:35:35 +04:00
|
|
|
|
|
|
|
let of_bytes_opt s =
|
|
|
|
if MBytes.length s = size then Some (Unknown s) else None
|
|
|
|
|
|
|
|
let to_string s = MBytes.to_string (to_bytes s)
|
|
|
|
let of_string_opt s = of_bytes_opt (MBytes.of_string s)
|
|
|
|
|
|
|
|
type Base58.data += Data of t
|
|
|
|
let b58check_encoding =
|
|
|
|
Base58.register_encoding
|
2018-04-18 11:34:00 +04:00
|
|
|
~prefix: Base58.Prefix.generic_signature
|
|
|
|
~length: Ed25519.size
|
2018-04-05 19:35:35 +04:00
|
|
|
~to_raw: to_string
|
|
|
|
~of_raw: of_string_opt
|
|
|
|
~wrap: (fun x -> Data x)
|
|
|
|
|
2018-04-18 11:34:00 +04:00
|
|
|
let () =
|
|
|
|
Base58.check_encoded_prefix b58check_encoding "sig" 96
|
|
|
|
|
2018-04-05 19:35:35 +04:00
|
|
|
include Helpers.MakeRaw(struct
|
|
|
|
type nonrec t = t
|
|
|
|
let name = name
|
|
|
|
let of_bytes_opt = of_bytes_opt
|
|
|
|
let of_string_opt = of_string_opt
|
|
|
|
let to_string = to_string
|
|
|
|
end)
|
|
|
|
|
|
|
|
include Compare.Make(struct
|
|
|
|
type nonrec t = t
|
|
|
|
let compare a b =
|
|
|
|
let a = to_bytes a
|
|
|
|
and b = to_bytes b in
|
|
|
|
MBytes.compare a b
|
|
|
|
end)
|
|
|
|
|
|
|
|
let of_b58check_opt s =
|
|
|
|
if TzString.has_prefix ~prefix:Ed25519.b58check_encoding.encoded_prefix s then
|
|
|
|
Option.map
|
|
|
|
(Ed25519.of_b58check_opt s)
|
|
|
|
~f: (fun x -> Ed25519 x)
|
|
|
|
else if TzString.has_prefix ~prefix:Secp256k1.b58check_encoding.encoded_prefix s then
|
|
|
|
Option.map
|
|
|
|
(Secp256k1.of_b58check_opt s)
|
|
|
|
~f: (fun x -> Secp256k1 x)
|
2018-06-05 21:27:58 +04:00
|
|
|
else if TzString.has_prefix ~prefix:P256.b58check_encoding.encoded_prefix s then
|
|
|
|
Option.map
|
|
|
|
(P256.of_b58check_opt s)
|
|
|
|
~f: (fun x -> P256 x)
|
2018-04-05 19:35:35 +04:00
|
|
|
else
|
|
|
|
Base58.simple_decode b58check_encoding s
|
|
|
|
|
|
|
|
let of_b58check_exn s =
|
|
|
|
match of_b58check_opt s with
|
|
|
|
| Some x -> x
|
|
|
|
| None -> Format.kasprintf Pervasives.failwith "Unexpected data (%s)" name
|
|
|
|
let of_b58check s =
|
|
|
|
match of_b58check_opt s with
|
|
|
|
| Some x -> Ok x
|
|
|
|
| None ->
|
|
|
|
generic_error
|
|
|
|
"Failed to read a b58check_encoding data (%s): %S"
|
|
|
|
name s
|
|
|
|
|
|
|
|
let to_b58check = function
|
|
|
|
| Ed25519 b -> Ed25519.to_b58check b
|
|
|
|
| Secp256k1 b -> Secp256k1.to_b58check b
|
2018-06-05 21:27:58 +04:00
|
|
|
| P256 b -> P256.to_b58check b
|
2018-04-05 19:35:35 +04:00
|
|
|
| Unknown b -> Base58.simple_encode b58check_encoding (Unknown b)
|
|
|
|
|
|
|
|
let to_short_b58check = function
|
|
|
|
| Ed25519 b -> Ed25519.to_short_b58check b
|
|
|
|
| Secp256k1 b -> Secp256k1.to_short_b58check b
|
2018-06-05 21:27:58 +04:00
|
|
|
| P256 b -> P256.to_short_b58check b
|
2018-04-05 19:35:35 +04:00
|
|
|
| Unknown b -> Base58.simple_encode b58check_encoding (Unknown b)
|
|
|
|
|
|
|
|
include Helpers.MakeEncoder(struct
|
|
|
|
type nonrec t = t
|
|
|
|
let name = name
|
|
|
|
let title = title
|
|
|
|
let raw_encoding =
|
|
|
|
Data_encoding.conv
|
|
|
|
to_bytes
|
|
|
|
of_bytes_exn
|
|
|
|
(Data_encoding.Fixed.bytes size)
|
|
|
|
let of_b58check = of_b58check
|
|
|
|
let of_b58check_opt = of_b58check_opt
|
|
|
|
let of_b58check_exn = of_b58check_exn
|
|
|
|
let to_b58check = to_b58check
|
|
|
|
let to_short_b58check = to_short_b58check
|
|
|
|
end)
|
|
|
|
|
|
|
|
let pp ppf t = Format.fprintf ppf "%s" (to_b58check t)
|
|
|
|
|
|
|
|
let of_ed25519 s = Ed25519 s
|
2018-06-05 21:27:58 +04:00
|
|
|
let of_secp256k1 s = Secp256k1 s
|
|
|
|
let of_p256 s = P256 s
|
2018-04-05 19:35:35 +04:00
|
|
|
|
|
|
|
let zero = of_ed25519 Ed25519.zero
|
|
|
|
|
2018-05-25 17:50:31 +04:00
|
|
|
let bytes_of_watermark = function
|
2018-06-27 19:00:24 +04:00
|
|
|
| Block_header chain_id -> MBytes.concat "" [ MBytes.of_string "\x01" ; Chain_id.to_bytes chain_id ]
|
|
|
|
| Endorsement chain_id -> MBytes.concat "" [ MBytes.of_string "\x02" ; Chain_id.to_bytes chain_id ]
|
2018-05-25 17:50:31 +04:00
|
|
|
| Generic_operation -> MBytes.of_string "\x03"
|
|
|
|
| Custom bytes -> bytes
|
2018-04-20 13:27:13 +04:00
|
|
|
|
2018-05-25 17:50:31 +04:00
|
|
|
let sign ?watermark secret_key message =
|
|
|
|
let watermark = Option.map ~f:bytes_of_watermark watermark in
|
2018-04-05 19:35:35 +04:00
|
|
|
match secret_key with
|
2018-05-25 17:50:31 +04:00
|
|
|
| Secret_key.Ed25519 sk -> of_ed25519 (Ed25519.sign ?watermark sk message)
|
2018-06-05 21:27:58 +04:00
|
|
|
| Secp256k1 sk -> of_secp256k1 (Secp256k1.sign ?watermark sk message)
|
|
|
|
| P256 sk -> of_p256 (P256.sign ?watermark sk message)
|
2018-04-05 19:35:35 +04:00
|
|
|
|
2018-05-25 17:50:31 +04:00
|
|
|
let check ?watermark public_key signature message =
|
|
|
|
let watermark = Option.map ~f:bytes_of_watermark watermark in
|
2018-04-05 19:35:35 +04:00
|
|
|
match public_key, signature with
|
|
|
|
| Public_key.Ed25519 pk, Unknown signature -> begin
|
|
|
|
match Ed25519.of_bytes_opt signature with
|
2018-05-25 17:50:31 +04:00
|
|
|
| Some s -> Ed25519.check ?watermark pk s message
|
2018-04-05 19:35:35 +04:00
|
|
|
| None -> false
|
|
|
|
end
|
|
|
|
| Public_key.Secp256k1 pk, Unknown signature -> begin
|
|
|
|
match Secp256k1.of_bytes_opt signature with
|
2018-05-25 17:50:31 +04:00
|
|
|
| Some s -> Secp256k1.check ?watermark pk s message
|
2018-04-05 19:35:35 +04:00
|
|
|
| None -> false
|
|
|
|
end
|
2018-06-05 21:27:58 +04:00
|
|
|
| Public_key.P256 pk, Unknown signature -> begin
|
|
|
|
match P256.of_bytes_opt signature with
|
|
|
|
| Some s -> P256.check ?watermark pk s message
|
|
|
|
| None -> false
|
|
|
|
end
|
2018-04-05 19:35:35 +04:00
|
|
|
| Public_key.Ed25519 pk, Ed25519 signature ->
|
2018-05-25 17:50:31 +04:00
|
|
|
Ed25519.check ?watermark pk signature message
|
2018-04-05 19:35:35 +04:00
|
|
|
| Public_key.Secp256k1 pk, Secp256k1 signature ->
|
2018-05-25 17:50:31 +04:00
|
|
|
Secp256k1.check ?watermark pk signature message
|
2018-06-05 21:27:58 +04:00
|
|
|
| Public_key.P256 pk, P256 signature ->
|
|
|
|
P256.check ?watermark pk signature message
|
|
|
|
| _ -> false
|
2018-04-05 19:35:35 +04:00
|
|
|
|
2018-05-25 17:50:31 +04:00
|
|
|
let append ?watermark sk msg =
|
|
|
|
MBytes.concat "" [msg; (to_bytes (sign ?watermark sk msg))]
|
2018-04-05 19:35:35 +04:00
|
|
|
|
|
|
|
let concat msg signature =
|
2018-05-10 13:12:19 +04:00
|
|
|
MBytes.concat "" [msg; (to_bytes signature)]
|
2018-04-05 19:35:35 +04:00
|
|
|
|
|
|
|
type algo =
|
|
|
|
| Ed25519
|
|
|
|
| Secp256k1
|
2018-06-05 21:27:58 +04:00
|
|
|
| P256
|
2018-04-05 19:35:35 +04:00
|
|
|
|
|
|
|
let algo_param () =
|
|
|
|
Clic.parameter
|
2018-06-05 21:27:58 +04:00
|
|
|
~autocomplete:(fun _ -> return [ "ed25519" ; "secp256k1" ; "p256"])
|
2018-04-05 19:35:35 +04:00
|
|
|
begin fun _ name ->
|
|
|
|
match name with
|
|
|
|
| "ed25519" -> return Ed25519
|
|
|
|
| "secp256k1" -> return Secp256k1
|
2018-06-05 21:27:58 +04:00
|
|
|
| "p256" -> return P256
|
2018-04-05 19:35:35 +04:00
|
|
|
| name ->
|
|
|
|
failwith
|
|
|
|
"Unknown signature algorithm (%s). \
|
2018-06-05 21:27:58 +04:00
|
|
|
Available: 'ed25519', 'secp256k1' or 'p256'"
|
2018-04-05 19:35:35 +04:00
|
|
|
name
|
|
|
|
end
|
|
|
|
|
|
|
|
let generate_key ?(algo = Ed25519) ?seed () =
|
2018-04-06 01:22:30 +04:00
|
|
|
match algo with
|
|
|
|
| Ed25519 ->
|
|
|
|
let pkh, pk, sk = Ed25519.generate_key ?seed () in
|
2018-04-05 19:35:35 +04:00
|
|
|
(Public_key_hash.Ed25519 pkh,
|
|
|
|
Public_key.Ed25519 pk, Secret_key.Ed25519 sk)
|
2018-06-05 21:27:58 +04:00
|
|
|
| Secp256k1 ->
|
|
|
|
let pkh, pk, sk = Secp256k1.generate_key ?seed () in
|
|
|
|
(Public_key_hash.Secp256k1 pkh,
|
|
|
|
Public_key.Secp256k1 pk, Secret_key.Secp256k1 sk)
|
|
|
|
| P256 ->
|
|
|
|
let pkh, pk, sk = P256.generate_key ?seed () in
|
|
|
|
(Public_key_hash.P256 pkh,
|
|
|
|
Public_key.P256 pk, Secret_key.P256 sk)
|