Crypto: add P256 cryptography

This commit is contained in:
Vincent Bernardoff 2018-06-05 19:27:58 +02:00 committed by Benjamin Canou
parent 7df49b62e1
commit 21823483a5
20 changed files with 476 additions and 78 deletions

View File

@ -300,217 +300,222 @@ opam:11:tezos-rpc:
variables:
package: tezos-rpc
opam:12:tezos-crypto:
opam:12:uecc:
<<: *opam_definition
variables:
package: uecc
opam:13:tezos-crypto:
<<: *opam_definition
variables:
package: tezos-crypto
opam:13:tezos-micheline:
opam:14:tezos-micheline:
<<: *opam_definition
variables:
package: tezos-micheline
opam:14:lmdb:
opam:15:lmdb:
<<: *opam_definition
variables:
package: lmdb
opam:15:pbkdf:
opam:16:pbkdf:
<<: *opam_definition
variables:
package: pbkdf
opam:16:ocplib-resto-cohttp:
opam:17:ocplib-resto-cohttp:
<<: *opam_definition
variables:
package: ocplib-resto-cohttp
opam:17:tezos-base:
opam:18:tezos-base:
<<: *opam_definition
variables:
package: tezos-base
opam:18:irmin-lmdb:
opam:19:irmin-lmdb:
<<: *opam_definition
variables:
package: irmin-lmdb
opam:19:bip39:
opam:20:bip39:
<<: *opam_definition
variables:
package: bip39
opam:20:tezos-rpc-http:
opam:21:tezos-rpc-http:
<<: *opam_definition
variables:
package: tezos-rpc-http
opam:21:tezos-shell-services:
opam:22:tezos-shell-services:
<<: *opam_definition
variables:
package: tezos-shell-services
opam:22:tezos-stdlib-unix:
opam:23:tezos-stdlib-unix:
<<: *opam_definition
variables:
package: tezos-stdlib-unix
opam:23:tezos-storage:
opam:24:tezos-storage:
<<: *opam_definition
variables:
package: tezos-storage
opam:24:tezos-protocol-environment-sigs:
opam:25:tezos-protocol-environment-sigs:
<<: *opam_definition
variables:
package: tezos-protocol-environment-sigs
opam:25:tezos-client-base:
opam:26:tezos-client-base:
<<: *opam_definition
variables:
package: tezos-client-base
opam:26:tezos-protocol-compiler:
opam:27:tezos-protocol-compiler:
<<: *opam_definition
variables:
package: tezos-protocol-compiler
opam:27:tezos-signer-services:
opam:28:tezos-signer-services:
<<: *opam_definition
variables:
package: tezos-signer-services
opam:28:tezos-protocol-alpha:
opam:29:tezos-protocol-alpha:
<<: *opam_definition
variables:
package: tezos-protocol-alpha
opam:29:tezos-protocol-environment:
opam:30:tezos-protocol-environment:
<<: *opam_definition
variables:
package: tezos-protocol-environment
opam:30:tezos-signer-backends:
opam:31:tezos-signer-backends:
<<: *opam_definition
variables:
package: tezos-signer-backends
opam:31:tezos-client-alpha:
opam:32:tezos-client-alpha:
<<: *opam_definition
variables:
package: tezos-client-alpha
opam:32:tezos-client-commands:
opam:33:tezos-client-commands:
<<: *opam_definition
variables:
package: tezos-client-commands
opam:33:tezos-protocol-environment-shell:
opam:34:tezos-protocol-environment-shell:
<<: *opam_definition
variables:
package: tezos-protocol-environment-shell
opam:34:tezos-baking-alpha:
opam:35:tezos-baking-alpha:
<<: *opam_definition
variables:
package: tezos-baking-alpha
opam:35:tezos-protocol-genesis:
opam:36:tezos-protocol-genesis:
<<: *opam_definition
variables:
package: tezos-protocol-genesis
opam:36:ocplib-resto-json:
opam:37:ocplib-resto-json:
<<: *opam_definition
variables:
package: ocplib-resto-json
opam:37:tezos-protocol-updater:
opam:38:tezos-protocol-updater:
<<: *opam_definition
variables:
package: tezos-protocol-updater
opam:38:tezos-p2p:
opam:39:tezos-p2p:
<<: *opam_definition
variables:
package: tezos-p2p
opam:39:tezos-baking-alpha-commands:
opam:40:tezos-baking-alpha-commands:
<<: *opam_definition
variables:
package: tezos-baking-alpha-commands
opam:40:tezos-client-alpha-commands:
opam:41:tezos-client-alpha-commands:
<<: *opam_definition
variables:
package: tezos-client-alpha-commands
opam:41:tezos-client-base-unix:
opam:42:tezos-client-base-unix:
<<: *opam_definition
variables:
package: tezos-client-base-unix
opam:42:tezos-client-genesis:
opam:43:tezos-client-genesis:
<<: *opam_definition
variables:
package: tezos-client-genesis
opam:43:ocplib-ezresto:
opam:44:ocplib-ezresto:
<<: *opam_definition
variables:
package: ocplib-ezresto
opam:44:tezos-embedded-protocol-alpha:
opam:45:tezos-embedded-protocol-alpha:
<<: *opam_definition
variables:
package: tezos-embedded-protocol-alpha
opam:45:tezos-embedded-protocol-demo:
opam:46:tezos-embedded-protocol-demo:
<<: *opam_definition
variables:
package: tezos-embedded-protocol-demo
opam:46:tezos-embedded-protocol-genesis:
opam:47:tezos-embedded-protocol-genesis:
<<: *opam_definition
variables:
package: tezos-embedded-protocol-genesis
opam:47:tezos-shell:
opam:48:tezos-shell:
<<: *opam_definition
variables:
package: tezos-shell
opam:48:tezos-client:
opam:49:tezos-client:
<<: *opam_definition
variables:
package: tezos-client
opam:49:ocplib-ezresto-directory:
opam:50:ocplib-ezresto-directory:
<<: *opam_definition
variables:
package: ocplib-ezresto-directory
opam:50:tezos-baker-alpha:
opam:51:tezos-baker-alpha:
<<: *opam_definition
variables:
package: tezos-baker-alpha
opam:51:tezos-protocol-demo:
opam:52:tezos-protocol-demo:
<<: *opam_definition
variables:
package: tezos-protocol-demo
opam:52:tezos-signer:
opam:53:tezos-signer:
<<: *opam_definition
variables:
package: tezos-signer
opam:53:tezos-node:
opam:54:tezos-node:
<<: *opam_definition
variables:
package: tezos-node
opam:54:ocplib-json-typed-browser:
opam:55:ocplib-json-typed-browser:
<<: *opam_definition
variables:
package: ocplib-json-typed-browser

