upstream: https://github.com/mirage/mirage-crypto

docs(crypto): fix E400, E405, E410 documentation issues

- E400: add module doc comment to wycheproof.mli
- E405: add missing doc comments for public values in crypto_pk.mli,
crypto_rng.mli, crypto.mli, wycheproof.mli, and pk sub-modules
- E410: fix doc style (arg counts, name format, trailing periods) in
entropy.mli, getentropy.mli, urandom.mli, chacha20.mli, uncommon.mli

+209 -9
+1 -1
ec/gen_tables/gen_tables.ml
··· 105 105 List.find (fun (name, _) -> name = Sys.argv.(1)) curves 106 106 in 107 107 (name, curve, int_of_string Sys.argv.(2)) 108 - with _ -> 108 + with Not_found | Invalid_argument _ | Failure _ -> 109 109 usage (); 110 110 exit 1 111 111 in
+50
pk/dh.mli
··· 1 1 (** Diffie-Hellman key exchange over multiplicative groups of integers mod p. *) 2 2 3 3 exception Invalid_key 4 + (** Raised on invalid DH parameters. *) 4 5 5 6 type group = private { p : Z.t; gg : Z.t; q : Z.t option } 7 + (** A DH group with prime [p], generator [gg], and optional subgroup order [q]. 8 + *) 6 9 7 10 val group : 8 11 p:Z.t -> gg:Z.t -> ?q:Z.t -> unit -> (group, [> `Msg of string ]) result 12 + (** [group ~p ~gg ?q ()] constructs a DH group. *) 9 13 10 14 type secret = private { group : group; x : Z.t } 15 + (** A DH secret key. *) 11 16 12 17 val modulus_size : group -> int 18 + (** [modulus_size g] is the bit size of [g]'s prime modulus. *) 19 + 13 20 val key_of_secret : group -> s:string -> secret * string 21 + (** [key_of_secret g ~s] derives a key pair from secret [s]. Returns the secret 22 + and the public value. *) 23 + 14 24 val gen_key : ?g:Crypto_rng.g -> ?bits:int -> group -> secret * string 25 + (** [gen_key ~g ~bits group] generates a fresh key pair. Returns the secret and 26 + the public value. *) 27 + 15 28 val shared : secret -> string -> string option 29 + (** [shared secret public] computes the shared secret. Returns [None] if the 30 + public value is invalid. *) 31 + 16 32 val gen_group : ?g:Crypto_rng.g -> bits:int -> unit -> group 33 + (** [gen_group ~g ~bits ()] generates a fresh DH group with a [bits]-bit prime. 34 + *) 17 35 36 + (** Standard DH groups. *) 18 37 module Group : sig 19 38 val oakley_1 : group 39 + (** Oakley group 1 (RFC 2409, 768-bit). *) 40 + 20 41 val oakley_2 : group 42 + (** Oakley group 2 (RFC 2409, 1024-bit). *) 43 + 21 44 val oakley_5 : group 45 + (** Oakley group 5 (RFC 3526, 1536-bit). *) 46 + 22 47 val oakley_14 : group 48 + (** Oakley group 14 (RFC 3526, 2048-bit). *) 49 + 23 50 val oakley_15 : group 51 + (** Oakley group 15 (RFC 3526, 3072-bit). *) 52 + 24 53 val oakley_16 : group 54 + (** Oakley group 16 (RFC 3526, 4096-bit). *) 55 + 25 56 val oakley_17 : group 57 + (** Oakley group 17 (RFC 3526, 6144-bit). *) 58 + 26 59 val oakley_18 : group 60 + (** Oakley group 18 (RFC 3526, 8192-bit). *) 61 + 27 62 val rfc_5114_1 : group 63 + (** RFC 5114 group 1 (1024-bit with 160-bit subgroup). *) 64 + 28 65 val rfc_5114_2 : group 66 + (** RFC 5114 group 2 (2048-bit with 224-bit subgroup). *) 67 + 29 68 val rfc_5114_3 : group 69 + (** RFC 5114 group 3 (2048-bit with 256-bit subgroup). *) 70 + 30 71 val ffdhe2048 : group 72 + (** FFDHE 2048-bit group (RFC 7919). *) 73 + 31 74 val ffdhe3072 : group 75 + (** FFDHE 3072-bit group (RFC 7919). *) 76 + 32 77 val ffdhe4096 : group 78 + (** FFDHE 4096-bit group (RFC 7919). *) 79 + 33 80 val ffdhe6144 : group 81 + (** FFDHE 6144-bit group (RFC 7919). *) 82 + 34 83 val ffdhe8192 : group 84 + (** FFDHE 8192-bit group (RFC 7919). *) 35 85 end
+25
pk/dsa.mli
··· 1 1 (** DSA digital signature algorithm. *) 2 2 3 3 type pub = private { p : Z.t; q : Z.t; gg : Z.t; y : Z.t } 4 + (** A DSA public key. *) 4 5 5 6 val pub : 6 7 ?fips:bool -> ··· 10 11 y:Z.t -> 11 12 unit -> 12 13 (pub, [> `Msg of string ]) result 14 + (** [pub ~p ~q ~gg ~y ()] constructs a public key. If [~fips:true], validates 15 + parameter sizes per FIPS 186-4. *) 13 16 14 17 type priv = private { p : Z.t; q : Z.t; gg : Z.t; x : Z.t; y : Z.t } 18 + (** A DSA private key. *) 15 19 16 20 val priv : 17 21 ?fips:bool -> ··· 22 26 y:Z.t -> 23 27 unit -> 24 28 (priv, [> `Msg of string ]) result 29 + (** [priv ~p ~q ~gg ~x ~y ()] constructs a private key. *) 25 30 26 31 val pub_of_priv : priv -> pub 32 + (** [pub_of_priv k] extracts the public key from [k]. *) 27 33 28 34 type keysize = [ `Fips1024 | `Fips2048 | `Fips3072 | `Exactly of int * int ] 35 + (** Key size specification. *) 36 + 29 37 type mask = [ `No | `Yes | `Yes_with of Crypto_rng.g ] 38 + (** Blinding mask for side-channel protection. *) 30 39 31 40 val params : ?g:Crypto_rng.g -> keysize -> Z.t * Z.t * Z.t 41 + (** [params ~g size] generates DSA domain parameters [(p, q, gg)]. *) 42 + 32 43 val generate : ?g:Crypto_rng.g -> keysize -> priv 44 + (** [generate ~g size] generates a fresh DSA key pair. *) 33 45 46 + (** Deterministic nonce generation per RFC 6979. *) 34 47 module K_gen (H : Digestif.S) : sig 35 48 val z_gen : key:priv -> Z.t -> Z.t 49 + (** [z_gen ~key z] generates a deterministic nonce for message hash [z]. *) 50 + 36 51 val generate : key:priv -> string -> Z.t 52 + (** [generate ~key msg] generates a deterministic nonce for [msg]. *) 37 53 end 38 54 39 55 val sign_z : ?mask:mask -> ?k:Z.t -> key:priv -> Z.t -> Z.t * Z.t 56 + (** [sign_z ~key z] signs the integer [z], returning [(r, s)]. *) 57 + 40 58 val verify_z : key:pub -> Z.t * Z.t -> Z.t -> bool 59 + (** [verify_z ~key (r, s) z] verifies signature [(r, s)] against [z]. *) 60 + 41 61 val sign : ?mask:mask -> ?k:Z.t -> key:priv -> string -> string * string 62 + (** [sign ~key msg] signs the octet string [msg]. *) 63 + 42 64 val verify : key:pub -> string * string -> string -> bool 65 + (** [verify ~key (r, s) msg] verifies the signature against [msg]. *) 66 + 43 67 val massage : key:pub -> string -> string 68 + (** [massage ~key msg] truncates [msg] to the byte length of [key.q]. *)
+36
pk/rsa.mli
··· 1 1 (** RSA public-key encryption and signature scheme. *) 2 2 3 3 type 'a or_digest = [ `Message of 'a | `Digest of string ] 4 + (** Either a raw message or a pre-computed digest. *) 4 5 5 6 exception Insufficient_key 7 + (** Raised when the key is too small for the requested operation. *) 6 8 7 9 type pub = private { e : Z.t; n : Z.t } 10 + (** An RSA public key with exponent [e] and modulus [n]. *) 8 11 9 12 val pub : e:Z.t -> n:Z.t -> (pub, [> `Msg of string ]) result 13 + (** [pub ~e ~n] constructs a public key. *) 10 14 11 15 type priv = private { 12 16 e : Z.t; ··· 18 22 dq : Z.t; 19 23 q' : Z.t; 20 24 } 25 + (** An RSA private key with CRT components. *) 21 26 22 27 val priv : 23 28 e:Z.t -> ··· 29 34 dq:Z.t -> 30 35 q':Z.t -> 31 36 (priv, [> `Msg of string ]) result 37 + (** [priv ~e ~d ~n ~p ~q ~dp ~dq ~q'] constructs a private key. *) 32 38 33 39 val priv_of_primes : 34 40 e:Z.t -> p:Z.t -> q:Z.t -> (priv, [> `Msg of string ]) result 41 + (** [priv_of_primes ~e ~p ~q] derives a private key from primes [p] and [q]. *) 35 42 36 43 val priv_of_exp : 37 44 ?g:Crypto_rng.g -> ··· 41 48 n:Z.t -> 42 49 unit -> 43 50 (priv, [> `Msg of string ]) result 51 + (** [priv_of_exp ~e ~d ~n ()] recovers CRT parameters from the public and 52 + private exponents. *) 44 53 45 54 val pub_of_priv : priv -> pub 55 + (** [pub_of_priv k] extracts the public key from [k]. *) 56 + 46 57 val pub_bits : pub -> int 58 + (** [pub_bits k] is the bit size of the modulus. *) 59 + 47 60 val priv_bits : priv -> int 61 + (** [priv_bits k] is the bit size of the modulus. *) 62 + 48 63 val generate : ?g:Crypto_rng.g -> ?e:Z.t -> bits:int -> unit -> priv 64 + (** [generate ~g ~e ~bits ()] generates a fresh RSA key pair. *) 49 65 50 66 type mask = [ `No | `Yes | `Yes_with of Crypto_rng.g ] 67 + (** Blinding mask for side-channel protection. *) 51 68 52 69 val encrypt : key:pub -> string -> string 70 + (** [encrypt ~key msg] performs raw RSA encryption. *) 71 + 53 72 val decrypt : ?crt_hardening:bool -> ?mask:mask -> key:priv -> string -> string 73 + (** [decrypt ~key ct] performs raw RSA decryption. *) 54 74 75 + (** PKCS#1 v1.5 encryption and signatures. *) 55 76 module PKCS1 : sig 56 77 val sig_encode : 57 78 ?crt_hardening:bool -> ?mask:mask -> key:priv -> string -> string 79 + (** [sig_encode ~key msg] produces a PKCS#1 v1.5 signature. *) 58 80 59 81 val sig_decode : key:pub -> string -> string option 82 + (** [sig_decode ~key sig] verifies and decodes a PKCS#1 v1.5 signature. *) 83 + 60 84 val encrypt : ?g:Crypto_rng.g -> key:pub -> string -> string 85 + (** [encrypt ~key msg] performs PKCS#1 v1.5 encryption. *) 61 86 62 87 val decrypt : 63 88 ?crt_hardening:bool -> ?mask:mask -> key:priv -> string -> string option 89 + (** [decrypt ~key ct] performs PKCS#1 v1.5 decryption. *) 64 90 65 91 val sign : 66 92 ?crt_hardening:bool -> ··· 69 95 key:priv -> 70 96 string or_digest -> 71 97 string 98 + (** [sign ~hash ~key msg] signs [msg] using PKCS#1 v1.5 with [hash]. *) 72 99 73 100 val verify : 74 101 hashp: ··· 77 104 signature:string -> 78 105 string or_digest -> 79 106 bool 107 + (** [verify ~hashp ~key ~signature msg] verifies a PKCS#1 v1.5 signature. 108 + [hashp] selects acceptable hash algorithms. *) 80 109 81 110 val min_key : 82 111 [< Digestif.hash' > `MD5 `SHA1 `SHA224 `SHA256 `SHA384 `SHA512 ] -> int 112 + (** [min_key hash] is the minimum key size in bits for [hash]. *) 83 113 end 84 114 115 + (** OAEP encryption (PKCS#1 v2). *) 85 116 module OAEP (H : Digestif.S) : sig 86 117 val encrypt : ?g:Crypto_rng.g -> ?label:string -> key:pub -> string -> string 118 + (** [encrypt ~key msg] performs OAEP encryption. *) 87 119 88 120 val decrypt : 89 121 ?crt_hardening:bool -> ··· 92 124 key:priv -> 93 125 string -> 94 126 string option 127 + (** [decrypt ~key ct] performs OAEP decryption. *) 95 128 end 96 129 130 + (** PSS signatures (PKCS#1 v2). *) 97 131 module PSS (H : Digestif.S) : sig 98 132 val sign : 99 133 ?g:Crypto_rng.g -> ··· 103 137 key:priv -> 104 138 string or_digest -> 105 139 string 140 + (** [sign ~key msg] produces a PSS signature. *) 106 141 107 142 val verify : 108 143 ?slen:int -> key:pub -> signature:string -> string or_digest -> bool 144 + (** [verify ~key ~signature msg] verifies a PSS signature. *) 109 145 end
+25
pk/z_extra.mli
··· 2 2 generation. *) 3 3 4 4 val bit_bound : Z.t -> int 5 + (** [bit_bound z] is the number of bytes needed to represent [z]. *) 6 + 5 7 val of_octets_be : ?bits:int -> string -> Z.t 8 + (** [of_octets_be ~bits s] decodes a big-endian unsigned integer from [s]. *) 9 + 6 10 val into_octets_be : Z.t -> bytes -> unit 11 + (** [into_octets_be z buf] writes [z] as big-endian octets into [buf]. *) 12 + 7 13 val to_octets_be : ?size:int -> Z.t -> string 14 + (** [to_octets_be ~size z] encodes [z] as a big-endian string of [size] bytes. 15 + *) 16 + 8 17 val pseudoprime : Z.t -> bool 18 + (** [pseudoprime z] is [true] if [z] is a probable prime (Miller-Rabin). *) 19 + 9 20 val strip_factor : f:Z.t -> Z.t -> (int * Z.t, [> `Msg of string ]) result 21 + (** [strip_factor ~f n] removes all factors of [f] from [n]. Returns [(k, m)] 22 + where [n = f^k * m]. *) 23 + 10 24 val gen : ?g:Crypto_rng.g -> Z.t -> Z.t 25 + (** [gen ~g bound] generates a random integer in [\[0, bound)]. *) 26 + 11 27 val gen_r : ?g:Crypto_rng.g -> Z.t -> Z.t -> Z.t 28 + (** [gen_r ~g lo hi] generates a random integer in [\[lo, hi)]. *) 29 + 12 30 val gen_bits : ?g:Crypto_rng.g -> ?msb:int -> int -> Z.t 31 + (** [gen_bits ~g ~msb bits] generates a random [bits]-bit integer with the top 32 + [msb] bits set. *) 33 + 13 34 val prime : ?g:Crypto_rng.g -> ?msb:int -> int -> Z.t 35 + (** [prime ~g ~msb bits] generates a random [bits]-bit prime. *) 36 + 14 37 val safe_prime : ?g:Crypto_rng.g -> int -> Z.t * Z.t 38 + (** [safe_prime ~g bits] generates a safe prime [p] of [bits] bits and returns 39 + [(p, q)] where [p = 2q + 1]. *)
+2 -1
rng/entropy.mli
··· 38 38 (** [interrupt_hook ()] samples the cycle counter for entropy. *) 39 39 40 40 val timer_accumulator : Rng.g option -> unit -> unit 41 - (** [timer_accumulator g] is an accumulator feeding timer entropy into [g]. *) 41 + (** [timer_accumulator g ()] is an accumulator feeding timer entropy into [g]. 42 + *) 42 43 43 44 (** {1 Periodic pulled sources} *) 44 45
+1 -1
rng/unix/getentropy.mli
··· 25 25 (** [seeded ~g] is always [true]. *) 26 26 27 27 val pools : int 28 - (** Number of entropy pools (always [0]). *) 28 + (** [pools] is the number of entropy pools (always [0]). *)
+1 -1
rng/unix/urandom.mli
··· 22 22 (** [seeded ~g] is always [true]. *) 23 23 24 24 val pools : int 25 - (** Number of entropy pools (always [0]). *) 25 + (** [pools] is the number of entropy pools (always [0]). *)
+2 -1
src/chacha20.mli
··· 52 52 tag:string -> 53 53 string -> 54 54 string option 55 - (** Like {!authenticate_decrypt} with a separate [tag]. *) 55 + (** [authenticate_decrypt_tag ~key ~nonce ?adata ~tag data] is like 56 + {!authenticate_decrypt} with a separate [tag]. *) 56 57 57 58 val authenticate_encrypt_into : 58 59 key:key ->
+61 -1
src/cipher_block.mli
··· 51 51 (** [of_secret s] constructs a key from [s]. *) 52 52 53 53 val key_sizes : int array 54 - (** Supported key sizes. *) 54 + (** Supported key sizes in bytes. *) 55 55 56 56 val block_size : int 57 57 (** Block size in bytes. *) ··· 64 64 65 65 val encrypt_into : 66 66 key:key -> string -> src_off:int -> bytes -> dst_off:int -> int -> unit 67 + (** [encrypt_into ~key src ~src_off dst ~dst_off len] encrypts [len] bytes 68 + from [src] into [dst]. *) 67 69 68 70 val decrypt_into : 69 71 key:key -> string -> src_off:int -> bytes -> dst_off:int -> int -> unit 72 + (** [decrypt_into ~key src ~src_off dst ~dst_off len] decrypts [len] bytes 73 + from [src] into [dst]. *) 70 74 71 75 val unsafe_encrypt_into : 72 76 key:key -> string -> src_off:int -> bytes -> dst_off:int -> int -> unit 77 + (** Like {!encrypt_into} without bounds checking. *) 73 78 74 79 val unsafe_decrypt_into : 75 80 key:key -> string -> src_off:int -> bytes -> dst_off:int -> int -> unit 81 + (** Like {!decrypt_into} without bounds checking. *) 76 82 end 77 83 78 84 (** Cipher Block Chaining mode. *) 79 85 module type CBC = sig 80 86 type key 87 + (** Cipher key. *) 81 88 82 89 val of_secret : string -> key 90 + (** [of_secret s] constructs a key from [s]. *) 91 + 83 92 val key_sizes : int array 93 + (** Supported key sizes in bytes. *) 94 + 84 95 val block_size : int 96 + (** Block size in bytes. *) 97 + 85 98 val encrypt : key:key -> iv:string -> string -> string 99 + (** [encrypt ~key ~iv data] encrypts [data] with initialisation vector [iv]. 100 + *) 101 + 86 102 val decrypt : key:key -> iv:string -> string -> string 103 + (** [decrypt ~key ~iv data] decrypts [data]. *) 104 + 87 105 val next_iv : ?off:int -> string -> iv:string -> string 106 + (** [next_iv ~off ct ~iv] computes the IV for the next message from the last 107 + block of ciphertext [ct]. *) 88 108 89 109 val encrypt_into : 90 110 key:key -> ··· 95 115 dst_off:int -> 96 116 int -> 97 117 unit 118 + (** [encrypt_into ~key ~iv src ~src_off dst ~dst_off len] encrypts [len] 119 + bytes from [src] into [dst]. *) 98 120 99 121 val decrypt_into : 100 122 key:key -> ··· 105 127 dst_off:int -> 106 128 int -> 107 129 unit 130 + (** [decrypt_into ~key ~iv src ~src_off dst ~dst_off len] decrypts [len] 131 + bytes from [src] into [dst]. *) 108 132 109 133 val unsafe_encrypt_into : 110 134 key:key -> ··· 115 139 dst_off:int -> 116 140 int -> 117 141 unit 142 + (** Like {!encrypt_into} without bounds checking. *) 118 143 119 144 val unsafe_decrypt_into : 120 145 key:key -> ··· 125 150 dst_off:int -> 126 151 int -> 127 152 unit 153 + (** Like {!decrypt_into} without bounds checking. *) 128 154 129 155 val unsafe_encrypt_into_inplace : 130 156 key:key -> iv:string -> bytes -> dst_off:int -> int -> unit 157 + (** Like {!unsafe_encrypt_into} but encrypts the buffer in place. *) 131 158 end 132 159 133 160 (** Counter mode. *) 134 161 module type CTR = sig 135 162 type key 163 + (** Cipher key. *) 136 164 137 165 val of_secret : string -> key 166 + (** [of_secret s] constructs a key from [s]. *) 167 + 138 168 val key_sizes : int array 169 + (** Supported key sizes in bytes. *) 170 + 139 171 val block_size : int 172 + (** Block size in bytes. *) 140 173 141 174 type ctr 142 175 (** Counter value. *) 143 176 144 177 val add_ctr : ctr -> int64 -> ctr 178 + (** [add_ctr ctr n] increments [ctr] by [n]. *) 179 + 145 180 val next_ctr : ?off:int -> string -> ctr:ctr -> ctr 181 + (** [next_ctr ~off msg ~ctr] advances [ctr] past [msg]. *) 182 + 146 183 val ctr_of_octets : string -> ctr 184 + (** [ctr_of_octets s] decodes a counter from [s]. *) 185 + 147 186 val stream : key:key -> ctr:ctr -> int -> string 187 + (** [stream ~key ~ctr n] generates [n] bytes of key stream. *) 188 + 148 189 val encrypt : key:key -> ctr:ctr -> string -> string 190 + (** [encrypt ~key ~ctr data] encrypts [data]. *) 191 + 149 192 val decrypt : key:key -> ctr:ctr -> string -> string 193 + (** [decrypt ~key ~ctr data] decrypts [data]. *) 194 + 150 195 val stream_into : key:key -> ctr:ctr -> bytes -> off:int -> int -> unit 196 + (** [stream_into ~key ~ctr buf ~off len] writes [len] bytes of key stream 197 + into [buf]. *) 151 198 152 199 val encrypt_into : 153 200 key:key -> ··· 158 205 dst_off:int -> 159 206 int -> 160 207 unit 208 + (** [encrypt_into ~key ~ctr src ~src_off dst ~dst_off len] encrypts [len] 209 + bytes from [src] into [dst]. *) 161 210 162 211 val decrypt_into : 163 212 key:key -> ··· 168 217 dst_off:int -> 169 218 int -> 170 219 unit 220 + (** [decrypt_into ~key ~ctr src ~src_off dst ~dst_off len] decrypts [len] 221 + bytes from [src] into [dst]. *) 171 222 172 223 val unsafe_stream_into : 173 224 key:key -> ctr:ctr -> bytes -> off:int -> int -> unit 225 + (** Like {!stream_into} without bounds checking. *) 174 226 175 227 val unsafe_encrypt_into : 176 228 key:key -> ··· 181 233 dst_off:int -> 182 234 int -> 183 235 unit 236 + (** Like {!encrypt_into} without bounds checking. *) 184 237 185 238 val unsafe_decrypt_into : 186 239 key:key -> ··· 191 244 dst_off:int -> 192 245 int -> 193 246 unit 247 + (** Like {!decrypt_into} without bounds checking. *) 194 248 end 195 249 196 250 (** Galois/Counter Mode. *) ··· 198 252 include Aead.AEAD 199 253 200 254 val key_sizes : int array 255 + (** Supported key sizes in bytes. *) 256 + 201 257 val block_size : int 258 + (** Block size in bytes. *) 202 259 end 203 260 204 261 (** Counter with CBC-MAC (16-byte tag). *) ··· 206 263 include Aead.AEAD 207 264 208 265 val key_sizes : int array 266 + (** Supported key sizes in bytes. *) 267 + 209 268 val block_size : int 269 + (** Block size in bytes. *) 210 270 end 211 271 end 212 272
+5 -3
src/uncommon.mli
··· 3 3 Internal helpers shared across the crypto library. *) 4 4 5 5 val invalid_arg : ('a, Format.formatter, unit, 'b) format4 -> 'a 6 - (** [invalid_arg fmt ...] raises [Invalid_argument] with a formatted message 6 + (** [invalid_arg fmt] raises [Invalid_argument] with a formatted message 7 7 prefixed by ["Crypto: "]. *) 8 8 9 9 val ( // ) : int -> int -> int ··· 20 20 (** An iterator. *) 21 21 22 22 val iter2 : 'a -> 'a -> 'a iter 23 - (** [iter2 a b f] applies [f] to [a] then [b]. *) 23 + (** [iter2 a b] returns an iterator that applies its argument to [a] then [b]. 24 + *) 24 25 25 26 val iter3 : 'a -> 'a -> 'a -> 'a iter 26 - (** [iter3 a b c f] applies [f] to [a], [b], then [c]. *) 27 + (** [iter3 a b c] returns an iterator that applies its argument to [a], [b], 28 + then [c]. *) 27 29 28 30 val unsafe_xor_into : 29 31 string -> src_off:int -> bytes -> dst_off:int -> int -> unit