objective categorical abstract machine language personal data server
65
fork

Configure Feed

Select the types of activity you want to include in your feed.

Fix low-s signature normalization not occurring

futurGH b62e14c6 ac0a3af6

+76 -4
+4 -4
kleidos/kleidos.ml
··· 78 78 let hashed = SHA2_256.hash msg in 79 79 let k = Rfc6979.k_for_k256 ~privkey ~msg in 80 80 match K256.Libsecp256k1.sign ~sk:privkey ~msg:hashed ~k with 81 - | Some signature -> 82 - signature 81 + | Some sgn -> 82 + Low_s.normalize_k256 sgn 83 83 | None -> 84 84 failwith "failed to sign message" 85 85 ··· 146 146 let hashed = SHA2_256.hash msg in 147 147 let k = Rfc6979.k_for_p256 ~privkey ~msg in 148 148 match P256.sign ~sk:privkey ~msg:hashed ~k with 149 - | Some signature -> 150 - signature 149 + | Some sgn -> 150 + Low_s.normalize_p256 sgn 151 151 | None -> 152 152 failwith "failed to sign message" 153 153
+56
kleidos/low_s.ml
··· 1 + open struct 2 + let z_of_bytes s = 3 + let acc = ref Z.zero in 4 + for i = 0 to String.length s - 1 do 5 + acc := Z.(shift_left !acc 8 + of_int (Char.code s.[i])) 6 + done ; 7 + !acc 8 + 9 + let bytes_of_z_32 z = 10 + let buf = Bytes.make 32 '\x00' in 11 + let rec fill i v = 12 + if i >= 0 then ( 13 + Bytes.set buf i (Char.chr (Z.to_int (Z.logand v (Z.of_int 0xff)))) ; 14 + fill (i - 1) (Z.shift_right v 8) ) 15 + in 16 + fill 31 z ; Bytes.unsafe_to_string buf 17 + 18 + let to_32 s = 19 + let l = String.length s in 20 + if l = 32 then s 21 + else if l < 32 then String.make (32 - l) '\x00' ^ s 22 + else String.sub s (l - 32) 32 23 + end 24 + 25 + let normalize ~(order : Z.t) (r : string) (s : string) : bytes = 26 + let r32 = to_32 r in 27 + let s32 = to_32 s in 28 + let s_z = z_of_bytes s32 in 29 + let s_low = if Z.gt s_z Z.(order / ~$2) then Z.(order - s_z) else s_z in 30 + r32 ^ bytes_of_z_32 s_low |> Bytes.of_string 31 + 32 + let k256_n = 33 + Z.of_string 34 + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141" 35 + 36 + let p256_n = 37 + Z.of_string 38 + "0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551" 39 + 40 + let rs_of_sig (signature : bytes) : string * string = 41 + let sig_str = Bytes.to_string signature in 42 + let sig_len = String.length sig_str in 43 + if sig_len <> 64 then 44 + invalid_arg 45 + (Format.sprintf "signature must be 64 bytes (r||s); got %d" sig_len) ; 46 + let r = String.sub sig_str 0 32 in 47 + let s = String.sub sig_str 32 32 in 48 + (r, s) 49 + 50 + let normalize_k256 sgn = 51 + let r, s = rs_of_sig sgn in 52 + normalize ~order:k256_n r s 53 + 54 + let normalize_p256 sgn = 55 + let r, s = rs_of_sig sgn in 56 + normalize ~order:p256_n r s
+3
pegasus/lib/plc.ml
··· 212 212 | Operation 213 213 {type'; rotation_keys; verification_methods; also_known_as; services; prev} 214 214 -> 215 + assert ( 216 + Util.sig_matches_some_did_key ~did_keys:rotation_keys 217 + ~signature:sig_bytes ~msg:cbor ) ; 215 218 Operation 216 219 { type' 217 220 ; rotation_keys
+13
pegasus/lib/util.ml
··· 310 310 let mkfile_p path ~perm = 311 311 Core_unix.mkdir_p (Filename.dirname path) ~perm:0o755 ; 312 312 Core_unix.openfile ~mode:[O_CREAT; O_WRONLY] ~perm path |> Core_unix.close 313 + 314 + let sig_matches_some_did_key ~did_keys ~signature ~msg = 315 + List.find_opt 316 + (fun key -> 317 + let raw, (module Curve) = 318 + Kleidos.parse_multikey_str (String.sub key 8 (String.length key - 8)) 319 + in 320 + let valid = 321 + Curve.verify ~pubkey:(Curve.normalize_pubkey_to_raw raw) ~signature ~msg 322 + in 323 + valid ) 324 + did_keys 325 + <> None