(* http://people.csail.mit.edu/rivest/pubs/RS14.pdf https://relrod.github.io/spritz/Crypto-Cipher-Spritz.html *) type ob = {nb : unit -> int; squeeze : int -> int array};; (* Every time that nS is called a new state is created and a record of functions is returned. *) (let nS key = (let s = Array.init 256 char_of_int and w = ref 1 and i = ref 0 and j = ref 0 and k = ref 0 and z = ref 0 and a = ref 0 and (+) a b = (a+b) land 255 and c = Char.code in (let swap i j = (let t = s.(i) in (s.(i) <- s.(j); s.(j) <- t)) in (let update _ = (i := !i + !w; j := !k + (c (s.(!j + c s.(!i)))); k := !i + !k + c s.(!j); swap !i !j) and crush _ = for v = 0 to 127 do if c s.(v) > c s.(255 - v) then swap v (255 - v) done and output _ = (z := c s.(!j + c s.(!i + c s.(!z + !k))); !z) in (let whip n = (for j = 0 to n - 1 do update () done; w := !w+2) in (let shuffle _ = whip 512; crush (); whip 512; crush (); whip 512; a := 0 in (let drip _ = ((if !a > 0 then shuffle ()); update (); output ()) and absorbn k = (if !a = 128 then shuffle ()); swap !a (128 + k); a := !a+1 in (let absorbb b = (absorbn (b land 15); absorbn (b asr 4)) in (let absorb i = for k = 0 to (String.length i) - 1 do absorbb (c i.[k]) done in (let keySetup = absorb in keySetup key; {nb = drip; squeeze = fun r -> ((if !a > 0 then shuffle ()); Array.init r (fun _ -> drip ()))} ))))))))) in (let rec ph x = ((if x > 15 then ph (x asr 4)); print_char "0123456789ABCDEF".[x land 15]) in let tst st = (let ox = nS(st) in for y = 0 to 12 do ph (ox.nb ()); print_char ' ' done; print_string ("... " ^ st); print_newline ()) in (* Page 30 of white paper. *) tst("ABC"); tst("spam"); tst("arcfour"); (let f = (nS "sizle").squeeze 12 in for j=0 to 11 do ph f.(j) done)))