371 lines
11 KiB
OCaml
371 lines
11 KiB
OCaml
module By = Digestif_by
|
|
module Bi = Digestif_bi
|
|
|
|
module type S = sig
|
|
type ctx
|
|
type kind = [ `RMD160 ]
|
|
|
|
val init : unit -> ctx
|
|
val unsafe_feed_bytes : ctx -> By.t -> int -> int -> unit
|
|
val unsafe_feed_bigstring : ctx -> Bi.t -> int -> int -> unit
|
|
val unsafe_get : ctx -> By.t
|
|
val dup : ctx -> ctx
|
|
end
|
|
|
|
module Int32 = struct
|
|
include Int32
|
|
|
|
let ( lsl ) = Int32.shift_left
|
|
let ( lsr ) = Int32.shift_right_logical
|
|
let ( asr ) = Int32.shift_right
|
|
let ( lor ) = Int32.logor
|
|
let ( lxor ) = Int32.logxor
|
|
let ( land ) = Int32.logand
|
|
let lnot = Int32.lognot
|
|
let ( + ) = Int32.add
|
|
let rol32 a n = (a lsl n) lor (a lsr (32 - n))
|
|
let ror32 a n = (a lsr n) lor (a lsl (32 - n))
|
|
end
|
|
|
|
module Int64 = struct
|
|
include Int64
|
|
|
|
let ( land ) = Int64.logand
|
|
let ( lsl ) = Int64.shift_left
|
|
end
|
|
|
|
module Unsafe : S = struct
|
|
type kind = [ `RMD160 ]
|
|
type ctx = { s : int32 array; mutable n : int; h : int32 array; b : Bytes.t }
|
|
|
|
let dup ctx =
|
|
{ s = Array.copy ctx.s; n = ctx.n; h = Array.copy ctx.h; b = By.copy ctx.b }
|
|
|
|
let init () =
|
|
let b = By.make 64 '\x00' in
|
|
{
|
|
s = [| 0l; 0l |];
|
|
n = 0;
|
|
b;
|
|
h = [| 0x67452301l; 0xefcdab89l; 0x98badcfel; 0x10325476l; 0xc3d2e1f0l |];
|
|
}
|
|
|
|
let f x y z = Int32.(x lxor y lxor z)
|
|
let g x y z = Int32.(x land y lor (lnot x land z))
|
|
let h x y z = Int32.(x lor lnot y lxor z)
|
|
let i x y z = Int32.(x land z lor (y land lnot z))
|
|
let j x y z = Int32.(x lxor (y lor lnot z))
|
|
|
|
let ff a b c d e x s =
|
|
let open Int32 in
|
|
a := !a + f !b !c !d + x ;
|
|
a := rol32 !a s + !e ;
|
|
c := rol32 !c 10
|
|
|
|
let gg a b c d e x s =
|
|
let open Int32 in
|
|
a := !a + g !b !c !d + x + 0x5a827999l ;
|
|
a := rol32 !a s + !e ;
|
|
c := rol32 !c 10
|
|
|
|
let hh a b c d e x s =
|
|
let open Int32 in
|
|
a := !a + h !b !c !d + x + 0x6ed9eba1l ;
|
|
a := rol32 !a s + !e ;
|
|
c := rol32 !c 10
|
|
|
|
let ii a b c d e x s =
|
|
let open Int32 in
|
|
a := !a + i !b !c !d + x + 0x8f1bbcdcl ;
|
|
a := rol32 !a s + !e ;
|
|
c := rol32 !c 10
|
|
|
|
let jj a b c d e x s =
|
|
let open Int32 in
|
|
a := !a + j !b !c !d + x + 0xa953fd4el ;
|
|
a := rol32 !a s + !e ;
|
|
c := rol32 !c 10
|
|
|
|
let fff a b c d e x s =
|
|
let open Int32 in
|
|
a := !a + f !b !c !d + x ;
|
|
a := rol32 !a s + !e ;
|
|
c := rol32 !c 10
|
|
|
|
let ggg a b c d e x s =
|
|
let open Int32 in
|
|
a := !a + g !b !c !d + x + 0x7a6d76e9l ;
|
|
a := rol32 !a s + !e ;
|
|
c := rol32 !c 10
|
|
|
|
let hhh a b c d e x s =
|
|
let open Int32 in
|
|
a := !a + h !b !c !d + x + 0x6d703ef3l ;
|
|
a := rol32 !a s + !e ;
|
|
c := rol32 !c 10
|
|
|
|
let iii a b c d e x s =
|
|
let open Int32 in
|
|
a := !a + i !b !c !d + x + 0x5c4dd124l ;
|
|
a := rol32 !a s + !e ;
|
|
c := rol32 !c 10
|
|
|
|
let jjj a b c d e x s =
|
|
let open Int32 in
|
|
a := !a + j !b !c !d + x + 0x50a28be6l ;
|
|
a := rol32 !a s + !e ;
|
|
c := rol32 !c 10
|
|
|
|
let rmd160_do_chunk :
|
|
type a. le32_to_cpu:(a -> int -> int32) -> ctx -> a -> int -> unit =
|
|
fun ~le32_to_cpu ctx buff off ->
|
|
let aa, bb, cc, dd, ee, aaa, bbb, ccc, ddd, eee =
|
|
( ref ctx.h.(0),
|
|
ref ctx.h.(1),
|
|
ref ctx.h.(2),
|
|
ref ctx.h.(3),
|
|
ref ctx.h.(4),
|
|
ref ctx.h.(0),
|
|
ref ctx.h.(1),
|
|
ref ctx.h.(2),
|
|
ref ctx.h.(3),
|
|
ref ctx.h.(4) ) in
|
|
let w = Array.make 16 0l in
|
|
for i = 0 to 15 do
|
|
w.(i) <- le32_to_cpu buff (off + (i * 4))
|
|
done ;
|
|
ff aa bb cc dd ee w.(0) 11 ;
|
|
ff ee aa bb cc dd w.(1) 14 ;
|
|
ff dd ee aa bb cc w.(2) 15 ;
|
|
ff cc dd ee aa bb w.(3) 12 ;
|
|
ff bb cc dd ee aa w.(4) 5 ;
|
|
ff aa bb cc dd ee w.(5) 8 ;
|
|
ff ee aa bb cc dd w.(6) 7 ;
|
|
ff dd ee aa bb cc w.(7) 9 ;
|
|
ff cc dd ee aa bb w.(8) 11 ;
|
|
ff bb cc dd ee aa w.(9) 13 ;
|
|
ff aa bb cc dd ee w.(10) 14 ;
|
|
ff ee aa bb cc dd w.(11) 15 ;
|
|
ff dd ee aa bb cc w.(12) 6 ;
|
|
ff cc dd ee aa bb w.(13) 7 ;
|
|
ff bb cc dd ee aa w.(14) 9 ;
|
|
ff aa bb cc dd ee w.(15) 8 ;
|
|
gg ee aa bb cc dd w.(7) 7 ;
|
|
gg dd ee aa bb cc w.(4) 6 ;
|
|
gg cc dd ee aa bb w.(13) 8 ;
|
|
gg bb cc dd ee aa w.(1) 13 ;
|
|
gg aa bb cc dd ee w.(10) 11 ;
|
|
gg ee aa bb cc dd w.(6) 9 ;
|
|
gg dd ee aa bb cc w.(15) 7 ;
|
|
gg cc dd ee aa bb w.(3) 15 ;
|
|
gg bb cc dd ee aa w.(12) 7 ;
|
|
gg aa bb cc dd ee w.(0) 12 ;
|
|
gg ee aa bb cc dd w.(9) 15 ;
|
|
gg dd ee aa bb cc w.(5) 9 ;
|
|
gg cc dd ee aa bb w.(2) 11 ;
|
|
gg bb cc dd ee aa w.(14) 7 ;
|
|
gg aa bb cc dd ee w.(11) 13 ;
|
|
gg ee aa bb cc dd w.(8) 12 ;
|
|
hh dd ee aa bb cc w.(3) 11 ;
|
|
hh cc dd ee aa bb w.(10) 13 ;
|
|
hh bb cc dd ee aa w.(14) 6 ;
|
|
hh aa bb cc dd ee w.(4) 7 ;
|
|
hh ee aa bb cc dd w.(9) 14 ;
|
|
hh dd ee aa bb cc w.(15) 9 ;
|
|
hh cc dd ee aa bb w.(8) 13 ;
|
|
hh bb cc dd ee aa w.(1) 15 ;
|
|
hh aa bb cc dd ee w.(2) 14 ;
|
|
hh ee aa bb cc dd w.(7) 8 ;
|
|
hh dd ee aa bb cc w.(0) 13 ;
|
|
hh cc dd ee aa bb w.(6) 6 ;
|
|
hh bb cc dd ee aa w.(13) 5 ;
|
|
hh aa bb cc dd ee w.(11) 12 ;
|
|
hh ee aa bb cc dd w.(5) 7 ;
|
|
hh dd ee aa bb cc w.(12) 5 ;
|
|
ii cc dd ee aa bb w.(1) 11 ;
|
|
ii bb cc dd ee aa w.(9) 12 ;
|
|
ii aa bb cc dd ee w.(11) 14 ;
|
|
ii ee aa bb cc dd w.(10) 15 ;
|
|
ii dd ee aa bb cc w.(0) 14 ;
|
|
ii cc dd ee aa bb w.(8) 15 ;
|
|
ii bb cc dd ee aa w.(12) 9 ;
|
|
ii aa bb cc dd ee w.(4) 8 ;
|
|
ii ee aa bb cc dd w.(13) 9 ;
|
|
ii dd ee aa bb cc w.(3) 14 ;
|
|
ii cc dd ee aa bb w.(7) 5 ;
|
|
ii bb cc dd ee aa w.(15) 6 ;
|
|
ii aa bb cc dd ee w.(14) 8 ;
|
|
ii ee aa bb cc dd w.(5) 6 ;
|
|
ii dd ee aa bb cc w.(6) 5 ;
|
|
ii cc dd ee aa bb w.(2) 12 ;
|
|
jj bb cc dd ee aa w.(4) 9 ;
|
|
jj aa bb cc dd ee w.(0) 15 ;
|
|
jj ee aa bb cc dd w.(5) 5 ;
|
|
jj dd ee aa bb cc w.(9) 11 ;
|
|
jj cc dd ee aa bb w.(7) 6 ;
|
|
jj bb cc dd ee aa w.(12) 8 ;
|
|
jj aa bb cc dd ee w.(2) 13 ;
|
|
jj ee aa bb cc dd w.(10) 12 ;
|
|
jj dd ee aa bb cc w.(14) 5 ;
|
|
jj cc dd ee aa bb w.(1) 12 ;
|
|
jj bb cc dd ee aa w.(3) 13 ;
|
|
jj aa bb cc dd ee w.(8) 14 ;
|
|
jj ee aa bb cc dd w.(11) 11 ;
|
|
jj dd ee aa bb cc w.(6) 8 ;
|
|
jj cc dd ee aa bb w.(15) 5 ;
|
|
jj bb cc dd ee aa w.(13) 6 ;
|
|
jjj aaa bbb ccc ddd eee w.(5) 8 ;
|
|
jjj eee aaa bbb ccc ddd w.(14) 9 ;
|
|
jjj ddd eee aaa bbb ccc w.(7) 9 ;
|
|
jjj ccc ddd eee aaa bbb w.(0) 11 ;
|
|
jjj bbb ccc ddd eee aaa w.(9) 13 ;
|
|
jjj aaa bbb ccc ddd eee w.(2) 15 ;
|
|
jjj eee aaa bbb ccc ddd w.(11) 15 ;
|
|
jjj ddd eee aaa bbb ccc w.(4) 5 ;
|
|
jjj ccc ddd eee aaa bbb w.(13) 7 ;
|
|
jjj bbb ccc ddd eee aaa w.(6) 7 ;
|
|
jjj aaa bbb ccc ddd eee w.(15) 8 ;
|
|
jjj eee aaa bbb ccc ddd w.(8) 11 ;
|
|
jjj ddd eee aaa bbb ccc w.(1) 14 ;
|
|
jjj ccc ddd eee aaa bbb w.(10) 14 ;
|
|
jjj bbb ccc ddd eee aaa w.(3) 12 ;
|
|
jjj aaa bbb ccc ddd eee w.(12) 6 ;
|
|
iii eee aaa bbb ccc ddd w.(6) 9 ;
|
|
iii ddd eee aaa bbb ccc w.(11) 13 ;
|
|
iii ccc ddd eee aaa bbb w.(3) 15 ;
|
|
iii bbb ccc ddd eee aaa w.(7) 7 ;
|
|
iii aaa bbb ccc ddd eee w.(0) 12 ;
|
|
iii eee aaa bbb ccc ddd w.(13) 8 ;
|
|
iii ddd eee aaa bbb ccc w.(5) 9 ;
|
|
iii ccc ddd eee aaa bbb w.(10) 11 ;
|
|
iii bbb ccc ddd eee aaa w.(14) 7 ;
|
|
iii aaa bbb ccc ddd eee w.(15) 7 ;
|
|
iii eee aaa bbb ccc ddd w.(8) 12 ;
|
|
iii ddd eee aaa bbb ccc w.(12) 7 ;
|
|
iii ccc ddd eee aaa bbb w.(4) 6 ;
|
|
iii bbb ccc ddd eee aaa w.(9) 15 ;
|
|
iii aaa bbb ccc ddd eee w.(1) 13 ;
|
|
iii eee aaa bbb ccc ddd w.(2) 11 ;
|
|
hhh ddd eee aaa bbb ccc w.(15) 9 ;
|
|
hhh ccc ddd eee aaa bbb w.(5) 7 ;
|
|
hhh bbb ccc ddd eee aaa w.(1) 15 ;
|
|
hhh aaa bbb ccc ddd eee w.(3) 11 ;
|
|
hhh eee aaa bbb ccc ddd w.(7) 8 ;
|
|
hhh ddd eee aaa bbb ccc w.(14) 6 ;
|
|
hhh ccc ddd eee aaa bbb w.(6) 6 ;
|
|
hhh bbb ccc ddd eee aaa w.(9) 14 ;
|
|
hhh aaa bbb ccc ddd eee w.(11) 12 ;
|
|
hhh eee aaa bbb ccc ddd w.(8) 13 ;
|
|
hhh ddd eee aaa bbb ccc w.(12) 5 ;
|
|
hhh ccc ddd eee aaa bbb w.(2) 14 ;
|
|
hhh bbb ccc ddd eee aaa w.(10) 13 ;
|
|
hhh aaa bbb ccc ddd eee w.(0) 13 ;
|
|
hhh eee aaa bbb ccc ddd w.(4) 7 ;
|
|
hhh ddd eee aaa bbb ccc w.(13) 5 ;
|
|
ggg ccc ddd eee aaa bbb w.(8) 15 ;
|
|
ggg bbb ccc ddd eee aaa w.(6) 5 ;
|
|
ggg aaa bbb ccc ddd eee w.(4) 8 ;
|
|
ggg eee aaa bbb ccc ddd w.(1) 11 ;
|
|
ggg ddd eee aaa bbb ccc w.(3) 14 ;
|
|
ggg ccc ddd eee aaa bbb w.(11) 14 ;
|
|
ggg bbb ccc ddd eee aaa w.(15) 6 ;
|
|
ggg aaa bbb ccc ddd eee w.(0) 14 ;
|
|
ggg eee aaa bbb ccc ddd w.(5) 6 ;
|
|
ggg ddd eee aaa bbb ccc w.(12) 9 ;
|
|
ggg ccc ddd eee aaa bbb w.(2) 12 ;
|
|
ggg bbb ccc ddd eee aaa w.(13) 9 ;
|
|
ggg aaa bbb ccc ddd eee w.(9) 12 ;
|
|
ggg eee aaa bbb ccc ddd w.(7) 5 ;
|
|
ggg ddd eee aaa bbb ccc w.(10) 15 ;
|
|
ggg ccc ddd eee aaa bbb w.(14) 8 ;
|
|
fff bbb ccc ddd eee aaa w.(12) 8 ;
|
|
fff aaa bbb ccc ddd eee w.(15) 5 ;
|
|
fff eee aaa bbb ccc ddd w.(10) 12 ;
|
|
fff ddd eee aaa bbb ccc w.(4) 9 ;
|
|
fff ccc ddd eee aaa bbb w.(1) 12 ;
|
|
fff bbb ccc ddd eee aaa w.(5) 5 ;
|
|
fff aaa bbb ccc ddd eee w.(8) 14 ;
|
|
fff eee aaa bbb ccc ddd w.(7) 6 ;
|
|
fff ddd eee aaa bbb ccc w.(6) 8 ;
|
|
fff ccc ddd eee aaa bbb w.(2) 13 ;
|
|
fff bbb ccc ddd eee aaa w.(13) 6 ;
|
|
fff aaa bbb ccc ddd eee w.(14) 5 ;
|
|
fff eee aaa bbb ccc ddd w.(0) 15 ;
|
|
fff ddd eee aaa bbb ccc w.(3) 13 ;
|
|
fff ccc ddd eee aaa bbb w.(9) 11 ;
|
|
fff bbb ccc ddd eee aaa w.(11) 11 ;
|
|
let open Int32 in
|
|
ddd := !ddd + !cc + ctx.h.(1) ;
|
|
(* final result for h[0]. *)
|
|
ctx.h.(1) <- ctx.h.(2) + !dd + !eee ;
|
|
ctx.h.(2) <- ctx.h.(3) + !ee + !aaa ;
|
|
ctx.h.(3) <- ctx.h.(4) + !aa + !bbb ;
|
|
ctx.h.(4) <- ctx.h.(0) + !bb + !ccc ;
|
|
ctx.h.(0) <- !ddd ;
|
|
()
|
|
|
|
exception Leave
|
|
|
|
let feed :
|
|
type a.
|
|
le32_to_cpu:(a -> int -> int32) ->
|
|
blit:(a -> int -> By.t -> int -> int -> unit) ->
|
|
ctx ->
|
|
a ->
|
|
int ->
|
|
int ->
|
|
unit =
|
|
fun ~le32_to_cpu ~blit ctx buf off len ->
|
|
let t = ref ctx.s.(0) in
|
|
let off = ref off in
|
|
let len = ref len in
|
|
ctx.s.(0) <- Int32.add !t (Int32.of_int (!len lsl 3)) ;
|
|
if ctx.s.(0) < !t then ctx.s.(1) <- Int32.(ctx.s.(1) + 1l) ;
|
|
ctx.s.(1) <- Int32.add ctx.s.(1) (Int32.of_int (!len lsr 29)) ;
|
|
try
|
|
if ctx.n <> 0
|
|
then (
|
|
let t = 64 - ctx.n in
|
|
if !len < t
|
|
then (
|
|
blit buf !off ctx.b ctx.n !len ;
|
|
ctx.n <- ctx.n + !len ;
|
|
raise Leave) ;
|
|
blit buf !off ctx.b ctx.n t ;
|
|
rmd160_do_chunk ~le32_to_cpu:By.le32_to_cpu ctx ctx.b 0 ;
|
|
off := !off + t ;
|
|
len := !len - t) ;
|
|
while !len >= 64 do
|
|
rmd160_do_chunk ~le32_to_cpu ctx buf !off ;
|
|
off := !off + 64 ;
|
|
len := !len - 64
|
|
done ;
|
|
blit buf !off ctx.b 0 !len ;
|
|
ctx.n <- !len
|
|
with Leave -> ()
|
|
|
|
let unsafe_feed_bytes ctx buf off len =
|
|
feed ~blit:By.blit ~le32_to_cpu:By.le32_to_cpu ctx buf off len
|
|
|
|
let unsafe_feed_bigstring ctx buf off len =
|
|
feed ~blit:By.blit_from_bigstring ~le32_to_cpu:Bi.le32_to_cpu ctx buf off
|
|
len
|
|
|
|
let unsafe_get ctx =
|
|
let i = ref (ctx.n + 1) in
|
|
let res = By.create (5 * 4) in
|
|
By.set ctx.b ctx.n '\x80' ;
|
|
if !i > 56
|
|
then (
|
|
By.fill ctx.b !i (64 - !i) '\x00' ;
|
|
rmd160_do_chunk ~le32_to_cpu:By.le32_to_cpu ctx ctx.b 0 ;
|
|
i := 0) ;
|
|
By.fill ctx.b !i (56 - !i) '\x00' ;
|
|
By.cpu_to_le32 ctx.b 56 ctx.s.(0) ;
|
|
By.cpu_to_le32 ctx.b 60 ctx.s.(1) ;
|
|
rmd160_do_chunk ~le32_to_cpu:By.le32_to_cpu ctx ctx.b 0 ;
|
|
for i = 0 to 4 do
|
|
By.cpu_to_le32 res (i * 4) ctx.h.(i)
|
|
done ;
|
|
res
|
|
end
|