package tiny_libs
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
From-scratch libraries for teaching: graphics, audio, compression, crypto, networking and more
Install
dune-project
Dependency
Authors
Maintainers
Sources
0.3.6.tar.gz
md5=7c636383d146d30ac6f2fa234a6253c8
sha512=c79f3823c5f8f57e5038eb640d487c61168b84aa07c61999d6622ef9fd0c890e2b03b4c6a7cdbbe9352a49e25dda00ac7bb14693cee8e3d7beeed251351a2af0
doc/src/tiny_libs.crypto/Rsa.ml.html
Source file Rsa.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74(* Claude Code * * Copyright (C) 2026 Yoann Padioleau * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public License * (LGPL) as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. *) (* See Rsa.mli *) type hash = Sha256 | Sha384 | Sha512 let digest = function Sha256 -> Sha256.digest | Sha384 -> Sha512.digest384 | Sha512 -> Sha512.digest (* the DER of DigestInfo less the hash's bytes (RFC 8017, 9.2, note 1) *) let digest_info = function | Sha256 -> "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20" | Sha384 -> "\x30\x41\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x05\x00\x04\x30" | Sha512 -> "\x30\x51\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x05\x00\x04\x40" (* s^e mod n, as many bytes as n *) let apply ~(n : Bignum.t) ~(e : Bignum.t) (signature : string) : string option = let k = (Bignum.bits n + 7) / 8 in let s = Bignum.of_bytes signature in if String.length signature <> k || Bignum.compare s n >= 0 || Bignum.bits n < 1024 then None else Some (Bignum.to_bytes ~len:k (Bignum.pow_mod (Bignum.modulus n) s e)) let verify_pkcs1 ~n ~e (h : hash) ~(message : string) ~(signature : string) : bool = match apply ~n ~e signature with | None -> false | Some em -> let t = digest_info h ^ digest h message in let k = String.length em in k >= String.length t + 11 && em = "\x00\x01" ^ String.make (k - String.length t - 3) '\xff' ^ "\x00" ^ t let mgf1 (h : hash) (seed : string) (len : int) : string = let out = Buffer.create len in let rec go i = if Buffer.length out < len then ( Buffer.add_string out (digest h (seed ^ String.init 4 (fun k -> Char.chr ((i lsr (24 - (8 * k))) land 0xff)))); go (i + 1)) in go 0; Buffer.sub out 0 len let verify_pss ~n ~e (h : hash) ~(message : string) ~(signature : string) : bool = match apply ~n ~e signature with | None -> false | Some em -> let mod_bits = Bignum.bits n in let em_bits = mod_bits - 1 in let em_len = (em_bits + 7) / 8 in (* a modulus of 8k+1 bits: the first byte of k+1 is a zero to drop *) let em = if String.length em > em_len then (if em.[0] = '\000' then String.sub em 1 em_len else "") else em in let h_len = String.length (digest h "") in String.length em = em_len && em_len >= (2 * h_len) + 2 && em.[em_len - 1] = '\xbc' && let masked = String.sub em 0 (em_len - h_len - 1) and hh = String.sub em (em_len - h_len - 1) h_len in let top = (8 * em_len) - em_bits in Char.code masked.[0] lsr (8 - top) = 0 && let mask = mgf1 h hh (String.length masked) in let db = String.mapi (fun i c -> Char.chr (Char.code c lxor Char.code mask.[i])) masked in let db = String.mapi (fun i c -> if i = 0 then Char.chr (Char.code c land (0xff lsr top)) else c) db in let ps_len = em_len - (2 * h_len) - 2 in String.sub db 0 ps_len = String.make ps_len '\000' && db.[ps_len] = '\001' && let salt = String.sub db (ps_len + 1) h_len in digest h (String.make 8 '\000' ^ digest h message ^ salt) = hh
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>