···7878 let hashed = SHA2_256.hash msg in
7979 let k = Rfc6979.k_for_k256 ~privkey ~msg in
8080 match K256.Libsecp256k1.sign ~sk:privkey ~msg:hashed ~k with
8181- | Some signature ->
8282- signature
8181+ | Some sgn ->
8282+ Low_s.normalize_k256 sgn
8383 | None ->
8484 failwith "failed to sign message"
8585···146146 let hashed = SHA2_256.hash msg in
147147 let k = Rfc6979.k_for_p256 ~privkey ~msg in
148148 match P256.sign ~sk:privkey ~msg:hashed ~k with
149149- | Some signature ->
150150- signature
149149+ | Some sgn ->
150150+ Low_s.normalize_p256 sgn
151151 | None ->
152152 failwith "failed to sign message"
153153
+56
kleidos/low_s.ml
···11+open struct
22+ let z_of_bytes s =
33+ let acc = ref Z.zero in
44+ for i = 0 to String.length s - 1 do
55+ acc := Z.(shift_left !acc 8 + of_int (Char.code s.[i]))
66+ done ;
77+ !acc
88+99+ let bytes_of_z_32 z =
1010+ let buf = Bytes.make 32 '\x00' in
1111+ let rec fill i v =
1212+ if i >= 0 then (
1313+ Bytes.set buf i (Char.chr (Z.to_int (Z.logand v (Z.of_int 0xff)))) ;
1414+ fill (i - 1) (Z.shift_right v 8) )
1515+ in
1616+ fill 31 z ; Bytes.unsafe_to_string buf
1717+1818+ let to_32 s =
1919+ let l = String.length s in
2020+ if l = 32 then s
2121+ else if l < 32 then String.make (32 - l) '\x00' ^ s
2222+ else String.sub s (l - 32) 32
2323+end
2424+2525+let normalize ~(order : Z.t) (r : string) (s : string) : bytes =
2626+ let r32 = to_32 r in
2727+ let s32 = to_32 s in
2828+ let s_z = z_of_bytes s32 in
2929+ let s_low = if Z.gt s_z Z.(order / ~$2) then Z.(order - s_z) else s_z in
3030+ r32 ^ bytes_of_z_32 s_low |> Bytes.of_string
3131+3232+let k256_n =
3333+ Z.of_string
3434+ "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"
3535+3636+let p256_n =
3737+ Z.of_string
3838+ "0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551"
3939+4040+let rs_of_sig (signature : bytes) : string * string =
4141+ let sig_str = Bytes.to_string signature in
4242+ let sig_len = String.length sig_str in
4343+ if sig_len <> 64 then
4444+ invalid_arg
4545+ (Format.sprintf "signature must be 64 bytes (r||s); got %d" sig_len) ;
4646+ let r = String.sub sig_str 0 32 in
4747+ let s = String.sub sig_str 32 32 in
4848+ (r, s)
4949+5050+let normalize_k256 sgn =
5151+ let r, s = rs_of_sig sgn in
5252+ normalize ~order:k256_n r s
5353+5454+let normalize_p256 sgn =
5555+ let r, s = rs_of_sig sgn in
5656+ normalize ~order:p256_n r s