View File

@ -28,10 +28,12 @@ key2=bar
key3=boo
key4=king
key5=queen
key6=p256
$client gen keys $key1
$client gen keys $key2 --sig secp256k1
$client gen keys $key3 --sig ed25519
$client gen keys $key6 --sig p256
$client list known identities
$client get balance for bootstrap1
@ -39,10 +41,12 @@ $client get balance for bootstrap1
bake_after $client transfer 1,000 from bootstrap1 to $key1
bake_after $client transfer 2,000 from bootstrap1 to $key2
bake_after $client transfer 3,000 from bootstrap1 to $key3
bake_after $client transfer 4,000 from bootstrap1 to $key6
$client get balance for $key1 | assert "1,000 ꜩ"
$client get balance for $key2 | assert "2,000 ꜩ"
$client get balance for $key3 | assert "3,000 ꜩ"
$client get balance for $key6 | assert "4,000 ꜩ"
bake_after $client transfer 1,000 from $key2 to $key1 -fee 0
$client get balance for $key1 | assert "2,000 ꜩ"

View File

@ -29,7 +29,7 @@ let sig_algo_arg =
~doc:"use custom signature algorithm"
~long:"sig"
~short:'s'
~placeholder:"ed25519|secp256k1"
~placeholder:"ed25519|secp256k1|p256"
~default: "ed25519"
(Signature.algo_param ())

View File

