From 52e5105dd161684745791451132de8acaf5bf9e8 Mon Sep 17 00:00:00 2001 From: Hannes Mehnert Date: Tue, 18 Jun 2024 15:06:44 +0200 Subject: [PATCH] add tailcall annotations, remove an argument from ccm's loop --- src/ccm.ml | 18 +++++++++--------- src/chacha20.ml | 2 +- src/cipher_block.ml | 2 +- src/cipher_stream.ml | 4 ++-- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/ccm.ml b/src/ccm.ml index a0e02ec6..ecee28ec 100644 --- a/src/ccm.ml +++ b/src/ccm.ml @@ -10,7 +10,7 @@ let encode_len buf ~off size value = | 0 -> Bytes.set_uint8 buf off num | m -> Bytes.set_uint8 buf (off + m) (num land 0xff); - ass (num lsr 8) (pred m) + (ass [@tailcall]) (num lsr 8) (pred m) in ass value (pred size) @@ -91,25 +91,25 @@ let crypto_core_into ~cipher ~mode ~key ~nonce ~adata src ~src_off dst ~dst_off cipher ~key (Bytes.unsafe_to_string block) ~src_off:dst_off block ~dst_off in - let cbcprep = + let iv = let rec doit iv iv_off block block_off = match Bytes.length block - block_off with | 0 -> Bytes.sub iv iv_off block_size | _ -> cbc (Bytes.unsafe_to_string iv) iv_off block block_off; - doit block block_off block (block_off + block_size) + (doit [@tailcall]) block block_off block (block_off + block_size) in doit (Bytes.make block_size '\x00') 0 cbcheader 0 in - let rec loop iv ctr src src_off dst dst_off len = + let rec loop ctr src src_off dst dst_off len = let cbcblock, cbc_off = match mode with | Encrypt -> src, src_off | Decrypt -> Bytes.unsafe_to_string dst, dst_off in if len = 0 then - iv + () else if len < block_size then begin let buf = Bytes.make block_size '\x00' in Bytes.unsafe_blit dst dst_off buf 0 len ; @@ -118,16 +118,16 @@ let crypto_core_into ~cipher ~mode ~key ~nonce ~adata src ~src_off dst ~dst_off unsafe_xor_into src ~src_off dst ~dst_off len ; Bytes.unsafe_blit_string cbcblock cbc_off buf 0 len ; Bytes.unsafe_fill buf len (block_size - len) '\x00'; - cbc (Bytes.unsafe_to_string buf) cbc_off iv 0 ; - iv + cbc (Bytes.unsafe_to_string buf) cbc_off iv 0 end else begin ctrblock ctr dst ; unsafe_xor_into src ~src_off dst ~dst_off block_size ; cbc cbcblock cbc_off iv 0 ; - loop iv (succ ctr) src (src_off + block_size) dst (dst_off + block_size) (len - block_size) + (loop [@tailcall]) (succ ctr) src (src_off + block_size) dst (dst_off + block_size) (len - block_size) end in - loop cbcprep 1 src src_off dst dst_off len + loop 1 src src_off dst dst_off len; + iv let crypto_core ~cipher ~mode ~key ~nonce ~adata data = let datalen = String.length data in diff --git a/src/chacha20.ml b/src/chacha20.ml index 00119b5c..2c70251d 100644 --- a/src/chacha20.ml +++ b/src/chacha20.ml @@ -65,7 +65,7 @@ let crypt_into ~key ~nonce ~ctr src ~src_off dst ~dst_off len = chacha20_block state (dst_off + i) dst ; Native.xor_into_bytes src (src_off + i) dst (dst_off + i) block ; inc state; - loop (i + block) (n - 1) + (loop [@tailcall]) (i + block) (n - 1) in loop 0 block_count diff --git a/src/cipher_block.ml b/src/cipher_block.ml index 5ac862c5..d430492f 100644 --- a/src/cipher_block.ml +++ b/src/cipher_block.ml @@ -234,7 +234,7 @@ module Modes = struct | b -> Native.xor_into_bytes iv iv_i dst dst_i block ; Core.encrypt ~key ~blocks:1 (Bytes.unsafe_to_string dst) dst_i dst dst_i ; - loop (Bytes.unsafe_to_string dst) dst_i (dst_i + block) (b - 1) + (loop [@tailcall]) (Bytes.unsafe_to_string dst) dst_i (dst_i + block) (b - 1) in loop iv 0 dst_off (len / block) diff --git a/src/cipher_stream.ml b/src/cipher_stream.ml index 67ee0a63..69bbae3f 100644 --- a/src/cipher_stream.ml +++ b/src/cipher_stream.ml @@ -26,7 +26,7 @@ module ARC4 = struct let j = (j + si + x) land 0xff in let sj = s.(j) in s.(i) <- sj ; s.(j) <- si ; - loop j (succ i) + (loop [@tailcall]) j (succ i) in ( loop 0 0 ; (0, 0, s) ) @@ -44,7 +44,7 @@ module ARC4 = struct s.(i) <- sj ; s.(j) <- si ; let k = s.((si + sj) land 0xff) in Bytes.set_uint8 res n (k lxor String.get_uint8 buf n); - mix i j (succ n) + (mix [@tailcall]) i j (succ n) in let key' = mix i j 0 in { key = key' ; message = Bytes.unsafe_to_string res }