···11-type error =
22- [ `Invalid_format
11+type error = [
22+ | `Invalid_format
33 | `Invalid_length
44 | `Invalid_range
55 | `Not_on_curve
66- | `At_infinity ]
66+ | `At_infinity
77+ | `Low_order
88+]
79810let error_to_string = function
911 | `Invalid_format -> "invalid format"
···1113 | `At_infinity -> "point is at infinity"
1214 | `Invalid_length -> "invalid length"
1315 | `Invalid_range -> "invalid range"
1616+ | `Low_order -> "low order"
14171518let pp_error fmt e =
1619 Format.fprintf fmt "Cannot parse point: %s" (error_to_string e)
···321324module Make_scalar (Param : Parameters) (P : Point) : Scalar = struct
322325 let not_zero =
323326 let zero = Cstruct.create Param.byte_length in
324324- fun cs -> Eqaf_cstruct.compare_be_with_len ~len:Param.byte_length cs zero > 0
327327+ fun cs -> not (Eqaf_cstruct.equal cs zero)
325328326329 let is_in_range cs =
327330 not_zero cs
···777780 module Dsa = Make_dsa(Params)(Foreign_n)(P)(S)(Mirage_crypto.Hash.SHA512)
778781end
779782783783+module X25519 = struct
784784+ (* RFC 7748 *)
785785+ external x25519_scalar_mult_generic : Cstruct.buffer -> Cstruct.buffer -> Cstruct.buffer -> unit = "mc_x25519_scalar_mult_generic" [@@noalloc]
786786+787787+ let key_len = 32
788788+789789+ let scalar_mult in_ base =
790790+ let out = Cstruct.create key_len in
791791+ x25519_scalar_mult_generic out.Cstruct.buffer in_.Cstruct.buffer base.Cstruct.buffer;
792792+ out
793793+794794+ type secret = Cstruct.t
795795+796796+ let basepoint =
797797+ let data = Cstruct.create key_len in
798798+ Cstruct.set_uint8 data 0 9;
799799+ data
800800+801801+ let public priv = scalar_mult priv basepoint
802802+803803+ let gen_key ~rng =
804804+ let secret = rng key_len in
805805+ secret, public secret
806806+807807+ let is_zero =
808808+ let zero = Cstruct.create key_len in
809809+ fun cs -> Cstruct.equal zero cs
810810+811811+ let key_exchange secret public =
812812+ if Cstruct.len public = key_len then
813813+ let res = scalar_mult secret public in
814814+ if is_zero res then Error `Low_order else Ok res
815815+ else
816816+ Error `Invalid_length
817817+end
818818+819819+module Ed25519 = struct
820820+821821+ external scalar_mult_base_to_bytes : Cstruct.buffer -> Cstruct.buffer -> unit = "mc_25519_scalar_mult_base" [@@noalloc]
822822+ external reduce_l : Cstruct.buffer -> unit = "mc_25519_reduce_l" [@@noalloc]
823823+ external muladd : Cstruct.buffer -> Cstruct.buffer -> Cstruct.buffer -> Cstruct.buffer -> unit = "mc_25519_muladd" [@@noalloc]
824824+ external double_scalar_mult : Cstruct.buffer -> Cstruct.buffer -> Cstruct.buffer -> Cstruct.buffer -> bool = "mc_25519_double_scalar_mult" [@@noalloc]
825825+ external pub_ok : Cstruct.buffer -> bool = "mc_25519_pub_ok" [@@noalloc]
826826+827827+ type pub = Cstruct.t
828828+829829+ type priv = Cstruct.t
830830+831831+ (* RFC 8032 *)
832832+ let key_len = 32
833833+834834+ let public secret =
835835+ (* section 5.1.5 *)
836836+ (* step 1 *)
837837+ let h = Mirage_crypto.Hash.SHA512.digest secret in
838838+ (* step 2 *)
839839+ let s, rest = Cstruct.split h key_len in
840840+ Cstruct.set_uint8 s 0 (Cstruct.get_uint8 s 0 land 248);
841841+ Cstruct.set_uint8 s 31 ((Cstruct.get_uint8 s 31 land 127) lor 64);
842842+ (* step 3 and 4 *)
843843+ let public = Cstruct.create key_len in
844844+ scalar_mult_base_to_bytes public.Cstruct.buffer s.Cstruct.buffer;
845845+ public, (s, rest)
846846+847847+ let pub_of_priv secret = fst (public secret)
848848+849849+ let priv_of_cstruct cs =
850850+ if Cstruct.len cs = key_len then Ok cs else Error `Invalid_length
851851+852852+ let priv_to_cstruct priv = priv
853853+854854+ let pub_of_cstruct cs =
855855+ if Cstruct.len cs = key_len then
856856+ let cs_copy = Cstruct.create key_len in
857857+ Cstruct.blit cs 0 cs_copy 0 key_len;
858858+ if pub_ok cs_copy.Cstruct.buffer then
859859+ Ok cs_copy
860860+ else
861861+ Error `Not_on_curve
862862+ else
863863+ Error `Invalid_length
864864+865865+ let pub_to_cstruct pub = pub
866866+867867+ let generate ~rng =
868868+ let secret = rng key_len in
869869+ secret, pub_of_priv secret
870870+871871+ let sign ~key msg =
872872+ (* section 5.1.6 *)
873873+ let pub, (s, prefix) = public key in
874874+ let r = Mirage_crypto.Hash.SHA512.digest (Cstruct.append prefix msg) in
875875+ reduce_l r.Cstruct.buffer;
876876+ let r_big = Cstruct.create key_len in
877877+ scalar_mult_base_to_bytes r_big.Cstruct.buffer r.Cstruct.buffer;
878878+ let k = Mirage_crypto.Hash.SHA512.digest (Cstruct.concat [ r_big ; pub ; msg ]) in
879879+ reduce_l k.Cstruct.buffer;
880880+ let s_out = Cstruct.create key_len in
881881+ muladd s_out.Cstruct.buffer k.Cstruct.buffer s.Cstruct.buffer r.Cstruct.buffer;
882882+ Cstruct.append r_big s_out
883883+884884+ let verify ~key signature ~msg =
885885+ (* section 5.1.7 *)
886886+ if Cstruct.len signature = 2 * key_len then
887887+ let r, s = Cstruct.split signature key_len in
888888+ let s_smaller_l =
889889+ (* check s within 0 <= s < L *)
890890+ let s' = Cstruct.create (key_len * 2) in
891891+ Cstruct.blit s 0 s' 0 key_len;
892892+ reduce_l s'.Cstruct.buffer;
893893+ let s'' = Cstruct.(append s (create key_len)) in
894894+ Cstruct.equal s'' s'
895895+ in
896896+ if s_smaller_l then begin
897897+ let k =
898898+ Mirage_crypto.Hash.SHA512.digest (Cstruct.concat [ r ; key ; msg ])
899899+ in
900900+ reduce_l k.Cstruct.buffer;
901901+ let r' = Cstruct.create key_len in
902902+ let success =
903903+ double_scalar_mult r'.Cstruct.buffer k.Cstruct.buffer
904904+ key.Cstruct.buffer s.Cstruct.buffer
905905+ in
906906+ success && Cstruct.equal r r'
907907+ end else
908908+ false
909909+ else
910910+ false
911911+end
+60-6
ec/mirage_crypto_ec.mli
···99 consume a constant amount of time, independent of the input values.
1010*)
11111212-type error =
1313- [ `Invalid_range
1212+type error = [
1313+ | `Invalid_range
1414 | `Invalid_format
1515 | `Invalid_length
1616 | `Not_on_curve
1717- | `At_infinity ]
1717+ | `At_infinity
1818+ | `Low_order
1919+]
1820(** The type for errors. *)
19212022val pp_error : Format.formatter -> error -> unit
···105107106108 val sign : key:priv -> ?k:Cstruct.t -> Cstruct.t -> Cstruct.t * Cstruct.t
107109 (** [sign ~key ~k digest] signs the message [digest] using the private
108108- [key]. If [k] is not provided, it is computed using the deterministic
109109- construction from RFC 6979. The result is a pair of [r] and [s].
110110+ [key]. The [digest] is not processed further - it should be the hash of
111111+ the message to sign. If [k] is not provided, it is computed using the
112112+ deterministic construction from RFC 6979. The result is a pair of [r]
113113+ and [s].
110114111115 @raise Invalid_argument if [k] is not suitable or not in range.
112112- @raise Message_too_long if [msg] is too long for the curve. *)
116116+ @raise Message_too_long if the bit size of [msg] exceeds the curve. *)
113117114118 val verify : key:pub -> Cstruct.t * Cstruct.t -> Cstruct.t -> bool
115119 (** [verify ~key (r, s) digest] verifies the signature [r, s] on the message
···148152149153(** The NIST P-521 curve, also known as SECP521R1. *)
150154module P521 : Dh_dsa
155155+156156+(** Curve 25519 Diffie-Hellman, also known as X25519. *)
157157+module X25519 : Dh
158158+159159+(** Curve 25519 DSA, also known as Ed25519. *)
160160+module Ed25519 : sig
161161+ type priv
162162+ (** The type for private keys. *)
163163+164164+ type pub
165165+ (** The type for public keys. *)
166166+167167+ (** {2 Serialisation} *)
168168+169169+ val priv_of_cstruct : Cstruct.t -> (priv, error) result
170170+ (** [priv_of_cstruct cs] decodes a private key from the buffer [cs]. If the
171171+ provided data is invalid, an error is returned. *)
172172+173173+ val priv_to_cstruct : priv -> Cstruct.t
174174+ (** [priv_to_cstruct p] encode the private key [p] to a buffer. *)
175175+176176+ val pub_of_cstruct : Cstruct.t -> (pub, error) result
177177+ (** [pub_of_cstruct cs] decodes a public key from the buffer [cs]. If the
178178+ provided data is invalid, an error is returned. *)
179179+180180+ val pub_to_cstruct : pub -> Cstruct.t
181181+ (** [pub_to_cstruct p] encodes the public key [p] into a buffer. *)
182182+183183+ (** {2 Deriving the public key} *)
184184+185185+ val pub_of_priv : priv -> pub
186186+ (** [pub_of_priv p] extracts the public key from the private key [p]. *)
187187+188188+ (** {2 Key generation} *)
189189+190190+ val generate : rng:(int -> Cstruct.t) -> priv * pub
191191+ (** [generate ~rng] generates a key pair using the provided random number
192192+ generator. *)
193193+194194+ (** {2 Cryptographic operations} *)
195195+196196+ val sign : key:priv -> Cstruct.t -> Cstruct.t
197197+ (** [sign ~key msg] signs the message [msg] using the private [key]. The
198198+ result is the concatenation of [r] and [s], as specified in RFC 8032. *)
199199+200200+ val verify : key:pub -> Cstruct.t -> msg:Cstruct.t -> bool
201201+ (** [verify ~key signature msg] verifies the [signature] on the message
202202+ [msg] with the public [key]. The return value is [true] if verification
203203+ was successful, [false] otherwise. *)
204204+end