@ -308,9 +308,8 @@ module Prefix = struct
(* 20 *)
let ed25519_public_key_hash = "\006\161\159" (* tz1(36) *)
(* 20 *)
let secp256k1_public_key_hash = "\006\161\161" (* tz2(36) *)
let p256_public_key_hash = "\006\161\164" (* tz3(36) *)
(* 16 *)
let cryptobox_public_key_hash = "\153\103" (* id(30) *)
@ -319,14 +318,17 @@ module Prefix = struct
let ed25519_seed = "\013\015\058\007" (* edsk(54) *)
let ed25519_public_key = "\013\015\037\217" (* edpk(54) *)
let secp256k1_secret_key = "\017\162\224\201" (* spsk(54) *)
let p256_secret_key = "\016\081\238\189" (* p2sk(54) *)
(* 33 *)
let secp256k1_public_key = "\003\254\226\086" (* sppk(55) *)
let p256_public_key = "\003\178\139\127" (* p2pk(55) *)
(* 64 *)
let ed25519_secret_key = "\043\246\078\007" (* edsk(98) *)
let ed25519_signature = "\009\245\205\134\018" (* edsig(99) *)
let secp256k1_signature = "\013\115\101\019\063" (* spsig1(99) *)
let p256_signature = "\054\240\044\052" (* p2sig(98) *)
let generic_signature = "\004\130\043" (* sig(96) *)
(* 4 *)

View File

@ -19,6 +19,7 @@ module Prefix : sig
val context_hash: string
val ed25519_public_key_hash: string
val secp256k1_public_key_hash: string
val p256_public_key_hash: string
val cryptobox_public_key_hash: string
val ed25519_seed: string
val ed25519_public_key: string
@ -27,6 +28,9 @@ module Prefix : sig
val secp256k1_public_key: string
val secp256k1_secret_key: string
val secp256k1_signature: string
val p256_public_key: string
val p256_secret_key: string
val p256_signature: string
val generic_signature: string
val chain_id: string

View File

