414 lines
14 KiB
OCaml
414 lines
14 KiB
OCaml
module Num = struct
|
|
type t = Cstruct.buffer
|
|
|
|
external size :
|
|
unit -> int = "sizeof_secp256k1_num" [@@noalloc]
|
|
external copy :
|
|
t -> t -> unit = "ml_secp256k1_num_copy" [@@noalloc]
|
|
external get_bin :
|
|
Cstruct.buffer -> int -> t -> unit = "ml_secp256k1_num_get_bin" [@@noalloc]
|
|
external set_bin :
|
|
t -> Cstruct.buffer -> int -> unit = "ml_secp256k1_num_set_bin" [@@noalloc]
|
|
external mod_inverse :
|
|
t -> t -> t -> unit = "ml_secp256k1_num_mod_inverse" [@@noalloc]
|
|
external jacobi :
|
|
t -> t -> int = "ml_secp256k1_num_jacobi" [@@noalloc]
|
|
external compare :
|
|
t -> t -> int = "ml_secp256k1_num_cmp" [@@noalloc]
|
|
external equal :
|
|
t -> t -> bool = "ml_secp256k1_num_eq" [@@noalloc]
|
|
external add :
|
|
t -> t -> t -> unit = "ml_secp256k1_num_add" [@@noalloc]
|
|
external sub :
|
|
t -> t -> t -> unit = "ml_secp256k1_num_sub" [@@noalloc]
|
|
external mul :
|
|
t -> t -> t -> unit = "ml_secp256k1_num_mul" [@@noalloc]
|
|
external modulo :
|
|
t -> t -> unit = "ml_secp256k1_num_mod" [@@noalloc]
|
|
external shift :
|
|
t -> int -> unit = "ml_secp256k1_num_shift" [@@noalloc]
|
|
external is_zero :
|
|
t -> bool = "ml_secp256k1_num_is_zero" [@@noalloc]
|
|
external is_one :
|
|
t -> bool = "ml_secp256k1_num_is_one" [@@noalloc]
|
|
external is_neg :
|
|
t -> bool = "ml_secp256k1_num_is_neg" [@@noalloc]
|
|
external negate :
|
|
t -> unit = "ml_secp256k1_num_negate" [@@noalloc]
|
|
|
|
let size = size ()
|
|
|
|
let get_bin cs =
|
|
Cstruct.(get_bin (to_bigarray cs) (len cs))
|
|
let set_bin r cs =
|
|
Cstruct.(set_bin r (to_bigarray cs) (len cs))
|
|
|
|
let of_uint16 i =
|
|
let t = Cstruct.create size in
|
|
let cs = Cstruct.create 2 in
|
|
Cstruct.BE.set_uint16 cs 0 i ;
|
|
set_bin t.buffer cs ;
|
|
t.buffer
|
|
|
|
let zero () = of_uint16 0
|
|
let one () = of_uint16 1
|
|
|
|
let of_uint32 i =
|
|
let t = Cstruct.create size in
|
|
let cs = Cstruct.create 4 in
|
|
Cstruct.BE.set_uint32 cs 0 i ;
|
|
set_bin t.buffer cs ;
|
|
t.buffer
|
|
|
|
let of_uint64 i =
|
|
let t = Cstruct.create size in
|
|
let cs = Cstruct.create 8 in
|
|
Cstruct.BE.set_uint64 cs 0 i ;
|
|
set_bin t.buffer cs ;
|
|
t.buffer
|
|
end
|
|
|
|
module Scalar = struct
|
|
type t = Cstruct.buffer
|
|
|
|
let size = 32
|
|
|
|
external const :
|
|
t -> int64 -> int64 -> int64 -> int64 -> int64 -> int64 -> int64 -> int64 -> unit =
|
|
"ml_secp256k1_fe_const_bytecode" "ml_secp256k1_fe_const" [@@noalloc]
|
|
|
|
let const ?(d7=0L) ?(d6=0L) ?(d5=0L) ?(d4=0L) ?(d3=0L) ?(d2=0L) ?(d1=0L) ?(d0=0L) () =
|
|
let buf = Cstruct.create size in
|
|
const buf.buffer d7 d6 d5 d4 d3 d2 d1 d0 ;
|
|
buf.buffer
|
|
|
|
let zero () = const ()
|
|
let one () = const ~d0:1L ()
|
|
let copy t =
|
|
let ret = Cstruct.create size in
|
|
Cstruct.(blit (of_bigarray t) 0 ret 0 size) ;
|
|
ret.buffer
|
|
|
|
external clear :
|
|
t -> unit = "ml_secp256k1_scalar_clear" [@@noalloc]
|
|
external get_bits :
|
|
t -> int -> int -> int = "ml_secp256k1_scalar_get_bits" [@@noalloc]
|
|
external get_bits_var :
|
|
t -> int -> int -> int = "ml_secp256k1_scalar_get_bits_var" [@@noalloc]
|
|
external set_b32 :
|
|
t -> Cstruct.buffer -> bool = "ml_secp256k1_scalar_set_b32" [@@noalloc]
|
|
external set_int :
|
|
Cstruct.buffer -> int -> unit = "ml_secp256k1_scalar_set_int" [@@noalloc]
|
|
external get_b32 :
|
|
Cstruct.buffer -> t -> unit = "ml_secp256k1_scalar_get_b32" [@@noalloc]
|
|
external add :
|
|
t -> t -> t -> bool = "ml_secp256k1_scalar_add" [@@noalloc]
|
|
external cadd_bit :
|
|
t -> int -> bool -> unit = "ml_secp256k1_scalar_cadd_bit" [@@noalloc]
|
|
external mul :
|
|
t -> t -> t -> unit = "ml_secp256k1_scalar_mul" [@@noalloc]
|
|
external shr_int :
|
|
t -> int -> int = "ml_secp256k1_scalar_shr_int" [@@noalloc]
|
|
external sqr :
|
|
t -> t -> unit = "ml_secp256k1_scalar_sqr" [@@noalloc]
|
|
external inverse :
|
|
t -> t -> unit = "ml_secp256k1_scalar_inverse" [@@noalloc]
|
|
external inverse_var :
|
|
t -> t -> unit = "ml_secp256k1_scalar_inverse_var" [@@noalloc]
|
|
external negate :
|
|
t -> t -> unit = "ml_secp256k1_scalar_negate" [@@noalloc]
|
|
external is_zero :
|
|
t -> bool = "ml_secp256k1_scalar_is_zero" [@@noalloc]
|
|
external is_one :
|
|
t -> bool = "ml_secp256k1_scalar_is_one" [@@noalloc]
|
|
external is_even :
|
|
t -> bool = "ml_secp256k1_scalar_is_even" [@@noalloc]
|
|
external is_high :
|
|
t -> bool = "ml_secp256k1_scalar_is_high" [@@noalloc]
|
|
external cond_negate :
|
|
t -> bool -> bool = "ml_secp256k1_scalar_cond_negate" [@@noalloc]
|
|
external get_num :
|
|
Num.t -> t -> unit = "ml_secp256k1_scalar_get_num" [@@noalloc]
|
|
external order_get_num :
|
|
Num.t -> unit = "ml_secp256k1_scalar_order_get_num" [@@noalloc]
|
|
external equal :
|
|
t -> t -> bool = "ml_secp256k1_scalar_eq" [@@noalloc]
|
|
external mul_shift_var :
|
|
t -> t -> t -> int -> unit = "ml_secp256k1_mul_shift_var" [@@noalloc]
|
|
|
|
let set_b32 t buf = set_b32 t (Cstruct.to_bigarray buf)
|
|
let get_b32 buf t = get_b32 (Cstruct.to_bigarray buf) t
|
|
end
|
|
|
|
module Field = struct
|
|
type t = Cstruct.buffer
|
|
|
|
module Storage = struct
|
|
type t = Cstruct.buffer
|
|
let size = 32
|
|
let to_cstruct t = Cstruct.of_bigarray t
|
|
let of_cstruct cs =
|
|
let res = Cstruct.create size in
|
|
try
|
|
Cstruct.blit cs 0 res 0 size ;
|
|
Some res.buffer
|
|
with _ -> None
|
|
let of_cstruct_exn cs =
|
|
match of_cstruct cs with
|
|
| Some t -> t
|
|
| None -> invalid_arg "Field.Storage.of_cstruct_exn"
|
|
|
|
external const :
|
|
t -> int64 -> int64 -> int64 -> int64 -> int64 -> int64 -> int64 -> int64 -> unit =
|
|
"ml_secp256k1_fe_storage_const_bytecode" "ml_secp256k1_fe_storage_const" [@@noalloc]
|
|
|
|
let const ?(d7=0L) ?(d6=0L) ?(d5=0L) ?(d4=0L) ?(d3=0L) ?(d2=0L) ?(d1=0L) ?(d0=0L) () =
|
|
let buf = Cstruct.create size in
|
|
const buf.buffer d7 d6 d5 d4 d3 d2 d1 d0 ;
|
|
buf.buffer
|
|
|
|
external cmov :
|
|
t -> t -> bool -> unit = "ml_secp256k1_fe_storage_cmov" [@@noalloc]
|
|
end
|
|
|
|
let size = 40
|
|
|
|
external const :
|
|
t -> int64 -> int64 -> int64 -> int64 -> int64 -> int64 -> int64 -> int64 -> unit =
|
|
"ml_secp256k1_fe_const_bytecode" "ml_secp256k1_fe_const" [@@noalloc]
|
|
|
|
let const ?(d7=0L) ?(d6=0L) ?(d5=0L) ?(d4=0L) ?(d3=0L) ?(d2=0L) ?(d1=0L) ?(d0=0L) () =
|
|
let buf = Cstruct.create size in
|
|
const buf.buffer d7 d6 d5 d4 d3 d2 d1 d0 ;
|
|
buf.buffer
|
|
|
|
external normalize :
|
|
t -> unit = "ml_secp256k1_fe_normalize" [@@noalloc]
|
|
external normalize_weak :
|
|
t -> unit = "ml_secp256k1_fe_normalize_weak" [@@noalloc]
|
|
external normalize_var :
|
|
t -> unit = "ml_secp256k1_fe_normalize_var" [@@noalloc]
|
|
external normalizes_to_zero :
|
|
t -> bool = "ml_secp256k1_fe_normalizes_to_zero" [@@noalloc]
|
|
external normalizes_to_zero_var :
|
|
t -> bool = "ml_secp256k1_fe_normalizes_to_zero_var" [@@noalloc]
|
|
external set_int :
|
|
t -> int -> unit = "ml_secp256k1_fe_set_int" [@@noalloc]
|
|
external clear :
|
|
t -> unit = "ml_secp256k1_fe_clear" [@@noalloc]
|
|
external is_zero :
|
|
t -> bool = "ml_secp256k1_fe_is_zero" [@@noalloc]
|
|
external is_odd :
|
|
t -> bool = "ml_secp256k1_fe_is_odd" [@@noalloc]
|
|
external equal :
|
|
t -> t -> bool = "ml_secp256k1_fe_equal" [@@noalloc]
|
|
external equal_var :
|
|
t -> t -> bool = "ml_secp256k1_fe_equal_var" [@@noalloc]
|
|
external cmp_var :
|
|
t -> t -> int = "ml_secp256k1_fe_cmp_var" [@@noalloc]
|
|
external set_b32 :
|
|
t -> Cstruct.buffer -> bool = "ml_secp256k1_fe_set_b32" [@@noalloc]
|
|
external get_b32 :
|
|
Cstruct.buffer -> t -> unit = "ml_secp256k1_fe_get_b32" [@@noalloc]
|
|
external negate :
|
|
t -> t -> int -> unit = "ml_secp256k1_fe_negate" [@@noalloc]
|
|
external mul_int :
|
|
t -> int -> unit = "ml_secp256k1_fe_mul_int" [@@noalloc]
|
|
external add :
|
|
t -> t -> unit = "ml_secp256k1_fe_add" [@@noalloc]
|
|
external mul :
|
|
t -> t -> t -> unit = "ml_secp256k1_fe_mul" [@@noalloc]
|
|
external sqr :
|
|
t -> t -> unit = "ml_secp256k1_fe_sqr" [@@noalloc]
|
|
external sqrt :
|
|
t -> t -> int = "ml_secp256k1_fe_sqrt" [@@noalloc]
|
|
external is_quad_var :
|
|
t -> bool = "ml_secp256k1_fe_is_quad_var" [@@noalloc]
|
|
external inv :
|
|
t -> t -> unit = "ml_secp256k1_fe_inv" [@@noalloc]
|
|
external inv_var :
|
|
t -> t -> unit = "ml_secp256k1_fe_inv_var" [@@noalloc]
|
|
external inv_all_var :
|
|
t -> Cstruct.buffer -> int -> unit = "ml_secp256k1_fe_inv_all_var" [@@noalloc]
|
|
external to_storage :
|
|
Storage.t -> t -> unit = "ml_secp256k1_fe_to_storage" [@@noalloc]
|
|
external from_storage :
|
|
t -> Storage.t -> unit = "ml_secp256k1_fe_from_storage" [@@noalloc]
|
|
external cmov :
|
|
t -> t -> bool -> unit = "ml_secp256k1_fe_cmov" [@@noalloc]
|
|
|
|
let inv_all_var r fes =
|
|
let nb_fe = List.length fes in
|
|
let cs = Cstruct.create (nb_fe * size) in
|
|
List.iteri
|
|
(fun i fe -> Cstruct.(blit (of_bigarray fe) 0 cs (i*size) size)) fes ;
|
|
inv_all_var r cs.buffer nb_fe ;
|
|
Cstruct.memset cs 0
|
|
|
|
let set_b32 t buf = set_b32 t (Cstruct.to_bigarray buf)
|
|
let get_b32 buf t = get_b32 (Cstruct.to_bigarray buf) t
|
|
|
|
let compare = cmp_var
|
|
end
|
|
|
|
module Group = struct
|
|
type t = Cstruct.buffer
|
|
type ge = t
|
|
|
|
let size = 2 * Field.size + 8
|
|
|
|
module Storage = struct
|
|
type t = Cstruct.buffer
|
|
let size = 2 * Field.Storage.size
|
|
let to_cstruct t = Cstruct.of_bigarray t
|
|
let of_cstruct cs =
|
|
let res = Cstruct.create size in
|
|
try
|
|
Cstruct.blit cs 0 res 0 size ;
|
|
Some res.buffer
|
|
with _ -> None
|
|
let of_cstruct_exn cs =
|
|
match of_cstruct cs with
|
|
| Some t -> t
|
|
| None -> invalid_arg "Group.Storage.of_cstruct_exn"
|
|
external of_fields :
|
|
t -> Field.Storage.t -> Field.Storage.t -> unit =
|
|
"ml_secp256k1_ge_storage_of_fields" [@@noalloc]
|
|
let of_fields ?(x=Field.const ()) ?(y=Field.const ()) () =
|
|
let cs = Cstruct.create size in
|
|
of_fields cs.buffer x y ;
|
|
cs.buffer
|
|
external cmov : t -> t -> bool -> unit =
|
|
"ml_secp256k1_ge_storage_cmov" [@@noalloc]
|
|
end
|
|
|
|
module Jacobian = struct
|
|
type t = Cstruct.buffer
|
|
|
|
let size = 3 * Field.size + 8
|
|
|
|
external of_fields :
|
|
t -> Field.t -> Field.t -> Field.t -> bool -> unit =
|
|
"ml_secp256k1_gej_of_fields" [@@noalloc]
|
|
|
|
external set_infinity : t -> unit =
|
|
"ml_secp256k1_gej_set_infinity" [@@noalloc]
|
|
|
|
external set_ge : t -> ge -> unit =
|
|
"ml_secp256k1_gej_set_ge" [@@noalloc]
|
|
|
|
external get_ge : ge -> t -> unit =
|
|
"ml_secp256k1_ge_set_gej" [@@noalloc]
|
|
|
|
external eq_x_var : Field.t -> t -> int =
|
|
"ml_secp256k1_gej_eq_x_var" [@@noalloc]
|
|
|
|
external neg : t -> t -> unit =
|
|
"ml_secp256k1_gej_neg" [@@noalloc]
|
|
|
|
external is_infinity : t -> bool =
|
|
"ml_secp256k1_gej_is_infinity" [@@noalloc]
|
|
|
|
external has_quad_y_var : t -> bool =
|
|
"ml_secp256k1_gej_has_quad_y_var" [@@noalloc]
|
|
|
|
external double_nonzero : t -> t -> Field.t option -> unit =
|
|
"ml_secp256k1_gej_double_nonzero" [@@noalloc]
|
|
|
|
external double_var : t -> t -> Field.t option -> unit =
|
|
"ml_secp256k1_gej_double_var" [@@noalloc]
|
|
|
|
external add_var : t -> t -> t -> Field.t option -> unit =
|
|
"ml_secp256k1_gej_add_var" [@@noalloc]
|
|
|
|
external add_ge : t -> t -> ge -> unit =
|
|
"ml_secp256k1_gej_add_ge" [@@noalloc]
|
|
|
|
external add_ge_var : t -> t -> ge -> Field.t option -> unit =
|
|
"ml_secp256k1_gej_add_ge_var" [@@noalloc]
|
|
|
|
external add_zinv_var : t -> t -> ge -> Field.t -> unit =
|
|
"ml_secp256k1_gej_add_zinv_var" [@@noalloc]
|
|
|
|
external mul : t -> ge -> Scalar.t -> unit =
|
|
"ml_secp256k1_ecmult_const" [@@noalloc]
|
|
|
|
external clear : t -> unit =
|
|
"ml_secp256k1_gej_clear" [@@noalloc]
|
|
|
|
external rescale : t -> Field.t -> unit =
|
|
"ml_secp256k1_gej_rescale" [@@noalloc]
|
|
|
|
let of_fields ?(x=Field.const ()) ?(y=Field.const ()) ?(z=Field.const ()) ?(infinity=false) () =
|
|
let cs = Cstruct.create size in
|
|
of_fields cs.buffer x y z infinity ;
|
|
cs.buffer
|
|
|
|
let double_nonzero ?rzr r a = double_nonzero r a rzr
|
|
let double_var ?rzr r a = double_var r a rzr
|
|
let add_var ?rzr r a b = add_var r a b rzr
|
|
let add_ge_var ?rzr r a b = add_ge_var r a b rzr
|
|
end
|
|
|
|
external of_fields :
|
|
t -> Field.t -> Field.t -> bool -> unit =
|
|
"ml_secp256k1_ge_of_fields" [@@noalloc]
|
|
|
|
external set_xy : t -> Field.t -> Field.t -> unit =
|
|
"ml_secp256k1_ge_set_xy" [@@noalloc]
|
|
|
|
external set_xquad : t -> Field.t -> unit =
|
|
"ml_secp256k1_ge_set_xquad" [@@noalloc]
|
|
|
|
external set_xovar : t -> Field.t -> int -> bool =
|
|
"ml_secp256k1_ge_set_xquad" [@@noalloc]
|
|
|
|
external is_infinity : t -> bool =
|
|
"ml_secp256k1_ge_is_infinity" [@@noalloc]
|
|
|
|
external is_valid_var : t -> bool =
|
|
"ml_secp256k1_ge_is_valid_var" [@@noalloc]
|
|
|
|
external neg : t -> t -> unit =
|
|
"ml_secp256k1_ge_neg" [@@noalloc]
|
|
|
|
external clear : t -> unit =
|
|
"ml_secp256k1_ge_clear" [@@noalloc]
|
|
|
|
external to_storage : Storage.t -> t -> unit =
|
|
"ml_secp256k1_ge_to_storage" [@@noalloc]
|
|
|
|
external from_storage : t -> Storage.t -> unit =
|
|
"ml_secp256k1_ge_from_storage" [@@noalloc]
|
|
|
|
let of_fields ?(x=Field.const ()) ?(y=Field.const ()) ?(infinity=false) () =
|
|
let cs = Cstruct.create size in
|
|
of_fields cs.buffer x y infinity ;
|
|
cs.buffer
|
|
|
|
let g =
|
|
let x = Field.const
|
|
~d7:0x79BE667EL ~d6:0xF9DCBBACL ~d5:0x55A06295L ~d4:0xCE870B07L
|
|
~d3:0x029BFCDBL ~d2:0x2DCE28D9L ~d1:0x59F2815BL ~d0:0x16F81798L () in
|
|
let y = Field.const
|
|
~d7:0x483ADA77L ~d6:0x26A3C465L ~d5:0x5DA4FBFCL ~d4:0x0E1108A8L
|
|
~d3:0xFD17B448L ~d2:0xA6855419L ~d1:0x9C47D08FL ~d0:0xFB10D4B8L () in
|
|
of_fields ~x ~y ~infinity:false ()
|
|
|
|
external serialize : t -> Cstruct.buffer -> int -> bool -> int =
|
|
"ml_secp256k1_eckey_pubkey_serialize" [@@noalloc]
|
|
|
|
external parse : t -> Cstruct.buffer -> int -> bool =
|
|
"ml_secp256k1_eckey_pubkey_parse" [@@noalloc]
|
|
|
|
let to_pubkey ?(compress=true) cs e =
|
|
match serialize e cs.Cstruct.buffer cs.len compress with
|
|
| 0 -> failwith "Group.to_pubkey"
|
|
| len -> Cstruct.sub cs 0 len
|
|
|
|
let from_pubkey t cs =
|
|
match parse t cs.Cstruct.buffer cs.len with
|
|
| false -> failwith "Group.from_pubkey"
|
|
| true -> ()
|
|
end
|