@ -18,6 +18,7 @@
blake2
hacl
secp256k1
uecc
zarith))))
(alias

266
src/lib_crypto/p256.ml Normal file
View File

@ -0,0 +1,266 @@
(**************************************************************************)
(* *)
(* Copyright (c) 2014 - 2018. *)
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
(* *)
(* All rights reserved. No warranty, explicit or implicit, provided. *)
(* *)
(**************************************************************************)
module Public_key_hash = Blake2B.Make(Base58)(struct
let name = "P256.Public_key_hash"
let title = "A P256 public key hash"
let b58check_prefix = Base58.Prefix.p256_public_key_hash
let size = Some 20
end)
let () =
Base58.check_encoded_prefix Public_key_hash.b58check_encoding "tz3" 36
open Uecc
module Public_key = struct
type t = (secp256r1, public) key
let name = "P256.Public_key"
let title = "A P256 public key"
let to_bytes = to_bytes ~compress:true
let of_bytes_opt = pk_of_bytes secp256r1
let to_string s = MBytes.to_string (to_bytes s)
let of_string_opt s = of_bytes_opt (MBytes.of_string s)
let size = compressed_size secp256r1
type Base58.data +=
| Data of t
let b58check_encoding =
Base58.register_encoding
~prefix: Base58.Prefix.p256_public_key
~length: size
~to_raw: to_string
~of_raw: of_string_opt
~wrap: (fun x -> Data x)
let () =
Base58.check_encoded_prefix b58check_encoding "p2pk" 55
let hash v =
Public_key_hash.hash_bytes [to_bytes v]
include Compare.Make(struct
type nonrec t = t
let compare a b =
MBytes.compare (to_bytes a) (to_bytes b)
end)
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 Helpers.MakeB58(struct
type nonrec t = t
let title = title
let name = name
let b58check_encoding = b58check_encoding
end)
include Helpers.MakeEncoder(struct
type nonrec t = t
let name = name
let title = title
let raw_encoding =
let open Data_encoding in
conv to_bytes of_bytes_exn (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)
end
module Secret_key = struct
type t = (secp256r1, secret) key
let name = "P256.Secret_key"
let title = "A P256 secret key"
let size = sk_size secp256r1
let of_bytes_opt buf =
Option.map ~f:fst (sk_of_bytes secp256r1 buf)
let to_bytes = to_bytes ~compress:true
let to_string s = MBytes.to_string (to_bytes s)
let of_string_opt s = of_bytes_opt (MBytes.of_string s)
let to_public_key = neuterize
type Base58.data +=
| Data of t
let b58check_encoding =
Base58.register_encoding
~prefix: Base58.Prefix.p256_secret_key
~length: size
~to_raw: to_string
~of_raw: of_string_opt
~wrap: (fun x -> Data x)
let () =
Base58.check_encoded_prefix b58check_encoding "p2sk" 54
include Compare.Make(struct
type nonrec t = t
let compare a b =
MBytes.compare (to_bytes a) (to_bytes b)
end)
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 Helpers.MakeB58(struct
type nonrec t = t
let title = title
let name = name
let b58check_encoding = b58check_encoding
end)
include Helpers.MakeEncoder(struct
type nonrec t = t
let name = name
let title = title
let raw_encoding =
let open Data_encoding in
conv to_bytes of_bytes_exn (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)
end
type t = MBytes.t
type watermark = MBytes.t
let name = "P256"
let title = "A P256 signature"
let size = pk_size secp256r1
let of_bytes_opt s =
if MBytes.length s = size then Some s else None
let to_bytes s = s
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
~prefix: Base58.Prefix.p256_signature
~length: size
~to_raw: to_string
~of_raw: of_string_opt
~wrap: (fun x -> Data x)
let () =
Base58.check_encoded_prefix b58check_encoding "p2sig" 98
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 Helpers.MakeB58(struct
type nonrec t = t
let title = title
let name = name
let b58check_encoding = b58check_encoding
end)
include Helpers.MakeEncoder(struct
type nonrec t = t
let name = name
let title = title
let raw_encoding =
let open Data_encoding in
conv to_bytes of_bytes_exn (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 zero = of_bytes_exn (MBytes.make size '\000')
let sign ?watermark sk msg =
let msg =
Blake2B.to_bytes @@
Blake2B.hash_bytes @@
match watermark with
| None -> [msg]
| Some prefix -> [ prefix ; msg ] in
match sign sk msg with
| None ->
(* Will never happen in practice. This can only happen in case
of RNG error. *)
invalid_arg "P256.sign: internal error"
| Some signature -> signature
let check ?watermark public_key signature msg =
let msg =
Blake2B.to_bytes @@
Blake2B.hash_bytes @@
match watermark with
| None -> [msg]
| Some prefix -> [ prefix ; msg ] in
verify public_key ~msg ~signature
let generate_key ?(seed=Rand.generate 32) () =
let seedlen = MBytes.length seed in
if seedlen < 32 then
invalid_arg (Printf.sprintf "P256.generate_key: seed must be at \
least 32 bytes long (was %d)" seedlen) ;
match sk_of_bytes secp256r1 seed with
| None -> invalid_arg "P256.generate_key: invalid seed (very rare!)"
| Some (sk, pk) ->
let pkh = Public_key.hash pk in
pkh, pk, sk
include Compare.Make(struct
type nonrec t = t
let compare = MBytes.compare
end)

13
src/lib_crypto/p256.mli Normal file
View File

@ -0,0 +1,13 @@
(**************************************************************************)
(* *)
(* Copyright (c) 2014 - 2018. *)
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
(* *)
(* All rights reserved. No warranty, explicit or implicit, provided. *)
(* *)
(**************************************************************************)
(** Tezos - P256 cryptography *)
include S.SIGNATURE with type watermark = MBytes.t
include S.RAW_DATA with type t := t

View File

@ -62,7 +62,7 @@ module Public_key = struct
include Compare.Make(struct
type nonrec t = t
let compare a b =
MBytes.compare (Key.buffer a) (Key.buffer b)
MBytes.compare (to_bytes a) (to_bytes b)
end)
include Helpers.MakeRaw(struct
@ -264,4 +264,3 @@ let generate_key ?(seed=Rand.generate 32) () =
let pk = Key.neuterize_exn context sk in
let pkh = Public_key.hash pk in
pkh, pk, sk

View File

@ -12,14 +12,17 @@ open Error_monad
type public_key_hash =
| Ed25519 of Ed25519.Public_key_hash.t
| Secp256k1 of Secp256k1.Public_key_hash.t
| P256 of P256.Public_key_hash.t
type public_key =
| Ed25519 of Ed25519.Public_key.t
| Secp256k1 of Secp256k1.Public_key.t
| P256 of P256.Public_key.t
type secret_key =
| Ed25519 of Ed25519.Secret_key.t
| Secp256k1 of Secp256k1.Secret_key.t
| P256 of P256.Secret_key.t
type watermark =
| Block_header
@ -32,9 +35,10 @@ module Public_key_hash = struct
type t = public_key_hash =
| Ed25519 of Ed25519.Public_key_hash.t
| Secp256k1 of Secp256k1.Public_key_hash.t
| P256 of P256.Public_key_hash.t
let name = "Signature.Public_key_hash"
let title = "A Secp256k1 or Ed25519 public key hash"
let title = "A Ed25519, Secp256k1, or P256 public key hash"
type Base58.data += Data of t (* unused *)
let b58check_encoding = (* unused *)
@ -56,7 +60,11 @@ module Public_key_hash = struct
case (Tag 1) Secp256k1.Public_key_hash.encoding
~title:"Secp256k1"
(function Secp256k1 x -> Some x | _ -> None)
(function x -> Secp256k1 x)
(function x -> Secp256k1 x) ;
case (Tag 2)
~title:"P256" P256.Public_key_hash.encoding
(function P256 x -> Some x | _ -> None)
(function x -> P256 x)
]
let to_bytes s =
@ -82,6 +90,7 @@ module Public_key_hash = struct
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)
| Some P256.Public_key_hash.Data pkh -> Some (P256 pkh)
| _ -> None
let of_b58check_exn s =
@ -99,14 +108,17 @@ module Public_key_hash = struct
let to_b58check = function
| Ed25519 pkh -> Ed25519.Public_key_hash.to_b58check pkh
| Secp256k1 pkh -> Secp256k1.Public_key_hash.to_b58check pkh
| P256 pkh -> P256.Public_key_hash.to_b58check pkh
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
| P256 pkh -> P256.Public_key_hash.to_short_b58check pkh
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
| P256 h -> "p256" :: P256.Public_key_hash.to_path h l
let of_path = function
| "ed25519" :: q -> begin
@ -119,10 +131,17 @@ module Public_key_hash = struct
| Some pkh -> Some (Secp256k1 pkh)
| None -> None
end
| "p256" :: q -> begin
match P256.Public_key_hash.of_path q with
| Some pkh -> Some (P256 pkh)
| None -> None
end
| _ -> assert false (* FIXME classification des erreurs *)
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)
| "p256" :: q -> P256 (P256.Public_key_hash.of_path_exn q)
| _ -> assert false (* FIXME classification des erreurs *)
let path_length =
@ -139,12 +158,13 @@ module Public_key_hash = struct
type nonrec t = t
let compare a b =
match (a, b) with
| Ed25519 _ , Secp256k1 _ -> 1
| Secp256k1 _, Ed25519 _ -> -1
| Ed25519 x, Ed25519 y ->
Ed25519.Public_key_hash.compare x y
| Secp256k1 x, Secp256k1 y ->
Secp256k1.Public_key_hash.compare x y
| P256 x, P256 y ->
P256.Public_key_hash.compare x y
| _ -> Pervasives.compare a b
end)
include Helpers.MakeEncoder(struct
@ -180,22 +200,24 @@ module Public_key = struct
type t = public_key =
| Ed25519 of Ed25519.Public_key.t
| Secp256k1 of Secp256k1.Public_key.t
| P256 of P256.Public_key.t
let name = "Signature.Public_key"
let title = "A Secp256k1 or Ed25519 public key"
let title = "A Ed25519, Secp256k1, or P256 public key"
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)
| P256 pk -> Public_key_hash.P256 (P256.Public_key.hash pk)
include Compare.Make(struct
type nonrec t = t
let compare a b = match (a, b) with
| (Ed25519 _ , Secp256k1 _) -> 1
| (Secp256k1 _, Ed25519 _ ) -> -1
| (Ed25519 x, Ed25519 y) -> Ed25519.Public_key.compare x y
| (Secp256k1 x, Secp256k1 y) -> Secp256k1.Public_key.compare x y
| 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
end)
type Base58.data += Data of t (* unused *)
@ -211,6 +233,7 @@ module Public_key = struct
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)
| Some (P256.Public_key.Data public_key) -> Some (P256 public_key)
| _ -> None
let of_b58check_exn s =
@ -228,10 +251,12 @@ module Public_key = struct
let to_b58check = function
| Ed25519 pk -> Ed25519.Public_key.to_b58check pk
| Secp256k1 pk -> Secp256k1.Public_key.to_b58check pk
| P256 pk -> P256.Public_key.to_b58check pk
let to_short_b58check = function
| Ed25519 pk -> Ed25519.Public_key.to_short_b58check pk
| Secp256k1 pk -> Secp256k1.Public_key.to_short_b58check pk
| P256 pk -> P256.Public_key.to_short_b58check pk
include Helpers.MakeEncoder(struct
type nonrec t = t
@ -248,7 +273,11 @@ module Public_key = struct
case (Tag 1) Secp256k1.Public_key.encoding
~title:"Secp256k1"
(function Secp256k1 x -> Some x | _ -> None)
(function x -> Secp256k1 x)
(function x -> Secp256k1 x) ;
case
~title:"P256" (Tag 2) P256.Public_key.encoding
(function P256 x -> Some x | _ -> None)
(function x -> P256 x)
]
let of_b58check = of_b58check
let of_b58check_opt = of_b58check_opt
@ -266,21 +295,23 @@ module Secret_key = struct
type t = secret_key =
| Ed25519 of Ed25519.Secret_key.t
| Secp256k1 of Secp256k1.Secret_key.t
| P256 of P256.Secret_key.t
let name = "Signature.Secret_key"
let title = "A Secp256k1 or Ed25519 secret key"
let title = "A Ed25519, Secp256k1 or P256 secret key"
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)
| P256 sk -> Public_key.P256 (P256.Secret_key.to_public_key sk)
include Compare.Make(struct
type nonrec t = t
let compare a b = match (a, b) with
| (Ed25519 _ , Secp256k1 _) -> 1
| (Secp256k1 _, Ed25519 _ ) -> -1
| (Ed25519 x, Ed25519 y) -> Ed25519.Secret_key.compare x y
| (Secp256k1 x, Secp256k1 y) -> Secp256k1.Secret_key.compare x y
| 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
end)
type Base58.data += Data of t (* unused *)
@ -296,6 +327,7 @@ module Secret_key = struct
match Base58.decode b with
| Some (Ed25519.Secret_key.Data sk) -> Some (Ed25519 sk)
| Some (Secp256k1.Secret_key.Data sk) -> Some (Secp256k1 sk)
| Some (P256.Secret_key.Data sk) -> Some (P256 sk)
| _ -> None
let of_b58check_exn s =
@ -313,10 +345,12 @@ module Secret_key = struct
let to_b58check = function
| Ed25519 sk -> Ed25519.Secret_key.to_b58check sk
| Secp256k1 sk -> Secp256k1.Secret_key.to_b58check sk
| P256 sk -> P256.Secret_key.to_b58check sk
let to_short_b58check = function
| Ed25519 sk -> Ed25519.Secret_key.to_short_b58check sk
| Secp256k1 sk -> Secp256k1.Secret_key.to_short_b58check sk
| P256 sk -> P256.Secret_key.to_short_b58check sk
include Helpers.MakeEncoder(struct
type nonrec t = t
@ -333,7 +367,11 @@ module Secret_key = struct
case (Tag 1) Secp256k1.Secret_key.encoding
~title:"Secp256k1"
(function Secp256k1 x -> Some x | _ -> None)
(function x -> Secp256k1 x)
(function x -> Secp256k1 x) ;
case (Tag 2)
~title:"P256" P256.Secret_key.encoding
(function P256 x -> Some x | _ -> None)
(function x -> P256 x)
]
let of_b58check = of_b58check
let of_b58check_opt = of_b58check_opt
@ -349,18 +387,21 @@ end
type t =
| Ed25519 of Ed25519.t
| Secp256k1 of Secp256k1.t
| P256 of P256.t
| Unknown of MBytes.t
let name = "Signature"
let title = "A Secp256k1 or Ed25519 signature"
let title = "A Ed25519, Secp256k1 or P256 signature"
let () = assert (Ed25519.size = Secp256k1.size)
let size = Ed25519.size
let size =
assert (Ed25519.size = Secp256k1.size && Secp256k1.size = P256.size) ;
Ed25519.size
let to_bytes = function
| Unknown b -> b
| Ed25519 b -> Ed25519.to_bytes b
| Secp256k1 b -> Secp256k1.to_bytes b
| P256 b -> P256.to_bytes b
| Unknown b -> b
let of_bytes_opt s =
if MBytes.length s = size then Some (Unknown s) else None
@ -405,6 +446,10 @@ let of_b58check_opt s =
Option.map
(Secp256k1.of_b58check_opt s)
~f: (fun x -> Secp256k1 x)
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)
else
Base58.simple_decode b58check_encoding s
@ -423,11 +468,13 @@ let of_b58check s =
let to_b58check = function
| Ed25519 b -> Ed25519.to_b58check b
| Secp256k1 b -> Secp256k1.to_b58check b
| P256 b -> P256.to_b58check b
| 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
| P256 b -> P256.to_short_b58check b
| Unknown b -> Base58.simple_encode b58check_encoding (Unknown b)
include Helpers.MakeEncoder(struct
@ -448,8 +495,9 @@ include Helpers.MakeEncoder(struct
let pp ppf t = Format.fprintf ppf "%s" (to_b58check t)
let of_secp256k1 s = Secp256k1 s
let of_ed25519 s = Ed25519 s
let of_secp256k1 s = Secp256k1 s
let of_p256 s = P256 s
let zero = of_ed25519 Ed25519.zero
@ -463,7 +511,8 @@ let sign ?watermark secret_key message =
let watermark = Option.map ~f:bytes_of_watermark watermark in
match secret_key with
| Secret_key.Ed25519 sk -> of_ed25519 (Ed25519.sign ?watermark sk message)
| Secret_key.Secp256k1 sk -> of_secp256k1 (Secp256k1.sign ?watermark sk message)
| Secp256k1 sk -> of_secp256k1 (Secp256k1.sign ?watermark sk message)
| P256 sk -> of_p256 (P256.sign ?watermark sk message)
let check ?watermark public_key signature message =
let watermark = Option.map ~f:bytes_of_watermark watermark in
@ -478,12 +527,18 @@ let check ?watermark public_key signature message =
| Some s -> Secp256k1.check ?watermark pk s message
| None -> false
end
| 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
| Public_key.Ed25519 pk, Ed25519 signature ->
Ed25519.check ?watermark pk signature message
| Public_key.Secp256k1 pk, Secp256k1 signature ->
Secp256k1.check ?watermark pk signature message
| Public_key.Ed25519 _, Secp256k1 _ -> false
| Public_key.Secp256k1 _, Ed25519 _ -> false
| Public_key.P256 pk, P256 signature ->
P256.check ?watermark pk signature message
| _ -> false
let append ?watermark sk msg =
MBytes.concat "" [msg; (to_bytes (sign ?watermark sk msg))]
@ -494,28 +549,34 @@ let concat msg signature =
type algo =
| Ed25519
| Secp256k1
| P256
let algo_param () =
Clic.parameter
~autocomplete:(fun _ -> return [ "ed25519" ; "secp256k1" ])
~autocomplete:(fun _ -> return [ "ed25519" ; "secp256k1" ; "p256"])
begin fun _ name ->
match name with
| "ed25519" -> return Ed25519
| "secp256k1" -> return Secp256k1
| "p256" -> return P256
| name ->
failwith
"Unknown signature algorithm (%s). \
Available: 'ed25519' or 'secp256k1'"
Available: 'ed25519', 'secp256k1' or 'p256'"
name
end
let generate_key ?(algo = Ed25519) ?seed () =
match algo with
| Secp256k1 ->
let pkh, pk, sk = Secp256k1.generate_key ?seed () in
(Public_key_hash.Secp256k1 pkh,
Public_key.Secp256k1 pk, Secret_key.Secp256k1 sk)
| Ed25519 ->
let pkh, pk, sk = Ed25519.generate_key ?seed () in
(Public_key_hash.Ed25519 pkh,
Public_key.Ed25519 pk, Secret_key.Ed25519 sk)
| 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)

View File

@ -10,14 +10,17 @@
type public_key_hash =
| Ed25519 of Ed25519.Public_key_hash.t
| Secp256k1 of Secp256k1.Public_key_hash.t
| P256 of P256.Public_key_hash.t
type public_key =
| Ed25519 of Ed25519.Public_key.t
| Secp256k1 of Secp256k1.Public_key.t
| P256 of P256.Public_key.t
type secret_key =
| Ed25519 of Ed25519.Secret_key.t
| Secp256k1 of Secp256k1.Secret_key.t
| P256 of P256.Secret_key.t
type watermark =
| Block_header
@ -45,6 +48,7 @@ include S.RAW_DATA with type t := t
type algo =
| Ed25519
| Secp256k1
| P256
val algo_param: unit -> (algo, 'a) Clic.parameter

View File

@ -19,6 +19,7 @@ depends: [
"hacl"
"zarith"
"secp256k1"
"uecc"
"alcotest" { test & >= "0.8.3" }
]
build: [

View File

@ -41,6 +41,7 @@
v1/blake2B.mli
v1/ed25519.mli
v1/secp256k1.mli
v1/p256.mli
v1/signature.mli
v1/block_hash.mli
v1/operation_hash.mli

View File

@ -0,0 +1,12 @@
(**************************************************************************)
(* *)
(* Copyright (c) 2014 - 2018. *)
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
(* *)
(* All rights reserved. No warranty, explicit or implicit, provided. *)
(* *)
(**************************************************************************)
(** Tezos - P256 cryptography *)
include S.SIGNATURE with type watermark := MBytes.t

View File

@ -10,10 +10,12 @@
type public_key_hash =
| Ed25519 of Ed25519.Public_key_hash.t
| Secp256k1 of Secp256k1.Public_key_hash.t
| P256 of P256.Public_key_hash.t
type public_key =
| Ed25519 of Ed25519.Public_key.t
| Secp256k1 of Secp256k1.Public_key.t
| P256 of P256.Public_key.t
type watermark =
| Block_header

View File

@ -148,6 +148,9 @@ module Make (Context : CONTEXT) = struct
and type Secp256k1.Public_key_hash.t = Secp256k1.Public_key_hash.t
and type Secp256k1.Public_key.t = Secp256k1.Public_key.t
and type Secp256k1.t = Secp256k1.t
and type P256.Public_key_hash.t = P256.Public_key_hash.t
and type P256.Public_key.t = P256.Public_key.t
and type P256.t = P256.t
and type Signature.public_key_hash = Signature.public_key_hash
and type Signature.public_key = Signature.public_key
and type Signature.t = Signature.t
@ -232,6 +235,7 @@ module Make (Context : CONTEXT) = struct
module Time = Time
module Ed25519 = Ed25519
module Secp256k1 = Secp256k1
module P256 = P256
module Signature = Signature
module S = struct
module type T = Tezos_base.S.T

View File

@ -141,6 +141,9 @@ module Make (Context : CONTEXT) : sig
and type Secp256k1.Public_key_hash.t = Secp256k1.Public_key_hash.t
and type Secp256k1.Public_key.t = Secp256k1.Public_key.t
and type Secp256k1.t = Secp256k1.t
and type P256.Public_key_hash.t = P256.Public_key_hash.t
and type P256.Public_key.t = P256.Public_key.t
and type P256.t = P256.t
and type Signature.public_key_hash = Signature.public_key_hash
and type Signature.public_key = Signature.public_key
and type Signature.t = Signature.t

View File

@ -35,6 +35,7 @@ let of_b58check s =
match Base58.decode s with
| Some (Ed25519.Public_key_hash.Data h) -> ok (Implicit (Signature.Ed25519 h))
| Some (Secp256k1.Public_key_hash.Data h) -> ok (Implicit (Signature.Secp256k1 h))
| Some (P256.Public_key_hash.Data h) -> ok (Implicit (Signature.P256 h))
| Some (Contract_hash.Data h) -> ok (Originated h)
| _ -> error (Invalid_contract_notation s)
@ -184,6 +185,9 @@ module Index = struct
Ed25519.Public_key_hash.prefix_path s
let pkh_prefix_secp256k1 s =
Secp256k1.Public_key_hash.prefix_path s
let pkh_prefix_p256 s =
P256.Public_key_hash.prefix_path s
let rpc_arg = rpc_arg
let encoding = encoding
let compare = compare

View File

@ -65,4 +65,5 @@ module Index : sig
val contract_prefix: string -> string list
val pkh_prefix_ed25519: string -> string list
val pkh_prefix_secp256k1: string -> string list
val pkh_prefix_p256: string -> string list
end

View File

@ -536,4 +536,15 @@ let () =
| Contract_repr.Implicit (Secp256k1 pkh) -> pkh
| Contract_repr.Implicit _ -> assert false
| Contract_repr.Originated _ -> assert false)
l) ;
Raw_context.register_resolvers
P256.Public_key_hash.b58check_encoding
(fun ctxt p ->
let p = Contract_repr.Index.pkh_prefix_p256 p in
Contract.Indexed_context.resolve ctxt p >|= fun l ->
List.map
(function
| Contract_repr.Implicit (P256 pkh) -> pkh
| Contract_repr.Implicit _ -> assert false
| Contract_repr.Originated _ -> assert false)
l)