cryptgps/ 40755 764 144 0 7402536414 11166 5ustar gerduserscryptgps/Makefile100644 764 144 4616 7325627131 12733 0ustar gerdusers# make all: make bytecode archive # make opt: make native archive # make install: install bytecode archive, and if present, native archive # make uninstall: uninstall package # make clean: remove intermediate files # make distclean: remove any superflous files # make release: cleanup, create archive, tag CVS module # (for developers) #---------------------------------------------------------------------- # specific rules for this package: OBJECTS = crypt_aux.cmo \ cryptsystem_64.cmo cryptmodes_64.cmo \ crypt_blowfish.cmo crypt_des.cmo crypt_3des.cmo \ crypt_blowfish32.cmo XOBJECTS = crypt_aux.cmx \ cryptsystem_64.cmx cryptmodes_64.cmx \ crypt_blowfish.cmx crypt_des.cmx crypt_3des.cmx \ crypt_blowfish32.cmx ARCHIVE = cryptgps.cma XARCHIVE = cryptgps.cmxa NAME = cryptgps REQUIRES = all: $(ARCHIVE) opt: $(XARCHIVE) $(ARCHIVE): $(OBJECTS) $(OCAMLC) -a -o $(ARCHIVE) $(OBJECTS) $(XARCHIVE): $(XOBJECTS) $(OCAMLOPT) -a -o $(XARCHIVE) $(XOBJECTS) #---------------------------------------------------------------------- # general rules: OPTIONS = OCAMLC = ocamlc -g $(OPTIONS) $(ROPTIONS) OCAMLOPT = ocamlopt $(OPTIONS) $(ROPTIONS) OCAMLDEP = ocamldep $(OPTIONS) OCAMLFIND = ocamlfind depend: *.ml *.mli $(OCAMLDEP) *.ml *.mli >depend depend.pkg: Makefile $(OCAMLFIND) use -p ROPTIONS= $(REQUIRES) >depend.pkg .PHONY: install install: all { test ! -f $(XARCHIVE) || extra="*.cmxa *.a"; }; \ $(OCAMLFIND) install $(NAME) *.mli *.cmi *.cma META $$extra .PHONY: uninstall uninstall: $(OCAMLFIND) remove $(NAME) .PHONY: clean clean: rm -f *.cmi *.cmo *.cma *.cmx *.o *.a *.cmxa .PHONY: distclean distclean: clean rm -f *~ depend depend.pkg (cd cmp_cryptgps; rm -f *~) $(MAKE) -C cmp_ssleay distclean $(MAKE) -C test distclean RELEASE: META awk '/version/ { print substr($$3,2,length($$3)-2) }' META >RELEASE .PHONY: dist dist: RELEASE r=`head -1 RELEASE`; cd ..; gtar czf $(NAME)-$$r.tar.gz --exclude='*/CVS*' --exclude="*/depend.pkg" --exclude="*/depend" $(NAME) .PHONY: tag-release tag-release: RELEASE r=`head -1 RELEASE | sed -e s/\\\./-/g`; cd ..; cvs tag -F $(NAME)-$$r $(NAME) .PHONY: release release: distclean $(MAKE) tag-release $(MAKE) dist .ml.cmx: $(OCAMLOPT) -inline 10000 -unsafe -c $< .ml.cmo: $(OCAMLC) -c $< .mli.cmi: $(OCAMLC) -c $< .SUFFIXES: .cmo .cmi .cmx .ml .mli include depend include depend.pkg cryptgps/cmp_cryptgps/ 40755 764 144 0 7252455046 13704 5ustar gerduserscryptgps/cmp_cryptgps/blowfish100755 764 144 2653 7252447544 15556 0ustar gerdusers#! /bin/sh # (* exec ./top "$0" *) directory "..";; #load "cryptgps.cma";; open Crypt_blowfish;; open Cryptsystem;; open Cryptmodes;; let k = prepare "abcdefghijklmnop";; let print s = let l = String.length s in for i = 0 to l/2-1 do let j = 2*i in print_char ' '; print_int ((Char.code(s.[j]) lsl 8 ) lor (Char.code(s.[j+1]))) done ;; let (x3,x2,x1,x0) = encrypt_ecb k (0x3132,0x3334,0x3536,0x3738);; Printf.printf "Result ECB: %d %d %d %d\n" x3 x2 x1 x0;; let (v, s) = encrypt_cbc k (0,0,0,0) "12345678abcdefgh";; print_string "Result CBC:"; print s; print_newline() ;; let (v, s) = encrypt_cfb8 k (0,0,0,0) "12345678abcdefgh";; print_string "Result CFB-8:"; print s; print_newline() ;; let (v, _, s) = encrypt_cfb64 k (0,0,0,0) 0 "12345678abcdefgh";; print_string "Result CFB-64:"; print s; print_newline() ;; let (x3,x2,x1,x0) = decrypt_ecb k (0x3132,0x3334,0x3536,0x3738);; Printf.printf "Result de-ECB: %d %d %d %d\n" x3 x2 x1 x0;; let (v, s) = decrypt_cbc k (0,0,0,0) "12345678abcdefgh";; print_string "Result de-CBC:"; print s; print_newline() ;; let (v, s) = decrypt_cfb8 k (0,0,0,0) "12345678abcdefgh";; print_string "Result de-CFB-8:"; print s; print_newline() ;; let (v, _, s) = decrypt_cfb64 k (0,0,0,0) 0 "12345678abcdefgh";; print_string "Result de-CFB-64:"; print s; print_newline() ;; let (v, _, s) = crypt_ofb k (0,0,0,0) 0 "12345678abcdefgh";; print_string "Result OFB:"; print s; print_newline() ;; cryptgps/cmp_cryptgps/des100755 764 144 1507 6731767562 14517 0ustar gerdusers#! /bin/sh # (* exec ocaml "$0" *) directory "..";; #load "cryptgps.cma";; open Crypt_des;; open Cryptsystem;; open Cryptmodes;; let k = prepare (set_parity "abcdefgh");; let print s = let l = String.length s in for i = 0 to l/2-1 do let j = 2*i in print_char ' '; print_int ((Char.code(s.[j]) lsl 8 ) lor (Char.code(s.[j+1]))) done ;; let (x3,x2,x1,x0) = encrypt_ecb k (0x3132,0x3334,0x3536,0x3738);; Printf.printf "Result ECB: %d %d %d %d\n" x3 x2 x1 x0;; let (v, s) = encrypt_cbc k (0,0,0,0) "12345678abcdefgh";; print_string "Result CBC:"; print s; print_newline() ;; let (v, _, s) = encrypt_cfb64 k (0,0,0,0) 0 "12345678abcdefgh";; print_string "Result CFB-64:"; print s; print_newline() ;; let (v, _, s) = crypt_ofb k (0,0,0,0) 0 "12345678abcdefgh";; print_string "Result OFB:"; print s; print_newline() ;; cryptgps/cmp_cryptgps/3des100755 764 144 1530 6732271250 14557 0ustar gerdusers#! /bin/sh # (* exec ocaml "$0" *) directory "..";; #load "cryptgps.cma";; open Crypt_3des;; open Cryptsystem;; open Cryptmodes;; let k = prepare (set_parity "abcdefghijklmnopqrstuvwx");; let print s = let l = String.length s in for i = 0 to l/2-1 do let j = 2*i in print_char ' '; print_int ((Char.code(s.[j]) lsl 8 ) lor (Char.code(s.[j+1]))) done ;; let (x3,x2,x1,x0) = encrypt_ecb k (0x3132,0x3334,0x3536,0x3738);; Printf.printf "Result ECB: %d %d %d %d\n" x3 x2 x1 x0;; let (v, s) = encrypt_cbc k (0,0,0,0) "12345678abcdefgh";; print_string "Result CBC:"; print s; print_newline() ;; let (v, _, s) = encrypt_cfb64 k (0,0,0,0) 0 "12345678abcdefgh";; print_string "Result CFB-64:"; print s; print_newline() ;; let (v, _, s) = crypt_ofb k (0,0,0,0) 0 "12345678abcdefgh";; print_string "Result OFB:"; print s; print_newline() ;; cryptgps/cmp_cryptgps/blowfish32100755 764 144 2662 7252447604 15720 0ustar gerdusers#! /bin/sh # (* exec ./top "$0" "$@" *) directory "..";; #load "cryptgps.cma";; open Crypt_blowfish32;; open Cryptsystem;; open Cryptmodes;; let k = prepare "abcdefghijklmnop";; let print s = let l = String.length s in for i = 0 to l/2-1 do let j = 2*i in print_char ' '; print_int ((Char.code(s.[j]) lsl 8 ) lor (Char.code(s.[j+1]))) done ;; let (x3,x2,x1,x0) = encrypt_ecb k (0x3132,0x3334,0x3536,0x3738);; Printf.printf "Result ECB: %d %d %d %d\n" x3 x2 x1 x0;; let (v, s) = encrypt_cbc k (0,0,0,0) "12345678abcdefgh";; print_string "Result CBC:"; print s; print_newline() ;; let (v, s) = encrypt_cfb8 k (0,0,0,0) "12345678abcdefgh";; print_string "Result CFB-8:"; print s; print_newline() ;; let (v, _, s) = encrypt_cfb64 k (0,0,0,0) 0 "12345678abcdefgh";; print_string "Result CFB-64:"; print s; print_newline() ;; let (x3,x2,x1,x0) = decrypt_ecb k (0x3132,0x3334,0x3536,0x3738);; Printf.printf "Result de-ECB: %d %d %d %d\n" x3 x2 x1 x0;; let (v, s) = decrypt_cbc k (0,0,0,0) "12345678abcdefgh";; print_string "Result de-CBC:"; print s; print_newline() ;; let (v, s) = decrypt_cfb8 k (0,0,0,0) "12345678abcdefgh";; print_string "Result de-CFB-8:"; print s; print_newline() ;; let (v, _, s) = decrypt_cfb64 k (0,0,0,0) 0 "12345678abcdefgh";; print_string "Result de-CFB-64:"; print s; print_newline() ;; let (v, _, s) = crypt_ofb k (0,0,0,0) 0 "12345678abcdefgh";; print_string "Result OFB:"; print s; print_newline() ;; cryptgps/cmp_cryptgps/Makefile100664 764 144 106 7252444066 15420 0ustar gerduserstop: ocamlfind ocamlmktop -o top -package bigarray -custom -linkpkg cryptgps/cmp_ssleay/ 40755 764 144 0 7252455046 13331 5ustar gerduserscryptgps/cmp_ssleay/Makefile100644 764 144 510 6732311243 15032 0ustar gerdusersSSLEAY_INCL = /usr/ssl/include SSLEAY_LIB = /usr/ssl/lib CC = gcc -I$(SSLEAY_INCL) -L$(SSLEAY_LIB) all: blowfish des 3des blowfish: blowfish.c $(CC) -o blowfish blowfish.c -lcrypto des: des.c $(CC) -o des des.c -lcrypto 3des: 3des.c $(CC) -o 3des 3des.c -lcrypto clean: rm -f blowfish des 3des distclean: clean rm -f *~ cryptgps/cmp_ssleay/blowfish.c100644 764 144 2321 6726017343 15404 0ustar gerdusers#include #include "blowfish.h" void print4(unsigned char *p) { int x3,x2,x1,x0; x3 = p[0] << 8 | p[1]; x2 = p[2] << 8 | p[3]; x1 = p[4] << 8 | p[5]; x0 = p[6] << 8 | p[7]; printf(" %d %d %d %d", x3, x2, x1, x0); } main () { BF_KEY k; unsigned char out8[8]; unsigned char out16[16]; unsigned char ivec[8]; int i, num; BF_set_key(&k, 16, "abcdefghijklmnop"); /* ECB TEST */ BF_ecb_encrypt("12345678", out8, &k, 1); printf("Result ECB:"); print4(out8); printf("\n"); /* CBC TEST */ for (i=0; i<8; i++) ivec[i] = 0; BF_cbc_encrypt("12345678abcdefgh", out16, 16, &k, ivec, 1); printf("Result CBC:"); print4(out16); print4(out16+8); printf("\n"); /* CFB-64 TEST */ for (i=0; i<8; i++) ivec[i] = 0; num = 0; BF_cfb64_encrypt("12345678abcdefgh", out16, 16, &k, ivec, &num, 1); printf("Result CFB-64:"); print4(out16); print4(out16+8); printf("\n"); /* OFB TEST */ for (i=0; i<8; i++) ivec[i] = 0; num = 0; BF_ofb64_encrypt("12345678abcdefgh", out16, 16, &k, ivec, &num); printf("Result OFB:"); print4(out16); print4(out16+8); printf("\n"); } cryptgps/cmp_ssleay/des.c100644 764 144 2306 6731770214 14344 0ustar gerdusers#include #include "des.h" void print4(unsigned char *p) { int x3,x2,x1,x0; x3 = p[0] << 8 | p[1]; x2 = p[2] << 8 | p[3]; x1 = p[4] << 8 | p[5]; x0 = p[6] << 8 | p[7]; printf(" %d %d %d %d", x3, x2, x1, x0); } main () { des_key_schedule k; unsigned char out8[8]; unsigned char out16[16]; unsigned char ivec[8]; int i, num; des_set_key("abcdefgh",k); /* ECB TEST */ des_ecb_encrypt("12345678", out8, k, 1); printf("Result ECB:"); print4(out8); printf("\n"); /* CBC TEST */ for (i=0; i<8; i++) ivec[i] = 0; des_cbc_encrypt("12345678abcdefgh", out16, 16, k, ivec, 1); printf("Result CBC:"); print4(out16); print4(out16+8); printf("\n"); /* CFB-64 TEST */ for (i=0; i<8; i++) ivec[i] = 0; num = 0; des_cfb64_encrypt("12345678abcdefgh", out16, 16, k, ivec, &num, 1); printf("Result CFB-64:"); print4(out16); print4(out16+8); printf("\n"); /* OFB TEST */ for (i=0; i<8; i++) ivec[i] = 0; num = 0; des_ofb64_encrypt("12345678abcdefgh", out16, 16, k, ivec, &num); printf("Result OFB:"); print4(out16); print4(out16+8); printf("\n"); } cryptgps/cmp_ssleay/3des.c100644 764 144 2502 6732271535 14430 0ustar gerdusers#include #include "des.h" void print4(unsigned char *p) { int x3,x2,x1,x0; x3 = p[0] << 8 | p[1]; x2 = p[2] << 8 | p[3]; x1 = p[4] << 8 | p[5]; x0 = p[6] << 8 | p[7]; printf(" %d %d %d %d", x3, x2, x1, x0); } main () { des_key_schedule k1,k2,k3; unsigned char out8[8]; unsigned char out16[16]; unsigned char ivec[8]; int i, num; des_set_key("abcdefgh",k1); des_set_key("ijklmnop",k2); des_set_key("qrstuvwx",k3); /* ECB TEST */ des_ecb3_encrypt("12345678", out8, k1, k2, k3, 1); printf("Result ECB:"); print4(out8); printf("\n"); /* CBC TEST */ for (i=0; i<8; i++) ivec[i] = 0; des_ede3_cbc_encrypt("12345678abcdefgh", out16, 16, k1, k2, k3, ivec, 1); printf("Result CBC:"); print4(out16); print4(out16+8); printf("\n"); /* CFB-64 TEST */ for (i=0; i<8; i++) ivec[i] = 0; num = 0; des_ede3_cfb64_encrypt("12345678abcdefgh", out16, 16, k1, k2, k3, ivec, &num, 1); printf("Result CFB-64:"); print4(out16); print4(out16+8); printf("\n"); /* OFB TEST */ for (i=0; i<8; i++) ivec[i] = 0; num = 0; des_ede3_ofb64_encrypt("12345678abcdefgh", out16, 16, k1, k2, k3, ivec, &num); printf("Result OFB:"); print4(out16); print4(out16+8); printf("\n"); } cryptgps/LICENSE100644 764 144 2061 6735407375 12302 0ustar gerdusersCopyright 1999 by Gerd Stolpmann The package "cryptgps" is copyright by Gerd Stolpmann. Permission is hereby granted, free of charge, to any person obtaining a copy of the "cryptgps" software (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. The Software is provided ``as is'', without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall Gerd Stolpmann be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the Software or the use or other dealings in the software. cryptgps/META100644 764 144 152 7402536402 11707 0ustar gerdusersversion = "0.2.1" requires = "bigarray" archive(byte) = "cryptgps.cma" archive(native) = "cryptgps.cmxa" cryptgps/crypt_blowfish.ml100664 764 144 62515 7252454651 14713 0ustar gerdusers(* $Id: crypt_blowfish.ml,v 1.2 2001/03/10 16:43:21 gerd Exp $ * ---------------------------------------------------------------------- * This module is part of the cryptgps package by Gerd Stolpmann. *) (* This implementation of Blowfish uses 16 bit numbers instead of * 32 bits because of Caml limitations. *) open Crypt_aux module Cryptsystem : Cryptsystem_64.T = struct type key = { data : string; p_lsb : int array; p_msb : int array; (* subkeys: 18 elements of 16 bits *) p_lsb_rev : int array; p_msb_rev : int array; (* subkeys in reverse order *) s1_lsb : int array; s1_msb : int array; s2_lsb : int array; s2_msb : int array; s3_lsb : int array; s3_msb : int array; s4_lsb : int array; s4_msb : int array; (* the four s-boxes: sNP, where N=0,1,2,3 denotes the box, * and P=0,1 whether the LSB (0) or MSB (1) of the box * value is stored. *) } let encrypt_ecb k (xl_msb,xl_lsb,xr_msb,xr_lsb) = (* The 64-bit element (xl, xr) is encrypted using key k with: * - xl_lsb the LSB of xl * - xl_msb the MSB of xl * - xr_lsb the LSB of xr * - xr_msb the MSB of xr * Returns (xl_msb', xl_lsb', xr_msb', xr_lsb'). *) let p_lsb = k.p_lsb in let p_msb = k.p_msb in let s1_lsb = k.s1_lsb in let s1_msb = k.s1_msb in let s2_lsb = k.s2_lsb in let s2_msb = k.s2_msb in let s3_lsb = k.s3_lsb in let s3_msb = k.s3_msb in let s4_lsb = k.s4_lsb in let s4_msb = k.s4_msb in let rec compute_rounds i xl_lsb xl_msb xr_lsb xr_msb = if i < 16 then begin let xl_lsb' = xl_lsb lxor p_lsb.(i) in let xl_msb' = xl_msb lxor p_msb.(i) in let a = xl_msb' lsr 8 in let b = xl_msb' land 0xff in let c = xl_lsb' lsr 8 in let d = xl_lsb' land 0xff in let s_1a_plus_s_2b_lsb = s1_lsb.(a) + s2_lsb.(b) in let s_1a_plus_s_2b_msb = s1_msb.(a) + s2_msb.(b) + (s_1a_plus_s_2b_lsb lsr 16) in let after_xor_s_3c_lsb = (s_1a_plus_s_2b_lsb land 0xffff) lxor s3_lsb.(c) in let after_xor_s_3c_msb = (s_1a_plus_s_2b_msb land 0xffff) lxor s3_msb.(c) in let y_lsb = after_xor_s_3c_lsb + s4_lsb.(d) in let y_msb = after_xor_s_3c_msb + s4_msb.(d) + (y_lsb lsr 16) in let xr_lsb' = (y_lsb land 0xffff) lxor xr_lsb in let xr_msb' = (y_msb land 0xffff) lxor xr_msb in compute_rounds (i+1) xr_lsb' xr_msb' xl_lsb' xl_msb' end else (xr_msb lxor p_msb.(17), xr_lsb lxor p_lsb.(17), xl_msb lxor p_msb.(16), xl_lsb lxor p_lsb.(16)) in compute_rounds 0 xl_lsb xl_msb xr_lsb xr_msb let encrypt_ecb_int32 k xl xr ret_xl ret_xr = let x = quadruple_of_int32 xl xr in let y = encrypt_ecb k x in int32_of_quadruple y ret_xl ret_xr let decrypt_ecb k x = (* The 64-bit element (xl', xr') is decrypted using key k with: * - xl_lsb' the LSB of xl' * - xl_msb' the MSB of xl' * - xr_lsb' the LSB of xr' * - xr_msb' the MSB of xr' * Returns (xl_msb, xl_lsb, xr_msb, xr_lsb). *) let k' = { k with p_lsb = k.p_lsb_rev; p_msb = k.p_msb_rev } in encrypt_ecb k' x let decrypt_ecb_int32 k xl xr ret_xl ret_xr = let x = quadruple_of_int32 xl xr in let y = decrypt_ecb k x in int32_of_quadruple y ret_xl ret_xr let prepare key = let l_key = String.length key in if l_key = 0 or l_key > 56 then failwith "Crypt_blowfish: invalid key length"; let k = { data = key; p_lsb = [| 0x6a88; 0x08d3; 0x8a2e; 0x7344; 0x3822; 0x31d0; 0xfa98; 0x6c89; 0x21e6; 0x1377; 0x66cf; 0x0c6c; 0x29b7; 0x50dd; 0xd5b5; 0x0917; 0xd5d9; 0xfb1b |]; p_msb = [| 0x243f; 0x85a3; 0x1319; 0x0370; 0xa409; 0x299f; 0x082e; 0xec4e; 0x4528; 0x38d0; 0xbe54; 0x34e9; 0xc0ac; 0xc97c; 0x3f84; 0xb547; 0x9216; 0x8979 |]; p_lsb_rev = [| 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; |]; p_msb_rev = [| 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; |]; s1_lsb = [| 0x0ba6; 0xb5ac; 0x72db; 0xdfb7; 0xafed; 0x7e96; 0x9045; 0x7f99; 0x9947; 0x6cf7; 0xf2e2; 0xfc16; 0x20d8; 0x4e69; 0xfea3; 0x3d7e; 0x748f; 0xb658; 0xcd58; 0x4aee; 0xa41d; 0x59b5; 0xd539; 0x6013; 0xb023; 0x85f0; 0x7918; 0x38ef; 0xdcb0; 0x180e; 0x0e8b; 0x8a3e; 0x77c1; 0x4b27; 0x2fda; 0x5c60; 0x25f3; 0xab94; 0x9862; 0x1440; 0x396a; 0x10b6; 0x5c34; 0xe8ce; 0x86af; 0xe993; 0x1411; 0xbc2a; 0xc55d; 0x31f6; 0x3e16; 0x931e; 0xba33; 0xcf5c; 0x5381; 0x8677; 0x4898; 0xb9af; 0xe81b; 0x2193; 0x09cc; 0xa991; 0xac60; 0x8032; 0x5d5d; 0x75b1; 0x2302; 0x1b88; 0x3e81; 0xacc5; 0x6ff3; 0x4239; 0x4482; 0x2004; 0xf04a; 0x9b5e; 0x6842; 0x6c9a; 0x9c61; 0x88f0; 0xa0d2; 0x2f68; 0xa728; 0x33a3; 0x0b6c; 0x3be4; 0xf050; 0x2a98; 0x651d; 0x0176; 0x593e; 0x0e88; 0x8619; 0x9fb4; 0xa5c3; 0x5ebe; 0x75d8; 0x2073; 0x449f; 0x6aa6; 0xaa62; 0x7706; 0xdf72; 0x023d; 0xd724; 0x1248; 0xead3; 0xc09b; 0x72c9; 0x1b7b; 0x79d8; 0xdef7; 0x501a; 0x4c3b; 0xe0bd; 0x06ba; 0x4fb6; 0x60c4; 0x9ec2; 0x2463; 0x6faf; 0x53b5; 0xb2eb; 0xec6f; 0x511f; 0x952c; 0x4544; 0xbd09; 0xd004; 0x4afd; 0x2807; 0x4bb3; 0xa857; 0x740f; 0x5f39; 0xfbdb; 0xc0bd; 0x320a; 0x00c6; 0x7279; 0x25fe; 0xa3cc; 0xe9f8; 0x22f8; 0x16df; 0x6b15; 0x1ec8; 0x52ab; 0xb5fa; 0x8760; 0x7b48; 0xdf82; 0x57bb; 0x8ca0; 0x562e; 0x69db; 0xa8f6; 0xffc3; 0x32c6; 0x5573; 0x27b0; 0x58c8; 0xa35d; 0x11a0; 0x3d98; 0x83b8; 0xb56c; 0xd35b; 0xe479; 0x4565; 0x49bc; 0x9790; 0xf2da; 0x7e33; 0x1341; 0xc6e8; 0xcada; 0x4c01; 0x9efe; 0x1fb4; 0xda4d; 0x9198; 0x8e71; 0xd5a0; 0xd1d0; 0x25e0; 0x5b2f; 0x94b7; 0xe2fb; 0x2b64; 0xb812; 0xf01c; 0x5ea0; 0xc31c; 0xf191; 0xc1ad; 0x2218; 0x1777; 0x2dfe; 0x1fa1; 0xcc0f; 0x74e8; 0xf3d6; 0xe299; 0x4fe0; 0xe0b7; 0x3b81; 0xa8d9; 0xa266; 0x7705; 0x7314; 0x1477; 0x2065; 0xfa86; 0x42f5; 0x35cf; 0xaf0c; 0x89a0; 0x1bd3; 0x7e49; 0x0e2d; 0xb35e; 0x00bb; 0xe0af; 0x369b; 0xb91e; 0x911d; 0xa6aa; 0x4389; 0x537f; 0x5ba2; 0xb9c5; 0x0376; 0xcfa9; 0x1968; 0x4a41; 0x2dca; 0xa94a; 0x0052; 0x2915; 0x573f; 0xc6e4; 0xa476; 0x7400; 0x6fb5; 0xe91f; 0xec6b; 0xd915; 0x6521; 0xf9b6; 0x052e; 0x5664; 0x2d5d; 0x8fa1; 0x4799; 0x076a; |]; s1_msb = [| 0xd131; 0x98df; 0x2ffd; 0xd01a; 0xb8e1; 0x6a26; 0xba7c; 0xf12c; 0x24a1; 0xb391; 0x0801; 0x858e; 0x6369; 0x7157; 0xa458; 0xf493; 0x0d95; 0x728e; 0x718b; 0x8215; 0x7b54; 0xc25a; 0x9c30; 0x2af2; 0xc5d1; 0x2860; 0xca41; 0xb8db; 0x8e79; 0x603a; 0x6c9e; 0xb01e; 0xd715; 0xbd31; 0x78af; 0x5560; 0xe655; 0xaa55; 0x5748; 0x63e8; 0x55ca; 0x2aab; 0xb4cc; 0x1141; 0xa154; 0x7c72; 0xb3ee; 0x636f; 0x2ba9; 0x7418; 0xce5c; 0x9b87; 0xafd6; 0x6c24; 0x7a32; 0x2895; 0x3b8f; 0x6b4b; 0xc4bf; 0x6628; 0x61d8; 0xfb21; 0x487c; 0x5dec; 0xef84; 0xe985; 0xdc26; 0xeb65; 0x2389; 0xd396; 0x0f6d; 0x83f4; 0x2e0b; 0xa484; 0x69c8; 0x9e1f; 0x21c6; 0xf6e9; 0x670c; 0xabd3; 0x6a51; 0xd854; 0x960f; 0xab51; 0x6eef; 0x137a; 0xba3b; 0x7efb; 0xa1f1; 0x39af; 0x66ca; 0x8243; 0x8cee; 0x456f; 0x7d84; 0x3b8b; 0xe06f; 0x85c1; 0x401a; 0x56c1; 0x4ed3; 0x363f; 0x1bfe; 0x429b; 0x37d0; 0xd00a; 0xdb0f; 0x49f1; 0x0753; 0x8099; 0x25d4; 0xf6e8; 0xe3fe; 0xb679; 0x976c; 0x04c0; 0xc1a9; 0x409f; 0x5e5c; 0x196a; 0x68fb; 0x3e6c; 0x1339; 0x3b52; 0x6dfc; 0x9b30; 0xcc81; 0xaf5e; 0xbee3; 0xde33; 0x660f; 0x192e; 0xc0cb; 0x45c8; 0xd20b; 0xb9d3; 0x5579; 0x1a60; 0xd6a1; 0x402c; 0x679f; 0xfb1f; 0x8ea5; 0xdb32; 0x3c75; 0xfd61; 0x2f50; 0xad05; 0x323d; 0xfd23; 0x5331; 0x3e00; 0x9e5c; 0xca6f; 0x1a87; 0xdf17; 0xd542; 0x287e; 0xac67; 0x8c4f; 0x695b; 0xbbca; 0xe1ff; 0xb8f0; 0x10fa; 0xfd21; 0x4afc; 0x2dd1; 0x9a53; 0xb6f8; 0xd28e; 0x4bfb; 0xe1dd; 0xa4cb; 0x62fb; 0xcee4; 0xef20; 0x3677; 0xd07e; 0x2bf1; 0x95db; 0xae90; 0xeaad; 0x6b93; 0xd08e; 0xafc7; 0x8e3c; 0x8e75; 0x8ff6; 0xf212; 0x8888; 0x900d; 0x4fad; 0x688f; 0xd1cf; 0xb3a8; 0x2f2f; 0xbe0e; 0xea75; 0x8b02; 0xe5a0; 0xb56f; 0x18ac; 0xce89; 0xb4a8; 0xfd13; 0x7cc4; 0xd2ad; 0x165f; 0x8095; 0x93cc; 0x211a; 0xe6ad; 0x77b5; 0xc754; 0xfb9d; 0xebcd; 0x7b3e; 0xd641; 0xae1e; 0x0025; 0x2071; 0x2268; 0x57b8; 0x2464; 0xf009; 0x5563; 0x59df; 0x78c1; 0xd95a; 0x207d; 0x02e5; 0x8326; 0x6295; 0x11c8; 0x4e73; 0xb347; 0x7b14; 0x1b51; 0x9a53; 0xd60f; 0xbc9b; 0x2b60; 0x81e6; 0x08ba; 0x571b; 0xf296; 0x2a0d; 0xb663; 0xe7b9; 0xff34; 0xc585; 0x53b0; 0xa99f; 0x08ba; 0x6e85; |]; s2_lsb = [| 0x70e9; 0x2944; 0x092e; 0x2623; 0xa6b0; 0xdf7d; 0x60b8; 0xb266; 0x8c71; 0x17ff; 0x526c; 0x9ee1; 0x02a5; 0x4c29; 0x1340; 0x3a3e; 0x989a; 0x9d65; 0xe4d6; 0x3fd6; 0x9c07; 0x30f5; 0x38e6; 0x5dc1; 0x2086; 0xeb26; 0xe9c6; 0xcc5e; 0x6b3f; 0xefc9; 0x1814; 0x70a1; 0x3584; 0xe286; 0x5305; 0x0737; 0x841c; 0xae5c; 0x44ec; 0xf2b8; 0xda37; 0x0c0d; 0x1f04; 0xb3ff; 0xf51a; 0x74b2; 0x7a58; 0x21bd; 0x13f9; 0x2ff6; 0x4773; 0x4701; 0xe581; 0xdadc; 0x7634; 0xdda7; 0x6146; 0x030e; 0xc73e; 0x1e41; 0xcd99; 0x0e2f; 0xbba1; 0xb331; 0x8b38; 0xb908; 0x0d03; 0x04bf; 0x1290; 0x7c79; 0xb072; 0x89af; 0x771f; 0x0810; 0xae12; 0x3f2e; 0x721f; 0x7124; 0xdde6; 0xcd87; 0x4718; 0xda17; 0x9abc; 0x7d8c; 0xec3a; 0x1dfa; 0x4366; 0xc3d2; 0x1847; 0xd908; 0x3b37; 0xba16; 0x4d43; 0xc451; 0x0002; 0xe4dd; 0xf89e; 0x4e55; 0x77d6; 0x199b; 0x56f1; 0xc76b; 0x183b; 0xa509; 0xe6ed; 0xfbfa; 0xbf2c; 0x3c6e; 0x4570; 0x6fb1; 0x5e0a; 0x2ab3; 0xe71c; 0x06fa; 0xdcb9; 0x1d0f; 0x89d6; 0xc825; 0xc978; 0xb36a; 0x0eba; 0xea78; 0x3c53; 0x2df4; 0x4ea7; 0x2b3d; 0x260f; 0x7960; 0xa708; 0x12b6; 0xfe6e; 0x1f66; 0x4595; 0xc883; 0x37d1; 0xff28; 0xddef; 0x5aa5; 0x2185; 0x9802; 0xa50f; 0x953b; 0x7dad; 0x2f84; 0xb628; 0x6170; 0x4775; 0x1510; 0xa830; 0xbd96; 0xfe1e; 0x63cf; 0x5c90; 0xa239; 0x9e0b; 0xde14; 0x86bc; 0x2ca7; 0x5cab; 0x846e; 0x1eaf; 0xf0ca; 0x69b9; 0xbb50; 0x5a32; 0xb4b3; 0xe9d5; 0xb8f7; 0x0b19; 0xa099; 0x997e; 0x7da8; 0x889a; 0x2d77; 0x935f; 0x1281; 0x8829; 0x1fd6; 0xdfa1; 0xba99; 0x84a5; 0x7263; 0xc3ff; 0x4696; 0x0aeb; 0x3054; 0x48e4; 0x3128; 0xf2ef; 0xffea; 0xed61; 0x3c73; 0x14d9; 0xb7e3; 0x5d14; 0x13e0; 0xe2b6; 0xabea; 0x4f15; 0x4fd0; 0xf442; 0xbbb5; 0x3b1d; 0x2105; 0x799e; 0x4dc7; 0x476a; 0x6250; 0xa1f2; 0x2646; 0x83a0; 0xb6a3; 0x24c3; 0x7492; 0x8a0b; 0xb285; 0xbf00; 0x489d; 0xb174; 0x0e00; 0x8d2a; 0xf5ea; 0xf43e; 0x7061; 0xf092; 0x7e41; 0xecf1; 0x3bdb; 0x3759; 0x7460; 0xf2a7; 0x326e; 0x8084; 0x509e; 0xd855; 0x9735; 0xa7aa; 0x06c2; 0xabfc; 0xcadc; 0x7a2e; 0x3484; 0x6705; 0x9ec9; 0xdbd3; 0x88cd; 0xda79; 0x4340; 0x3465; 0x38d8; 0xf89e; 0xff20; 0x21e7; 0x3d4a; 0x9f2b; 0xadf7; |]; s2_msb = [| 0x4b7a; 0xb5b3; 0xdb75; 0xc419; 0xad6e; 0x49a7; 0x9cee; 0x8fed; 0xecaa; 0x699a; 0x5664; 0xc2b1; 0x1936; 0x7509; 0xa059; 0xe418; 0x3f54; 0x5b42; 0x6b8f; 0x99f7; 0xa1d2; 0xefe8; 0x4d2d; 0xf025; 0x4cdd; 0x8470; 0x6382; 0x021e; 0x0968; 0x3eba; 0x3c97; 0x6b6a; 0x687f; 0x52a0; 0xb79c; 0xaa50; 0x3e07; 0x7fde; 0x8e7d; 0x5716; 0xb03a; 0xf050; 0xf01c; 0x0200; 0xae0c; 0x3cb5; 0x2583; 0xdc09; 0xd191; 0x7ca9; 0x9432; 0x22f5; 0x3ae5; 0x37c2; 0xc8b5; 0x9af3; 0xa944; 0x0fd0; 0xecc8; 0xa475; 0xe238; 0x3bea; 0x3280; 0x183e; 0x4e54; 0x4f6d; 0x6f42; 0xf60a; 0x2cb8; 0x2497; 0x5679; 0xbcaf; 0xde9a; 0xd993; 0xb38b; 0xdccf; 0x5512; 0x2e6b; 0x501a; 0x9f84; 0x7a58; 0x7408; 0xbc9f; 0xe94b; 0xec7a; 0xdb85; 0x6309; 0xc464; 0xef1c; 0x3215; 0xdd43; 0x24c2; 0x12a1; 0x2a65; 0x5094; 0x133a; 0x71df; 0x1031; 0x81ac; 0x5f11; 0x0435; 0xd7a3; 0x3c11; 0x5924; 0xf28f; 0x97f1; 0x9eba; 0x1e15; 0x86e3; 0xeae9; 0x860e; 0x5a3e; 0x771f; 0x4e3d; 0x2965; 0x99e7; 0x803e; 0x5266; 0x2e4c; 0x9c10; 0xc615; 0x94e2; 0xa5fc; 0x1e0a; 0xf2f7; 0x361d; 0x1939; 0x19c2; 0x5223; 0xf713; 0xebad; 0xeac3; 0xe3bc; 0xa67b; 0xb17f; 0x018c; 0xc332; 0xbe6c; 0x6558; 0x68ab; 0xeece; 0xdb2f; 0x2aef; 0x5b6e; 0x1521; 0x2907; 0xecdd; 0x619f; 0x13cc; 0xeb61; 0x0334; 0xaa03; 0xb573; 0x4c70; 0xd59e; 0xcbaa; 0xeecc; 0x6062; 0x9cab; 0xb2f3; 0x648b; 0x19bd; 0xa023; 0x655a; 0x4068; 0x3c2a; 0x319e; 0xc021; 0x9b54; 0x875f; 0x95f7; 0x623d; 0xf837; 0x97e3; 0x11ed; 0x1668; 0x0e35; 0xc7e6; 0x96de; 0x7858; 0x57f5; 0x1b22; 0x9b83; 0x1ac2; 0xcdb3; 0x532e; 0x8fd9; 0x6dbc; 0x58eb; 0x34c6; 0xfe28; 0xee7c; 0x5d4a; 0xe864; 0x4210; 0x203e; 0x45ee; 0xa3aa; 0xdb6c; 0xfacb; 0xc742; 0xef6a; 0x654f; 0x41cd; 0xd81e; 0x8685; 0xe44b; 0x3d81; 0xcf62; 0x5b8d; 0xfc88; 0xc1c7; 0x7f15; 0x69cb; 0x4784; 0x5692; 0x095b; 0xad19; 0x1462; 0x2382; 0x5842; 0x0c55; 0x1dad; 0x233f; 0x3372; 0x8d93; 0xd65f; 0x6c22; 0x7cde; 0xcbee; 0x4085; 0xce77; 0xa607; 0x19f8; 0xe8ef; 0x61d9; 0xa969; 0xc50c; 0x5a04; 0x800b; 0x9e44; 0xc345; 0xfdd5; 0x0e1e; 0xdb73; 0x1055; 0x675f; 0xe367; 0xc5c4; 0x713e; 0x3d28; 0xf16d; 0x153e; 0x8fb0; 0xe6e3; 0xdb83; |]; s3_lsb = [| 0x5a68; 0x40f7; 0x261c; 0x2934; 0x20f7; 0xd4f7; 0x6b2e; 0x0068; 0x2471; 0xf46a; 0xd4b7; 0x61af; 0xf62e; 0x4546; 0x4f74; 0x8840; 0xfc1d; 0x91af; 0xddd3; 0x2f45; 0x09ec; 0x9785; 0x6dd0; 0x8504; 0x27b3; 0x3941; 0x47e6; 0x0a9a; 0x7825; 0x29f4; 0x86da; 0x6dfb; 0x1462; 0x6900; 0xc0a4; 0x8dee; 0xfea2; 0xad8c; 0xe006; 0xd6b6; 0x1e7c; 0x5fec; 0xa399; 0x2a42; 0x9e35; 0x85b9; 0xd7ab; 0x4e8b; 0xfaf7; 0x1856; 0x6631; 0x97b2; 0xfa74; 0x4332; 0xe7f7; 0x20fb; 0xf54e; 0xb397; 0x56ac; 0x9527; 0x3a3a; 0x8d87; 0xa9b7; 0x954b; 0x67bc; 0x9a58; 0x2963; 0xdb33; 0x4a56; 0x25f9; 0x7e1c; 0x317c; 0xe802; 0x2f70; 0x155c; 0x2ce3; 0x1548; 0x6d22; 0x133f; 0x86dc; 0xc9ee; 0x1f0f; 0x79a4; 0x6e17; 0x51eb; 0xc0d1; 0xc18f; 0x3564; 0x7834; 0x9c60; 0xe8a3; 0x6c1b; 0xb4c2; 0x329e; 0x4fd1; 0x8115; 0x95e0; 0x92e1; 0x0b62; 0xb922; 0xa20e; 0x0d99; 0x0c8c; 0xf728; 0x7845; 0x94fd; 0x0862; 0xf5f0; 0xa36f; 0x48fa; 0xfd27; 0x8d1e; 0x6341; 0xff74; 0x6eab; 0xfd37; 0xdc60; 0xddf8; 0xe14c; 0x6b0d; 0x5510; 0x2c37; 0xd43b; 0xe804; 0x0dc7; 0xffa3; 0x0f92; 0xed0b; 0x9ffb; 0x7d9c; 0xcf0b; 0x5ea3; 0x2f88; 0xad24; 0x79bf; 0xd6eb; 0x2eb3; 0x5979; 0xe297; 0x312d; 0xada7; 0x2b3b; 0x4ccc; 0xf11c; 0x4237; 0x51e7; 0xbbe6; 0x6350; 0x1018; 0xedfa; 0xbdd8; 0xc3c9; 0x1659; 0x1386; 0xec6e; 0xea2a; 0x674e; 0xa85f; 0xe988; 0xc3fe; 0x8057; 0xc086; 0x7bf8; 0x604d; 0x8346; 0x1fb0; 0xae04; 0xfccc; 0x6b33; 0xab71; 0x4187; 0x5e5f; 0x57be; 0xae24; 0x4299; 0x2e61; 0xf48f; 0xfda2; 0xef38; 0xbdc2; 0xf9c3; 0x8e74; 0xf255; 0xd9b9; 0x2661; 0xdf84; 0x0e79; 0x95e2; 0x598e; 0x5770; 0x5591; 0xde4c; 0xace1; 0x05d0; 0x6248; 0xa99e; 0x19b6; 0xdc09; 0x09a1; 0x4633; 0x1f02; 0xbe8c; 0xa025; 0xfe10; 0x3d1d; 0xa4df; 0xf20f; 0xf169; 0xda83; 0x06fe; 0xce9b; 0x7f52; 0x5e01; 0x83fa; 0xb5c4; 0xd027; 0x8c27; 0x8641; 0x4c06; 0x06b5; 0x7a28; 0x86e0; 0x58aa; 0x7d62; 0x9ed7; 0xea63; 0xdd94; 0x1634; 0xee56; 0xb6de; 0x7da1; 0x1d76; 0xe409; 0x0188; 0x0a3d; 0x7c24; 0x725f; 0x9db9; 0x5bb4; 0xb8fc; 0x5578; 0xa5b5; 0x7cd3; 0x0fc4; 0xef5e; 0xe6f8; 0x14d9; 0x133c; 0xc7e7; 0x4ec4; 0xbfce; 0xc837; 0x3234; 0x8212; 0xfa8e; 0x00e0; |]; s3_msb = [| 0xe93d; 0x9481; 0xf64c; 0x9469; 0x4115; 0x7602; 0xbcf4; 0xd4a2; 0xd408; 0x3320; 0x43b7; 0x5000; 0x1e39; 0x9724; 0x1421; 0xbf8b; 0x4d95; 0x96b5; 0x70f4; 0x66a0; 0xbfbc; 0x03bd; 0x7fac; 0x31cb; 0x96eb; 0x55fd; 0xda25; 0xabca; 0x2850; 0x5304; 0x0a2c; 0xe9b6; 0x68dc; 0xd748; 0x680e; 0x27a1; 0x4f3f; 0xe887; 0xb58c; 0x7af4; 0xaace; 0xd337; 0xce78; 0x406b; 0x20fe; 0xd9f3; 0xee39; 0x3b12; 0x1dc9; 0x4b6d; 0x26a3; 0xeae3; 0x3a6e; 0xdd5b; 0x6841; 0xca78; 0xfb0a; 0xd8fe; 0x4540; 0xba48; 0x5553; 0x2083; 0xfe6b; 0xd096; 0x55a8; 0xa115; 0xcca9; 0x99e1; 0xa62a; 0x3f31; 0x5ef4; 0x9029; 0xfdf8; 0x0427; 0x80bb; 0x0528; 0x95c1; 0xe4c6; 0x48c1; 0xc70f; 0x07f9; 0x4104; 0x4047; 0x5d88; 0x325f; 0xd59b; 0xf2bc; 0x4111; 0x257b; 0x602a; 0xdff8; 0x1f63; 0x0e12; 0x02e1; 0xaf66; 0xcad1; 0x6b23; 0x333e; 0x3b24; 0xeebe; 0x85b2; 0xe6ba; 0xde72; 0x2da2; 0xd012; 0x95b7; 0x647d; 0xe7cc; 0x5449; 0x877d; 0xc39d; 0xf33e; 0x0a47; 0x992e; 0x3a6f; 0xf4f8; 0xa812; 0xa1eb; 0x991b; 0xdb6e; 0xc67b; 0x6d67; 0x2765; 0xdcd0; 0xf129; 0xcc00; 0xb539; 0x690f; 0x667b; 0xcedb; 0xa091; 0xd915; 0xbb13; 0x515b; 0x7b94; 0x763b; 0x3739; 0xcc11; 0x8026; 0xf42e; 0x6842; 0xc66a; 0x1275; 0x782e; 0x6a12; 0xb792; 0x06a1; 0x4bfb; 0x1a6b; 0x11ca; 0x3d25; 0xe2e1; 0x4442; 0x0a12; 0xd90c; 0xd5ab; 0x64af; 0xda86; 0xbebf; 0x64e4; 0x9dbc; 0xf0f7; 0x6078; 0x6003; 0xd1fd; 0xf638; 0x7745; 0xd736; 0x8342; 0xf01e; 0xb080; 0x3c00; 0x77a0; 0xbde8; 0x5546; 0xbf58; 0x4e58; 0xf2dd; 0xf474; 0x8789; 0x5366; 0xc8b3; 0xb475; 0x46fc; 0x7aeb; 0x8b1d; 0x846a; 0x915f; 0x466e; 0x20b4; 0x8cd5; 0xc902; 0xb90b; 0xbb82; 0x11a8; 0x7574; 0xb77f; 0xe0a9; 0x662d; 0xc432; 0xe85a; 0x09f0; 0x4a99; 0x1d6e; 0x1ab9; 0x0ba5; 0xa186; 0x2868; 0xdcb7; 0x5739; 0xa1e2; 0x4fcd; 0x5011; 0xa706; 0xa002; 0x0de6; 0x9af8; 0x773f; 0xc360; 0x61a8; 0xf017; 0xc0f5; 0x0060; 0x30dc; 0x11e6; 0x2338; 0x53c2; 0xc2c2; 0xbbcb; 0x90bc; 0xebfc; 0xce59; 0x6f05; 0x4b7c; 0x3972; 0x7c92; 0x86e3; 0x724d; 0x1ac1; 0xd39e; 0xed54; 0x08fc; 0xd83d; 0x4dad; 0x1e50; 0xb161; 0xa285; 0x6c51; 0x6fd5; 0x56e1; 0x362a; 0xddc6; 0xd79a; 0x9263; 0x670e; 0x4060; |]; s4_lsb = [| 0xce37; 0xf5cf; 0x7737; 0x2d1b; 0x679e; 0x3742; 0x2740; 0x9bbe; 0x8e9d; 0x7315; 0x1c7e; 0xc47b; 0x1b6b; 0x9045; 0xb1be; 0x6eb4; 0xab2f; 0x6e79; 0x76d2; 0xc2c8; 0xf8ee; 0xde7d; 0x0a1d; 0x4dc6; 0xbbdb; 0x4650; 0x26e8; 0xe304; 0xd5f0; 0x519a; 0x8ce2; 0xee22; 0xc2b8; 0x2ef6; 0x03aa; 0xd0a4; 0x61ba; 0x6a4d; 0x1550; 0x5bd6; 0xa2f9; 0x3ae1; 0x9586; 0x62e9; 0xefd3; 0xf7da; 0x6f69; 0x0a59; 0xa915; 0x8601; 0xe6ad; 0xe593; 0xfd5a; 0xd797; 0xb7d9; 0x8b51; 0xac3a; 0xa67d; 0x3ed6; 0x2d28; 0x25cf; 0xb89b; 0xb472; 0xf54c; 0xac71; 0xa5e6; 0xacfd; 0xfa9b; 0xc48d; 0x57cc; 0x6629; 0x2e28; 0x0191; 0x6055; 0x0e44; 0x5e8c; 0x6dd4; 0x6dba; 0x6125; 0xf0bd; 0x9e15; 0x57a2; 0x1aec; 0x072a; 0x6d9b; 0x21f5; 0x66fb; 0xf319; 0xd928; 0xfdf5; 0x3482; 0x3cbb; 0x7711; 0xd9f8; 0x5167; 0x925f; 0x1751; 0xdc8e; 0x5862; 0xf991; 0x90c2; 0x7bce; 0xce64; 0xbe32; 0xe37e; 0x3d46; 0x5369; 0xe680; 0x0810; 0xb224; 0x2dfd; 0x2166; 0x460a; 0xc0dd; 0xdecf; 0xc8ae; 0xf7dd; 0x8d40; 0x017f; 0xe3bb; 0x6a7e; 0xff45; 0x0a44; 0xcdd5; 0xcea8; 0x84bb; 0x12ae; 0x6f47; 0xe463; 0x5d9e; 0x771b; 0x6370; 0x0d8d; 0x1357; 0x1671; 0x7d5d; 0xcb08; 0xe2cc; 0x466a; 0xaf84; 0x0428; 0x3a1d; 0x9fb4; 0xa048; 0x3b82; 0xab82; 0x1d4b; 0x27f8; 0x60b1; 0x3fdc; 0x792b; 0x25bd; 0x39e1; 0x794b; 0xc9b7; 0xbac9; 0xc87e; 0xd1f6; 0x11c3; 0xaac7; 0x8749; 0xbd9a; 0xdecb; 0xda38; 0xc32a; 0x3667; 0x317c; 0x2b4f; 0x59b7; 0xbb3a; 0x19ff; 0x459c; 0x222c; 0xfc2a; 0xfc71; 0x1525; 0x9361; 0x9ceb; 0x6459; 0xa8d1; 0x075e; 0x6a0c; 0x5065; 0xa442; 0x6e0e; 0xdb3b; 0xa0be; 0xe964; 0x9532; 0x92df; 0x342b; 0xf21e; 0x7441; 0x348c; 0x7120; 0x32d8; 0x9f8d; 0x2f2e; 0x6f47; 0xf11d; 0xda54; 0xd891; 0x79cf; 0x7e6f; 0xb166; 0x1d05; 0xd2c5; 0x2299; 0xf357; 0x7623; 0x3531; 0xcd02; 0x8162; 0xebb5; 0x3697; 0x73cc; 0x6292; 0x49d0; 0x901b; 0x5614; 0xc7bd; 0x140a; 0xd006; 0x7b9a; 0x53fd; 0x0f00; 0xbfe2; 0xd2f6; 0x6905; 0x0222; 0xcf7c; 0x9c2b; 0x3ec0; 0xe3d3; 0xbd60; 0xadf0; 0x209c; 0xce76; 0xa1c5; 0x6060; 0xfe4e; 0x8dd8; 0xf9b0; 0xaa7e; 0xc25c; 0x8a8c; 0x6ae4; 0xe1f9; 0xf869; 0xdea0; 0x252d; 0xe69f; 0x6132; 0xe25b; 0xdfe3; 0x72e6; |]; s4_msb = [| 0x3a39; 0xd3fa; 0xabc2; 0x5ac5; 0x5cb0; 0x4fa3; 0xd382; 0x99bc; 0xd511; 0xbf0f; 0xd62d; 0xc700; 0xb78c; 0x21a1; 0xb26e; 0x6a36; 0x5748; 0xbc94; 0xc6a3; 0x6549; 0x530f; 0x468d; 0xd573; 0x4cd0; 0x2939; 0xa9ba; 0xac95; 0xbe5e; 0xa1fa; 0x6a2d; 0x63ef; 0x9a86; 0xc089; 0x4324; 0xa51e; 0x9cf2; 0x83c0; 0x9be9; 0x8fe5; 0xba64; 0x2826; 0xa73a; 0x4ba9; 0xef55; 0xc72f; 0xf752; 0x3f04; 0x77fa; 0x80e4; 0x87b0; 0x9b09; 0x3b3e; 0xe990; 0x9e34; 0x2cf0; 0x022b; 0x96d5; 0x017d; 0xd1cf; 0x7c7d; 0x1f9f; 0xadf2; 0x5ad6; 0x5a88; 0xe029; 0xe019; 0x47b0; 0xed93; 0xe8d3; 0x283b; 0xf8d5; 0x7913; 0x785f; 0xed75; 0xf796; 0xe3d3; 0x1505; 0x88f4; 0x03a1; 0x0564; 0xc3eb; 0x3c90; 0x9727; 0xa93a; 0x1b3f; 0x1e63; 0xf59c; 0x26dc; 0x7533; 0xb155; 0x0356; 0x8aba; 0x2851; 0xc20a; 0xabcc; 0xccad; 0x4de8; 0x3830; 0x379d; 0x9320; 0xea7a; 0xfb3e; 0x5121; 0x774f; 0xa8b6; 0xc329; 0x48de; 0x6413; 0xa2ae; 0xdd6d; 0x6985; 0x0907; 0xb39a; 0x6445; 0x586c; 0x1c20; 0x5bbe; 0x1b58; 0xccd2; 0x6bb4; 0xdda2; 0x3a59; 0x3e35; 0xbcb4; 0x72ea; 0xfa64; 0x8d66; 0xbf3c; 0xd29b; 0x542f; 0xaec2; 0xf64e; 0x740e; 0xe75b; 0xf872; 0xaf53; 0x4040; 0x4eb4; 0x34d2; 0x0115; 0xe1b0; 0x9598; 0x06b8; 0xce6e; 0x6f3f; 0x3520; 0x011a; 0x2772; 0x6115; 0xe793; 0xbb3a; 0x3445; 0xa088; 0x51ce; 0x2f32; 0xa01f; 0xe01c; 0xbcc7; 0xcf01; 0xa1e8; 0x1a90; 0xd44f; 0xd0da; 0xd50a; 0x0339; 0xc691; 0x8df9; 0xe0b1; 0xf79e; 0x43f5; 0xf2d5; 0x27d9; 0xbf97; 0x15e6; 0x0f91; 0x9b94; 0xfae5; 0xceb6; 0xc2a8; 0x12ba; 0xb6c1; 0xe305; 0x10d2; 0xcb03; 0xe0ec; 0x1698; 0x4c98; 0x3278; 0x9f1f; 0xe0d3; 0xd3a0; 0x8971; 0x1b0a; 0x4ba3; 0xc5be; 0xc376; 0xdf35; 0x9b99; 0xe60b; 0x0fe3; 0xe54c; 0x1eda; 0xce62; 0xcd3e; 0x1618; 0xfd2c; 0x848f; 0xf6fb; 0xf523; 0xa632; 0x93a8; 0x56cc; 0xacf0; 0x5a75; 0x6e16; 0x88d2; 0xde96; 0x81b9; 0x4c50; 0x71c6; 0xe6c6; 0x327a; 0x45e1; 0xc3f2; 0xc9aa; 0x62a8; 0xbb25; 0x35bd; 0x7112; 0xb204; 0xb6cb; 0xcd76; 0x5311; 0x1640; 0x38ab; 0x2547; 0xba38; 0xf746; 0x77af; 0x2075; 0x85cb; 0x8ae8; 0x7aaa; 0x4cf9; 0x1948; 0x02fb; 0x01c3; 0xd6eb; 0x90d4; 0xa65c; 0x3f09; 0xc208; 0xb74e; 0xce77; 0x578f; 0x3ac3; |]; } in let j = ref 0 in for i = 0 to 17 do let k0 = Char.code(key.[ !j ]) in let k1 = Char.code(key.[ (!j + 1) mod l_key ]) in let k2 = Char.code(key.[ (!j + 2) mod l_key ]) in let k3 = Char.code(key.[ (!j + 3) mod l_key ]) in j := (!j + 4) mod l_key; let d_msb = ( k0 lsl 8 ) lor k1 in let d_lsb = ( k2 lsl 8 ) lor k3 in k.p_lsb.( i ) <- k.p_lsb.( i ) lxor d_lsb; k.p_msb.( i ) <- k.p_msb.( i ) lxor d_msb done; let d = ref (0,0,0,0) in for i = 0 to 8 do d := encrypt_ecb k !d; let (dl_msb, dl_lsb, dr_msb, dr_lsb) = !d in k.p_lsb.( 2*i ) <- dl_lsb; k.p_msb.( 2*i ) <- dl_msb; k.p_lsb.( 2*i+1 ) <- dr_lsb; k.p_msb.( 2*i+1 ) <- dr_msb; done; for i = 0 to 127 do d := encrypt_ecb k !d; let (dl_msb, dl_lsb, dr_msb, dr_lsb) = !d in k.s1_lsb.( 2*i ) <- dl_lsb; k.s1_msb.( 2*i ) <- dl_msb; k.s1_lsb.( 2*i+1 ) <- dr_lsb; k.s1_msb.( 2*i+1 ) <- dr_msb; done; for i = 0 to 127 do d := encrypt_ecb k !d; let (dl_msb, dl_lsb, dr_msb, dr_lsb) = !d in k.s2_lsb.( 2*i ) <- dl_lsb; k.s2_msb.( 2*i ) <- dl_msb; k.s2_lsb.( 2*i+1 ) <- dr_lsb; k.s2_msb.( 2*i+1 ) <- dr_msb; done; for i = 0 to 127 do d := encrypt_ecb k !d; let (dl_msb, dl_lsb, dr_msb, dr_lsb) = !d in k.s3_lsb.( 2*i ) <- dl_lsb; k.s3_msb.( 2*i ) <- dl_msb; k.s3_lsb.( 2*i+1 ) <- dr_lsb; k.s3_msb.( 2*i+1 ) <- dr_msb; done; for i = 0 to 127 do d := encrypt_ecb k !d; let (dl_msb, dl_lsb, dr_msb, dr_lsb) = !d in k.s4_lsb.( 2*i ) <- dl_lsb; k.s4_msb.( 2*i ) <- dl_msb; k.s4_lsb.( 2*i+1 ) <- dr_lsb; k.s4_msb.( 2*i+1 ) <- dr_msb; done; for i = 0 to 17 do k.p_lsb_rev.( i ) <- k.p_lsb.( 17-i ); k.p_msb_rev.( i ) <- k.p_msb.( 17-i ); done; k let textkey k = k.data let is_weak k = (* A weak key is one in which two entries for a given S-box are identical *) (* Time: check takes 129540 loops. *) let check s_lsb s_msb = for i=0 to 254 do let a_lsb = s_lsb.(i) in let a_msb = s_msb.(i) in for j=i+1 to 255 do if a_lsb = s_lsb.(j) & a_msb = s_msb.(j) then raise Not_found done done; () in try check k.s1_lsb k.s1_msb; check k.s2_lsb k.s2_msb; check k.s3_lsb k.s3_msb; check k.s4_lsb k.s4_msb; false with Not_found -> true end ;; module Cryptmodes = Cryptmodes_64.Make_modes(Cryptsystem) ;; (* ====================================================================== * History: * * $Log: crypt_blowfish.ml,v $ * Revision 1.2 2001/03/10 16:43:21 gerd * int32 experiments * * Revision 1.1 1999/06/04 20:42:00 gerd * Initial revision. * * *) cryptgps/crypt_blowfish.mli100644 764 144 1742 6726035031 15025 0ustar gerdusers(* $Id: crypt_blowfish.mli,v 1.1 1999/06/04 20:42:01 gerd Exp $ * ---------------------------------------------------------------------- * This module is part of the cryptgps package by Gerd Stolpmann. *) (* "Blowfish", created by Bruce Schneier, is a 64 bit block cipher, * so the following applies: *) module Cryptsystem : Cryptsystem_64.T;; module Cryptmodes : Cryptmodes_64.T with type key = Cryptsystem.key;; (* - Blowfish is one of the fastest ciphers. * - Blowfish supports keys from 8 bits to 448 bits. With longer keys * the algorithm does not slow down. * - There are weak keys. It is possible to recover some initialization * data for weak keys, but no way to exploit this knowlege has been * reported. * - Blowfish is public domain, i.e. free from patents. *) (* ====================================================================== * History: * * $Log: crypt_blowfish.mli,v $ * Revision 1.1 1999/06/04 20:42:01 gerd * Initial revision. * * *) cryptgps/cryptmodes_64.ml100664 764 144 35037 7252454651 14356 0ustar gerdusers(* $Id: cryptmodes_64.ml,v 1.2 2001/03/10 16:43:21 gerd Exp $ * ---------------------------------------------------------------------- * This module is part of the cryptgps package by Gerd Stolpmann. *) open Crypt_aux module type T = sig type key val encrypt_cbc : key -> (int * int * int * int) -> string -> ((int * int * int * int) * string) val decrypt_cbc : key -> (int * int * int * int) -> string -> ((int * int * int * int) * string) val encrypt_cfb8 : key -> (int * int * int * int) -> string -> ((int * int * int * int) * string) val decrypt_cfb8 : key -> (int * int * int * int) -> string -> ((int * int * int * int) * string) val encrypt_cfb64 : key -> (int * int * int * int) -> int -> string -> ((int * int * int * int) * int * string) val decrypt_cfb64 : key -> (int * int * int * int) -> int -> string -> ((int * int * int * int) * int * string) val crypt_ofb : key -> (int * int * int * int) -> int -> string -> ((int * int * int * int) * int * string) end ;; module Make_modes (M : Cryptsystem_64.T) = struct type key = M.key let encrypt_cbc k iv data = let l = String.length data in if l mod 8 <> 0 then failwith "encrypt_cbc"; let n = l / 8 in let data' = String.create l in let v = ref iv in for i = 0 to n-1 do let j = 8*i in let x3 = (Char.code(data.[j]) lsl 8) lor (Char.code(data.[j+1])) in let x2 = (Char.code(data.[j+2]) lsl 8) lor (Char.code(data.[j+3])) in let x1 = (Char.code(data.[j+4]) lsl 8) lor (Char.code(data.[j+5])) in let x0 = (Char.code(data.[j+6]) lsl 8) lor (Char.code(data.[j+7])) in let (v3,v2,v1,v0) = !v in v := M.encrypt_ecb k (v3 lxor x3, v2 lxor x2, v1 lxor x1, v0 lxor x0); let (v3',v2',v1',v0') = !v in data'.[j] <- Char.chr(v3' lsr 8); data'.[j+1] <- Char.chr(v3' land 0xff); data'.[j+2] <- Char.chr(v2' lsr 8); data'.[j+3] <- Char.chr(v2' land 0xff); data'.[j+4] <- Char.chr(v1' lsr 8); data'.[j+5] <- Char.chr(v1' land 0xff); data'.[j+6] <- Char.chr(v0' lsr 8); data'.[j+7] <- Char.chr(v0' land 0xff); done; !v, data' let decrypt_cbc k iv data = let l = String.length data in if l mod 8 <> 0 then failwith "decrypt_cbc"; let n = l / 8 in let data' = String.create l in let v = ref iv in for i = 0 to n-1 do let j = 8*i in let x3 = (Char.code(data.[j]) lsl 8) lor (Char.code(data.[j+1])) in let x2 = (Char.code(data.[j+2]) lsl 8) lor (Char.code(data.[j+3])) in let x1 = (Char.code(data.[j+4]) lsl 8) lor (Char.code(data.[j+5])) in let x0 = (Char.code(data.[j+6]) lsl 8) lor (Char.code(data.[j+7])) in let (y3,y2,y1,y0) = M.decrypt_ecb k (x3,x2,x1,x0) in let (v3,v2,v1,v0) = !v in let z3 = y3 lxor v3 in let z2 = y2 lxor v2 in let z1 = y1 lxor v1 in let z0 = y0 lxor v0 in data'.[j] <- Char.chr(z3 lsr 8); data'.[j+1] <- Char.chr(z3 land 0xff); data'.[j+2] <- Char.chr(z2 lsr 8); data'.[j+3] <- Char.chr(z2 land 0xff); data'.[j+4] <- Char.chr(z1 lsr 8); data'.[j+5] <- Char.chr(z1 land 0xff); data'.[j+6] <- Char.chr(z0 lsr 8); data'.[j+7] <- Char.chr(z0 land 0xff); v := (x3,x2,x1,x0); done; !v, data' let encrypt_cfb8 k iv data = let l = String.length data in let data' = String.create l in let sr = ref iv in (* shift register *) for i = 0 to l-1 do let (v,_,_,_) = M.encrypt_ecb k !sr in let c = Char.code(data.[i]) lxor (v lsr 8) in data'.[i] <- Char.chr c; let (sr3, sr2, sr1, sr0) = !sr in sr := (((sr3 lsl 8) land 0xff00) lor (sr2 lsr 8), ((sr2 lsl 8) land 0xff00) lor (sr1 lsr 8), ((sr1 lsl 8) land 0xff00) lor (sr0 lsr 8), ((sr0 lsl 8) land 0xff00) lor c); done; !sr, data' let decrypt_cfb8 k iv data = let l = String.length data in let data' = String.create l in let sr = ref iv in (* shift register *) for i = 0 to l-1 do let (v,_,_,_) = M.encrypt_ecb k !sr in (* sic! *) let c = Char.code(data.[i]) in let p = c lxor (v lsr 8) in data'.[i] <- Char.chr p; let (sr3, sr2, sr1, sr0) = !sr in sr := (((sr3 lsl 8) land 0xff00) lor (sr2 lsr 8), ((sr2 lsl 8) land 0xff00) lor (sr1 lsr 8), ((sr1 lsl 8) land 0xff00) lor (sr0 lsr 8), ((sr0 lsl 8) land 0xff00) lor c); done; !sr, data' let array_of_quadrupel (n3,n2,n1,n0) = [| n3 lsr 8; n3 land 0xff; n2 lsr 8; n2 land 0xff; n1 lsr 8; n1 land 0xff; n0 lsr 8; n0 land 0xff |] let quadrupel_of_array a = ((a.(0) lsl 8) lor a.(1), (a.(2) lsl 8) lor a.(3), (a.(4) lsl 8) lor a.(5), (a.(6) lsl 8) lor a.(7)) let encrypt_cfb64 k iv j data = if j < 0 or j > 7 then failwith "encrypt_cfb64"; let l = String.length data in let data' = String.create l in let sr_a = ref (array_of_quadrupel iv) in let jc = ref j in for i = 0 to l-1 do if !jc = 0 then sr_a := array_of_quadrupel (M.encrypt_ecb k (quadrupel_of_array !sr_a)); let sr_jc = (!sr_a).(!jc) in let c = Char.code(data.[i]) lxor sr_jc in data'.[i] <- Char.chr c; (!sr_a).(!jc) <- c; jc := (!jc + 1) mod 8; done; let sr = quadrupel_of_array !sr_a in sr, !jc, data' let decrypt_cfb64 k iv j data = if j < 0 or j > 7 then failwith "decrypt_cfb64"; let l = String.length data in let data' = String.create l in let sr_a = ref (array_of_quadrupel iv) in let jc = ref j in for i = 0 to l-1 do if !jc = 0 then sr_a := array_of_quadrupel (M.encrypt_ecb k (quadrupel_of_array !sr_a)); let sr_jc = (!sr_a).(!jc) in let c = Char.code(data.[i]) in data'.[i] <- Char.chr (c lxor sr_jc); (!sr_a).(!jc) <- c; jc := (!jc + 1) mod 8; done; let sr = quadrupel_of_array !sr_a in sr, !jc, data' let crypt_ofb k iv j data = if j < 0 or j > 7 then failwith "crypt_ofb"; let l = String.length data in let data' = String.create l in let sr_a = ref (array_of_quadrupel iv) in let jc = ref j in for i = 0 to l-1 do if !jc = 0 then sr_a := array_of_quadrupel (M.encrypt_ecb k (quadrupel_of_array !sr_a)); let sr_jc = (!sr_a).(!jc) in let c = Char.code(data.[i]) lxor sr_jc in data'.[i] <- Char.chr c; jc := (!jc + 1) mod 8; done; let sr = quadrupel_of_array !sr_a in sr, !jc, data' end ;; module Make_modes_int32 (M : Cryptsystem_64.T) = struct type key = M.key let encrypt_cbc k iv data = let l = String.length data in if l mod 8 <> 0 then failwith "encrypt_cbc"; let n = l / 8 in let data' = String.create l in let vl = ref Int32.zero in let vr = ref Int32.zero in int32_of_quadruple iv vl vr; for i = 0 to n-1 do let j = 8*i in let x3 = (Char.code(data.[j]) lsl 8) lor (Char.code(data.[j+1])) in let x2 = (Char.code(data.[j+2]) lsl 8) lor (Char.code(data.[j+3])) in let x1 = (Char.code(data.[j+4]) lsl 8) lor (Char.code(data.[j+5])) in let x0 = (Char.code(data.[j+6]) lsl 8) lor (Char.code(data.[j+7])) in let xl = Int32.logor (Int32.shift_left (Int32.of_int x3) 16) (Int32.of_int x2) in let xr = Int32.logor (Int32.shift_left (Int32.of_int x1) 16) (Int32.of_int x0) in let yl = Int32.logxor xl !vl in let yr = Int32.logxor xr !vr in M.encrypt_ecb_int32 k yl yr vl vr; let v3' = Int32.to_int (Int32.shift_right_logical !vl 16) in let v2' = Int32.to_int !vl in let v1' = Int32.to_int (Int32.shift_right_logical !vr 16) in let v0' = Int32.to_int !vr in data'.[j] <- Char.chr((v3' lsr 8) land 0xff); data'.[j+1] <- Char.chr(v3' land 0xff); data'.[j+2] <- Char.chr((v2' lsr 8) land 0xff); data'.[j+3] <- Char.chr(v2' land 0xff); data'.[j+4] <- Char.chr((v1' lsr 8) land 0xff); data'.[j+5] <- Char.chr(v1' land 0xff); data'.[j+6] <- Char.chr((v0' lsr 8) land 0xff); data'.[j+7] <- Char.chr(v0' land 0xff); done; quadruple_of_int32 !vl !vr, data' let decrypt_cbc k iv data = let l = String.length data in if l mod 8 <> 0 then failwith "decrypt_cbc"; let n = l / 8 in let data' = String.create l in let vl = ref Int32.zero in let vr = ref Int32.zero in int32_of_quadruple iv vl vr; for i = 0 to n-1 do let j = 8*i in let x3 = (Char.code(data.[j]) lsl 8) lor (Char.code(data.[j+1])) in let x2 = (Char.code(data.[j+2]) lsl 8) lor (Char.code(data.[j+3])) in let x1 = (Char.code(data.[j+4]) lsl 8) lor (Char.code(data.[j+5])) in let x0 = (Char.code(data.[j+6]) lsl 8) lor (Char.code(data.[j+7])) in let xl = Int32.logor (Int32.shift_left (Int32.of_int x3) 16) (Int32.of_int x2) in let xr = Int32.logor (Int32.shift_left (Int32.of_int x1) 16) (Int32.of_int x0) in let yl = ref Int32.zero in let yr = ref Int32.zero in M.decrypt_ecb_int32 k xl xr yl yr; let zl = Int32.logxor !yl !vl in let zr = Int32.logxor !yr !vr in let z3 = Int32.to_int (Int32.shift_right_logical zl 16) in let z2 = Int32.to_int zl in let z1 = Int32.to_int (Int32.shift_right_logical zr 16) in let z0 = Int32.to_int zr in data'.[j] <- Char.chr((z3 lsr 8) land 0xff); data'.[j+1] <- Char.chr(z3 land 0xff); data'.[j+2] <- Char.chr((z2 lsr 8) land 0xff); data'.[j+3] <- Char.chr(z2 land 0xff); data'.[j+4] <- Char.chr((z1 lsr 8) land 0xff); data'.[j+5] <- Char.chr(z1 land 0xff); data'.[j+6] <- Char.chr((z0 lsr 8) land 0xff); data'.[j+7] <- Char.chr(z0 land 0xff); vl := xl; vr := xr; done; quadruple_of_int32 !vl !vr, data' let encrypt_cfb8 k iv data = let l = String.length data in let data' = String.create l in let sr_l = ref Int32.zero in (* shift register MSB *) let sr_r = ref Int32.zero in (* shift register LSB *) int32_of_quadruple iv sr_l sr_r; let out_l = ref Int32.zero in let out_r = ref Int32.zero in for i = 0 to l-1 do M.encrypt_ecb_int32 k !sr_l !sr_r out_l out_r; let c = Char.code(data.[i]) lxor ((Int32.to_int (Int32.shift_right_logical !out_l 24)) land 0xff) in data'.[i] <- Char.chr c; sr_l := Int32.logor (Int32.shift_left !sr_l 8) (Int32.shift_right_logical !sr_r 24); sr_r := Int32.logor (Int32.shift_left !sr_r 8) (Int32.of_int c) done; quadruple_of_int32 !sr_l !sr_r, data' let decrypt_cfb8 k iv data = let l = String.length data in let data' = String.create l in let sr_l = ref Int32.zero in (* shift register MSB *) let sr_r = ref Int32.zero in (* shift register LSB *) int32_of_quadruple iv sr_l sr_r; let out_l = ref Int32.zero in let out_r = ref Int32.zero in for i = 0 to l-1 do M.encrypt_ecb_int32 k !sr_l !sr_r out_l out_r; (* sic! *) let c = Char.code(data.[i]) in let p = c lxor ((Int32.to_int (Int32.shift_right_logical !out_l 24)) land 0xff) in data'.[i] <- Char.chr p; sr_l := Int32.logor (Int32.shift_left !sr_l 8) (Int32.shift_right_logical !sr_r 24); sr_r := Int32.logor (Int32.shift_left !sr_r 8) (Int32.of_int c) done; quadruple_of_int32 !sr_l !sr_r, data' let mask = [| Int32.of_string "0x00ffffff"; Int32.of_string "0xff00ffff"; Int32.of_string "0xffff00ff"; Int32.of_string "0xffffff00"; |] let encrypt_cfb64 k iv j data = if j < 0 or j > 7 then failwith "encrypt_cfb64"; let l = String.length data in let data' = String.create l in let sr_l = ref Int32.zero in (* shift register MSB *) let sr_r = ref Int32.zero in (* shift register LSB *) int32_of_quadruple iv sr_l sr_r; let jc = ref j in for i = 0 to l-1 do if !jc = 0 then M.encrypt_ecb_int32 k !sr_l !sr_r sr_l sr_r; let jc8 = !jc lsl 3 in let sr_jc = if !jc < 4 then (Int32.to_int (Int32.shift_right_logical !sr_l (24 - jc8))) land 0xff else (Int32.to_int (Int32.shift_right_logical !sr_r (56 - jc8))) land 0xff in let c = Char.code(data.[i]) lxor sr_jc in data'.[i] <- Char.chr c; ( if !jc < 4 then sr_l := Int32.logor (Int32.logand !sr_l mask.(!jc)) (Int32.shift_left (Int32.of_int c) (24 - jc8)) else sr_r := Int32.logor (Int32.logand !sr_r mask.(!jc - 4)) (Int32.shift_left (Int32.of_int c) (56 - jc8)) ); jc := (!jc + 1) mod 8; done; quadruple_of_int32 !sr_l !sr_r, !jc, data' let decrypt_cfb64 k iv j data = if j < 0 or j > 7 then failwith "decrypt_cfb64"; let l = String.length data in let data' = String.create l in let sr_l = ref Int32.zero in (* shift register MSB *) let sr_r = ref Int32.zero in (* shift register LSB *) int32_of_quadruple iv sr_l sr_r; let jc = ref j in for i = 0 to l-1 do if !jc = 0 then M.encrypt_ecb_int32 k !sr_l !sr_r sr_l sr_r; let jc8 = !jc lsl 3 in let sr_jc = if !jc < 4 then (Int32.to_int (Int32.shift_right_logical !sr_l (24 - jc8))) land 0xff else (Int32.to_int (Int32.shift_right_logical !sr_r (56 - jc8))) land 0xff in let c = Char.code(data.[i]) in data'.[i] <- Char.chr (c lxor sr_jc); ( if !jc < 4 then sr_l := Int32.logor (Int32.logand !sr_l mask.(!jc)) (Int32.shift_left (Int32.of_int c) (24 - jc8)) else sr_r := Int32.logor (Int32.logand !sr_r mask.(!jc - 4)) (Int32.shift_left (Int32.of_int c) (56 - jc8)) ); jc := (!jc + 1) mod 8; done; quadruple_of_int32 !sr_l !sr_r, !jc, data' let crypt_ofb k iv j data = if j < 0 or j > 7 then failwith "crypt_ofb"; let l = String.length data in let data' = String.create l in let sr_l = ref Int32.zero in (* shift register MSB *) let sr_r = ref Int32.zero in (* shift register LSB *) int32_of_quadruple iv sr_l sr_r; let jc = ref j in for i = 0 to l-1 do if !jc = 0 then if !jc = 0 then M.encrypt_ecb_int32 k !sr_l !sr_r sr_l sr_r; let jc8 = !jc lsl 3 in let sr_jc = if !jc < 4 then (Int32.to_int (Int32.shift_right_logical !sr_l (24 - jc8))) land 0xff else (Int32.to_int (Int32.shift_right_logical !sr_r (56 - jc8))) land 0xff in let c = Char.code(data.[i]) lxor sr_jc in data'.[i] <- Char.chr c; jc := (!jc + 1) mod 8; done; quadruple_of_int32 !sr_l !sr_r, !jc, data' end ;; (* ====================================================================== * History: * * $Log: cryptmodes_64.ml,v $ * Revision 1.2 2001/03/10 16:43:21 gerd * int32 experiments * * Revision 1.1 1999/06/04 20:42:01 gerd * Initial revision. * * *) cryptgps/cryptmodes_64.mli100664 764 144 17026 7252454651 14525 0ustar gerdusers(* $Id: cryptmodes_64.mli,v 1.2 2001/03/10 16:43:21 gerd Exp $ * ---------------------------------------------------------------------- * This module is part of the cryptgps package by Gerd Stolpmann. *) (* OVERVIEW: * * A block cipher encrypts or decrypts a fixed amount of bits on every * invocation. Here, we assume that the underlying cipher handles 64 bit * blocks as elementary units. * If you have a message which is a multiple of 64 bits, you could encrypt * every block independently. IT IS STRONGLY RECOMMENDED NOT TO USE THIS * SIMPLE APPROACH. This method, often called ECB ("electronic code book"), * is vulnerable by plaintext attacks, even if a strong cipher is used. * This module implements the following, much better alternatives. * * --------------------- * CIPHER BLOCK CHAINING * --------------------- * * USAGE, LIMITATIONS: * * - buffer size: the buffer to be en/decrypted must be a multiple of 64 bits. * - initialization vector: the ivec used for encryption must be same as the * ivec for decryption. The ivec is not secret, it can be transmitted along * with the ciphertext. It is recommended to use the timestamp as ivec, * or some random bits. * * SECURITY: * * - good: * plaintext patterns (i.e. text structure in the plaintext) is hidden in * the ciphertext * - bad: some manipulations in the ciphertext at the end of the message * are possible. To avoid this, compute an MD5 hash of the message, and * PREPEND the hash value to the message. * * FAULT-TOLERANCE: * * - a bit error in the ciphertext affects the corresponding plaintext and * the following block * - no recovery from synchronisation errors possible (missing or extra bits) * * -------------------- * CIPHER-FEEDBACK MODE * -------------------- * * USAGE, LIMITATIONS: * * - buffer size: no restrictions * - initialization vector: the ivec used for encryption must be same as the * ivec for decryption. The ivec is not secret, it can be transmitted along * with the ciphertext. A different ivec must be used for every transmitted * message, e.g. MD5(timestamp + serial number). * * SECURITY: * * - good: * plaintext patterns (i.e. text structure in the plaintext) is hidden in * the ciphertext * - bad: some manipulations in the ciphertext at the end of the message * are possible. To avoid this, compute an MD5 hash of the message, and * PREPEND the hash value to the message. * * FAULT TOLERANCE: * * - a bit error in the ciphertext affects the corresponding plaintext and * the following block * - n-bit CFB can recover from missing n or extra n bits. * * -------------------- * OUTPUT-FEEDBACK MODE * -------------------- * * USAGE, LIMITATIONS: * * - buffer size: no restrictions * - initialization vector: the ivec used for encryption must be same as the * ivec for decryption. The ivec is not secret, it can be transmitted along * with the ciphertext. A different ivec must be used for every transmitted * message, e.g. MD5(timestamp + serial number). * * SECURITY: * * - good: * plaintext patterns (i.e. text structure in the plaintext) is hidden in * the ciphertext * - bad: * manipulation of bits in the ciphertext directly affects the corresponding * bits in the plaintext * * FAULT TOLERANCE: * * - a bit error in the ciphertext affects only corresponding plaintext bit * - n-bit CFB cannot recover from missing or extra bits. * * -------------- * RECOMMENDATION * -------------- * * - If the encrypted messages are transmitted on a serial line, use CFB-8. * This is the only mode which can recover from synchronization errors on * byte level. * - If your message is a multiple of 64 bits, use CBC. If possible, pad * the message to fill up to the next 64 bit multiple, and send the length * of the message, too. * - Otherwise, use CFB-64. *) module type T = sig type key (* CIPHER BLOCK CHAINING MODE *) val encrypt_cbc : key -> (int * int * int * int) -> string -> ((int * int * int * int) * string) (* Encrypts the string whose length MUST be a multiple of 8 bytes * with the given key and initialization vector, resulting in the * output vector (for the next CBC cascade) and the encrypted string. * The size of the string remains unchanged when it is encrypted. *) val decrypt_cbc : key -> (int * int * int * int) -> string -> ((int * int * int * int) * string) (* Decrypts the string whose length MUST be a multiple of 8 bytes * with the given key and initialization vector, resulting in the * output vector (for the next CBC cascade) and the decrypted string. *) (* 8 BIT CIPHER-FEEDBACK MODE *) (* This is 8 times slower than CBC *) val encrypt_cfb8 : key -> (int * int * int * int) -> string -> ((int * int * int * int) * string) (* Encrypts the string (with arbitraty length) with the given key * and initialization vector, resulting in the output vector (for * the next CFB cascade) and the encrypted string (of the same * length). *) val decrypt_cfb8 : key -> (int * int * int * int) -> string -> ((int * int * int * int) * string) (* Decrypts the string (with arbitraty length) with the given key * and initialization vector, resulting in the output vector (for * the next CFB cascade) and the decrypted string (of the same * length). *) (* 64 BIT CIPHER-FEEDBACK MODE *) val encrypt_cfb64 : key -> (int * int * int * int) -> int -> string -> ((int * int * int * int) * int * string) (* Encrypts the string (with arbitraty length) with the given key * and initialization vector, resulting in the output vector (for * the next CFB cascade) and the encrypted string (of the same * length). * Compared with cfb8, there is an additional int that it passed * to and from this function. It is always in the range 0..7 and * indicates which byte of the 64 bit block comes next. In doubt, * pass a 0 as this int. *) val decrypt_cfb64 : key -> (int * int * int * int) -> int -> string -> ((int * int * int * int) * int * string) (* Decrypts the string (with arbitraty length) with the given key * and initialization vector, resulting in the output vector (for * the next CFB cascade) and the decrypted string (of the same * length). *) (* OUTPUT-FEEDBACK MODE (64 bit) *) val crypt_ofb : key -> (int * int * int * int) -> int -> string -> ((int * int * int * int) * int * string) (* Encrypts/Decrypts the string * with the given key and initialization vector, resulting in the * output vector (for the next OFB cascade) and the encrypted string. * The size of the string remains unchanged when it is encrypted. *) end ;; (* Derives the other modes from the basic ECB mode: * * Make_modes: This version is efficient for cryptsystems based on * encrypt_ecb * Make_modes_int32: This version is efficient for cryptsystems based on * encrypt_ecb_int32 * * Both functors behave in an equivalent way; the only difference is that * Make_modes is fast if M.encrypt_ecb is fast, and that Make_modes_int32 * is fast if M.encrypt_ecb_int32 is fast. *) module Make_modes (M : Cryptsystem_64.T) : T with type key = M.key ;; module Make_modes_int32 (M : Cryptsystem_64.T) : T with type key = M.key ;; (* ====================================================================== * History: * * $Log: cryptmodes_64.mli,v $ * Revision 1.2 2001/03/10 16:43:21 gerd * int32 experiments * * Revision 1.1 1999/06/04 20:42:01 gerd * Initial revision. * * *) cryptgps/RELEASE100644 764 144 6 7402536415 12203 0ustar gerdusers0.2.1 cryptgps/cryptsystem_64.ml100664 764 144 3355 7252454651 14551 0ustar gerdusers(* $Id: cryptsystem_64.ml,v 1.2 2001/03/10 16:43:21 gerd Exp $ * ---------------------------------------------------------------------- * This module is part of the cryptgps package by Gerd Stolpmann. *) (* The module type of a cryptsystem using 64 bit block ciphers. *) module type T = sig type key (* This is the internal, often preprocessed representation of keys. *) val encrypt_ecb : key -> (int * int * int * int) -> (int * int * int * int) (* This is the ECB mode of the encryption function. The four ints * are numbers from 0 to 65535, and given from MSB to LSB. *) val encrypt_ecb_int32 : key -> int32 -> int32 -> int32 ref -> int32 ref -> unit (* The same as encrypt_ecb, but with an int32 interface *) val decrypt_ecb : key -> (int * int * int * int) -> (int * int * int * int) (* This is the ECB mode of the decryption function. The four ints * are numbers from 0 to 65535, and given from MSB to LSB. *) val decrypt_ecb_int32 : key -> int32 -> int32 -> int32 ref -> int32 ref -> unit (* The same as decrypt_ecb, but with an int32 interface *) val prepare : string -> key (* Prepares the string representation of a key. *) val textkey : key -> string (* Gets the string representation back *) val is_weak : key -> bool (* Determines whether the key is known as being weak. Do not use * such keys. *) end ;; (* ====================================================================== * History: * * $Log: cryptsystem_64.ml,v $ * Revision 1.2 2001/03/10 16:43:21 gerd * int32 experiments * * Revision 1.1 1999/06/04 20:42:01 gerd * Initial revision. * * *) cryptgps/cryptsystem_64.mli100664 764 144 5773 7252454651 14730 0ustar gerdusers(* $Id: cryptsystem_64.mli,v 1.2 2001/03/10 16:43:21 gerd Exp $ * ---------------------------------------------------------------------- * This module is part of the cryptgps package by Gerd Stolpmann. *) (* The module type of a cryptsystem using 64 bit block ciphers. * Such a module is normally not used directly to encrypt messages. * Only interesting for the average programmer are the key handling * functions: * - prepare: preprocesses the string representation of the key and get * the internal representation. For some ciphers, this is a very expensive * operation (e.g. for blowfish). * - is_weak: for some ciphers, some keys have bad characteristics and * should not be used to encrypt messages. These keys are called weak. * * HOW TO TRANSFORM A PASSWORD/PASSPHRASE INTO A KEY: * * It is not recommended to apply 'prepare' directly to the passphrase that * the user types in. As letters are much more likely than other characters, * and some bits are never used, the number of different keys would be * MUCH smaller than the number of possible keys. To avoid this, apply * an MD5 hash function on the ascii representation of the passphrase before * passing the value to 'prepare', i.e. * * let k = prepare (Digest.substring passphrase 0 (String.length passphrase)) * * Note, that the resulting key has not more than 128 bits, even if the * passphrase is longer. * To get a 256 bit key, you can concatenate the MD5 of the passphrase * and the MD5 of the reverted passphrase. * Up to now, 128 bit keys are secure. * *) module type T = sig type key (* This is the internal, often preprocessed representation of keys. *) val encrypt_ecb : key -> (int * int * int * int) -> (int * int * int * int) (* This is the ECB mode of the encryption function. The four ints * are numbers from 0 to 65535, and given from MSB to LSB. *) val encrypt_ecb_int32 : key -> int32 -> int32 -> int32 ref -> int32 ref -> unit (* The same as encrypt_ecb, but with an int32 interface *) val decrypt_ecb : key -> (int * int * int * int) -> (int * int * int * int) (* This is the ECB mode of the decryption function. The four ints * are numbers from 0 to 65535, and given from MSB to LSB. *) val decrypt_ecb_int32 : key -> int32 -> int32 -> int32 ref -> int32 ref -> unit (* The same as decrypt_ecb, but with an int32 interface *) val prepare : string -> key (* Prepares the string representation of a key. *) val textkey : key -> string (* Gets the string representation back *) val is_weak : key -> bool (* Determines whether the key is known as being weak. Do not use * such keys. *) end ;; (* ====================================================================== * History: * * $Log: cryptsystem_64.mli,v $ * Revision 1.2 2001/03/10 16:43:21 gerd * int32 experiments * * Revision 1.1 1999/06/04 20:42:01 gerd * Initial revision. * * *) cryptgps/test/ 40755 764 144 0 7252455046 12151 5ustar gerduserscryptgps/test/Makefile100644 764 144 2113 7252427632 13703 0ustar gerdusersSSLEAY_INCL = /usr/ssl/include SSLEAY_LIB = /usr/ssl/lib CC = gcc -I$(SSLEAY_INCL) -L$(SSLEAY_LIB) all: speed_blowfish_byte speed_blowfish_native speed_blowfish_c \ speed_des_byte speed_des_native speed_des_c speed_blowfish_byte: speed_blowfish.ml ../cryptgps.cma ocamlc -o speed_blowfish_byte -I .. bigarray.cma ../cryptgps.cma speed_blowfish.ml speed_blowfish_native: speed_blowfish.ml ../cryptgps.cmxa ocamlopt -o speed_blowfish_native -I .. bigarray.cmxa ../cryptgps.cmxa speed_blowfish.ml speed_blowfish_c: speed_blowfish.c $(CC) -o speed_blowfish_c speed_blowfish.c -lcrypto speed_des_byte: speed_des.ml ../cryptgps.cma ocamlc -o speed_des_byte -I .. ../cryptgps.cma speed_des.ml speed_des_native: speed_des.ml ../cryptgps.cmxa ocamlopt -p -o speed_des_native -I .. ../cryptgps.cmxa speed_des.ml speed_des_c: speed_des.c $(CC) -o speed_des_c speed_des.c -lcrypto clean: rm -f *.cmi *.cmo *.cmx *.o rm -f speed_blowfish_c speed_blowfish_byte speed_blowfish_native rm -f speed_des_c speed_des_byte speed_des_native rm -f gmon.out distclean: clean rm -f *~ cryptgps/test/speed_blowfish.ml100644 764 144 416 7252455025 15553 0ustar gerdusersopen Crypt_blowfish;; (* or Crypt_blowfish32 *) open Cryptsystem;; open Cryptmodes;; let k = prepare "abcdefghijklmnop";; let s = String.make (1024*1024) ' ';; let x0 = Sys.time() in ignore(encrypt_cbc k (0,0,0,0) s); print_float (Sys.time() -. x0); print_newline() ;; cryptgps/test/speed_blowfish.c100644 764 144 1172 6725051206 15402 0ustar gerdusers#include #include #include #include "blowfish.h" main () { BF_KEY k; unsigned char in[1024*1024]; unsigned char out[1024*1024]; unsigned char ivec[8]; int i; struct timeval tv; double t1,t2; BF_set_key(&k, 16, "abcdefghijklmnop"); /* CBC TEST */ for (i=0; i<8; i++) ivec[i] = 0; for (i=0; i<1024*1024; i++) in[i] = ' '; gettimeofday(&tv, NULL); t1 = tv.tv_sec + tv.tv_usec * 1E-6; BF_cbc_encrypt(in, out, 1024*1024, &k, ivec, 1); gettimeofday(&tv, NULL); t2 = tv.tv_sec + tv.tv_usec * 1E-6; printf("%f\n", t2-t1); } cryptgps/test/speed_des.ml100644 764 144 364 6731770346 14522 0ustar gerdusersopen Crypt_des;; open Cryptsystem;; open Cryptmodes;; let k = prepare (set_parity "abcdefgh");; let s = String.make (1024*1024) ' ';; let x0 = Sys.time() in ignore(encrypt_cbc k (0,0,0,0) s); print_float (Sys.time() -. x0); print_newline() ;; cryptgps/test/speed_des.c100644 764 144 1162 6731770477 14356 0ustar gerdusers#include #include #include #include "des.h" main () { des_key_schedule k; unsigned char in[1024*1024]; unsigned char out[1024*1024]; unsigned char ivec[8]; int i; struct timeval tv; double t1,t2; des_set_key("abcdefgh",k); /* CBC TEST */ for (i=0; i<8; i++) ivec[i] = 0; for (i=0; i<1024*1024; i++) in[i] = ' '; gettimeofday(&tv, NULL); t1 = tv.tv_sec + tv.tv_usec * 1E-6; des_cbc_encrypt(in, out, 1024*1024, k, ivec, 1); gettimeofday(&tv, NULL); t2 = tv.tv_sec + tv.tv_usec * 1E-6; printf("%f\n", t2-t1); } cryptgps/crypt_des.ml100664 764 144 70017 7252454651 13645 0ustar gerdusers(* $Id: crypt_des.ml,v 1.10 2001/03/10 16:43:21 gerd Exp $ * ---------------------------------------------------------------------- * This module is part of the cryptgps package by Gerd Stolpmann. *) (* Note: Bits are numbered from MSB to LSB! *) (* 64 bit numbers are represented as four 16 bit numbers, * (int * int * int * int), MSB first. * 56 bit numbers: like 64 bit numbers with 4 leading and 4 trailing zeros. * 48 bit numbers are represented as two 24 bit numbers, * (int * int), MSB first. * 32 bit numbers are represented as two 16 bit numbers, * (int * int), MSB first. *) open Crypt_aux (******************** key parity ************************) let odd_parity = [| 1; 1; 2; 2; 4; 4; 7; 7; 8; 8; 11; 11; 13; 13; 14; 14; 16; 16; 19; 19; 21; 21; 22; 22; 25; 25; 26; 26; 28; 28; 31; 31; 32; 32; 35; 35; 37; 37; 38; 38; 41; 41; 42; 42; 44; 44; 47; 47; 49; 49; 50; 50; 52; 52; 55; 55; 56; 56; 59; 59; 61; 61; 62; 62; 64; 64; 67; 67; 69; 69; 70; 70; 73; 73; 74; 74; 76; 76; 79; 79; 81; 81; 82; 82; 84; 84; 87; 87; 88; 88; 91; 91; 93; 93; 94; 94; 97; 97; 98; 98;100;100;103;103;104;104;107;107;109;109;110;110; 112;112;115;115;117;117;118;118;121;121;122;122;124;124;127;127; 128;128;131;131;133;133;134;134;137;137;138;138;140;140;143;143; 145;145;146;146;148;148;151;151;152;152;155;155;157;157;158;158; 161;161;162;162;164;164;167;167;168;168;171;171;173;173;174;174; 176;176;179;179;181;181;182;182;185;185;186;186;188;188;191;191; 193;193;194;194;196;196;199;199;200;200;203;203;205;205;206;206; 208;208;211;211;213;213;214;214;217;217;218;218;220;220;223;223; 224;224;227;227;229;229;230;230;233;233;234;234;236;236;239;239; 241;241;242;242;244;244;247;247;248;248;251;251;253;253;254;254; |];; let check_parity key = let l_key = String.length key in if l_key <> 8 then failwith "Crypt_des: invalid key length"; for i = 0 to 7 do let k = Char.code key.[i] in if k <> odd_parity.(k) then failwith "Crypt_des: key parity error" done; () ;; let set_parity key = let l_key = String.length key in if l_key <> 8 then failwith "Crypt_des: invalid key length"; let key' = String.copy key in for i = 0 to 7 do let k = Char.code key.[i] in key'.[i] <- Char.chr(odd_parity.(k)) done; key' ;; module Cryptsystem : Cryptsystem_64.T = struct type value64 = (int * int * int * int) type value48 = (int * int) type value32 = (int * int) (********************* permutations **********************) type perm64 = value64 array (* An array with 8 * 256 elements describing 64 bit numbers. * To permute a 64 bit number (b1,b2,b3,b4,b5,b6,b7,b8) given as byte * sequence, do * a.(b1) lor a.(256+b2) lor a.(512+b3) lor ... lor a.(1792+b8) *) type perm48 = value48 array (* An array with 6 * 256 elements describing 48 bit numbers. * To permute a 48 bit number (b1,b2,b3,b4,b5,b6) given as byte * sequence, do * a.(b1) lor a.(256+b2) lor a.(512+b3) lor ... lor a.(1280+b6) *) type perm32 = value32 array (* An array with 4 * 256 elements describing 32 bit numbers. * To permute a 32 bit number (b1,b2,b3,b4) given as byte * sequence, do * a.(b1) lor a.(256+b2) lor a.(512+b3) lor a.(768+b4) *) let quad_lor (a,b,c,d) (a',b',c',d') = (a lor a', b lor b', c lor c', d lor d') let ( |||| ) = quad_lor let double_lor (a,b) (a',b') = (a lor a', b lor b') let ( || ) = double_lor let inv64 p = let rec pos k x = if k < 64 then begin if p.(k) = x then k else pos (k+1) x end else failwith "inv64" in let p' = Array.create 64 0 in for k = 0 to 63 do p'.(k) <- pos 0 k done; p' let mk_perm64 p' = (* p: a 64 element array. p(i)=j means that bit position i of the output * is bit position j in the input. *) let rec pos k x = if k < 64 then begin if p'.(k) = x then k :: pos (k+1) x else pos (k+1) x end else [] in let p = Array.create 64 [] in for k = 0 to 63 do p.(k) <- pos 0 k done; let p64 = Array.create 2048 (0,0,0,0) in for n = 0 to 7 do (* n counts bytes *) for v = 0 to 255 do (* v counts values of a byte *) let v' = ref (0,0,0,0) in for ni = 0 to 7 do (* ni counts bits within bytes *) let i = 8*n + ni in if ((v lsl ni) land (0x80)) > 0 then begin List.iter (fun j -> (* the bit in position ni of byte v is set *) match j lsr 4 with 0 -> v' := !v' |||| (0x8000 lsr j, 0, 0, 0) | 1 -> v' := !v' |||| (0, 0x8000 lsr (j-16), 0, 0) | 2 -> v' := !v' |||| (0, 0, 0x8000 lsr (j-32), 0) | 3 -> v' := !v' |||| (0, 0, 0, 0x8000 lsr (j-48)) | _ -> () ) p.(i) end; done; p64.(256*n + v) <- !v' done done; p64 let do_perm64 (p64:perm64) (v64:value64) = let (a,b,c,d) = v64 in let (a0,b0,c0,d0) = p64.( a lsr 8 ) in let (a1,b1,c1,d1) = p64.( 256 + (a land 0xff)) in let (a2,b2,c2,d2) = p64.( 512 + (b lsr 8) ) in let (a3,b3,c3,d3) = p64.( 768 + (b land 0xff) ) in let (a4,b4,c4,d4) = p64.( 1024 + (c lsr 8) ) in let (a5,b5,c5,d5) = p64.( 1280 + (c land 0xff) ) in let (a6,b6,c6,d6) = p64.( 1536 + (d lsr 8) ) in let (a7,b7,c7,d7) = p64.( 1792 + (d land 0xff) ) in (a0 lor a1 lor a2 lor a3 lor a4 lor a5 lor a6 lor a7, b0 lor b1 lor b2 lor b3 lor b4 lor b5 lor b6 lor b7, c0 lor c1 lor c2 lor c3 lor c4 lor c5 lor c6 lor c7, d0 lor d1 lor d2 lor d3 lor d4 lor d5 lor d6 lor d7) let mk_perm48 p' = (* p: a 48 element array. p(i)=j means that bit position i of the output * is bit position j in the input. *) let rec pos k x = if k < 48 then begin if p'.(k) = x then k :: pos (k+1) x else pos (k+1) x end else [] in let p = Array.create 48 [] in for k = 0 to 47 do p.(k) <- pos 0 k done; let p48 = Array.create 1536 (0,0) in for n = 0 to 5 do (* n counts bytes *) for v = 0 to 255 do (* v counts values of a byte *) let v' = ref (0,0) in for ni = 0 to 7 do (* ni counts bits within bytes *) let i = 8*n + ni in if ((v lsl ni) land (0x80)) > 0 then begin (* the bit in position ni of byte v is set *) List.iter (fun j -> match j / 24 with 0 -> v' := !v' || (0x800000 lsr j, 0) | 1 -> v' := !v' || (0, 0x800000 lsr (j-24)) | _ -> ()) p.(i) end done; p48.(256*n + v) <- !v' done done; p48 let do_perm48 (p48:perm48) (v48:value48) = let (a,b) = v48 in let (a0,b0) = p48.( a lsr 16 ) in let (a1,b1) = p48.( 256 + ((a lsr 8) land 0xff)) in let (a2,b2) = p48.( 512 + (a land 0xff) ) in let (a3,b3) = p48.( 768 + ( b lsr 16 ) ) in let (a4,b4) = p48.( 1024 + ((b lsr 8) land 0xff) ) in let (a5,b5) = p48.( 1280 + (b land 0xff) ) in ( a0 lor a1 lor a2 lor a3 lor a4 lor a5, b0 lor b1 lor b2 lor b3 lor b4 lor b5 ) let combine48_and_64 (p48:perm48) (p64:perm64) : perm64 = (* creates a 'perm64' like table which is: * let (a,b,c,d) = do_perm64 (x0,x1) in * let (a',b') = do_perm48 (a,b) in * let (c',d') = do_perm48 (c,d) in * (a',b',c',d') * Note that the result is, strictly speaking, no value64, but * a value96. *) let q = Array.create 2048 (0,0,0,0) in for i = 0 to 2047 do let (a,b,c,d) = p64.(i) in let (a',b') = do_perm48 p48 (a,b) in let (c',d') = do_perm48 p48 (c,d) in q.(i) <- (a',b',c',d') done; q let mk_perm32 p' = (* p: a 32 element array. p(i)=j means that bit position i of the output * is bit position j in the input. *) let rec pos k x = if k < 32 then begin if p'.(k) = x then k :: pos (k+1) x else pos (k+1) x end else [] in let p = Array.create 32 [] in for k = 0 to 31 do p.(k) <- pos 0 k done; let p32 = Array.create 1024 (0,0) in for n = 0 to 3 do (* n counts bytes *) for v = 0 to 255 do (* v counts values of a byte *) let v' = ref (0,0) in for ni = 0 to 7 do (* ni counts bits within bytes *) let i = 8*n + ni in let j = p.(i) in if ((v lsl ni) land (0x80)) > 0 then begin (* the bit in position ni of byte v is set *) List.iter (fun j -> match j lsr 4 with 0 -> v' := !v' || (0x8000 lsr j, 0) | 1 -> v' := !v' || (0, 0x8000 lsr (j-16)) | _ -> ()) p.(i) end done; p32.(256*n + v) <- !v' done done; p32 let do_perm32 (p32:perm32) (v32:value32) = let (a,b) = v32 in let (a0,b0) = p32.( a lsr 8 ) in let (a1,b1) = p32.( 256 + (a land 0xff)) in let (a2,b2) = p32.( 512 + (b lsr 8) ) in let (a3,b3) = p32.( 768 + (b land 0xff)) in ( a0 lor a1 lor a2 lor a3, b0 lor b1 lor b2 lor b3 ) let des_iperm, des_fperm = (* initial, final permutation *) let p = [| 57; 49; 41; 33; 25; 17; 9; 1; 59; 51; 43; 35; 27; 19; 11; 3; 61; 53; 45; 37; 29; 21; 13; 5; 63; 55; 47; 39; 31; 23; 15; 7; 56; 48; 40; 32; 24; 16; 8; 0; 58; 50; 42; 34; 26; 18; 10; 2; 60; 52; 44; 36; 28; 20; 12; 4; 62; 54; 46; 38; 30; 22; 14; 6 |] in let p' = inv64 p in lazy (mk_perm64 p), lazy (mk_perm64 p') (* OK *) let des_kperm = (* key permutation *) lazy (mk_perm64 [| 64; 64; 64; 64; 56; 48; 40; 32; 24; 16; 8; 0; 57; 49; 41; 33; 25; 17; 9; 1; 58; 50; 42; 34; 26; 18; 10; 2; 59; 51; 43; 35; 62; 54; 46; 38; 30; 22; 14; 6; 61; 53; 45; 37; 29; 21; 13; 5; 60; 52; 44; 36; 28; 20; 12; 4; 27; 19; 11; 3; 64; 64; 64; 64 |] ) (* OK *) (* des_kperm: this is a 64-to-56 bit permutation. Remember that 56 bit * numbers are represented like 64 bit numbers but have 4 leading and * 4 trailing zeros. The "64" in the array literal above sets the corresponding * bit to zero. *) let des_cperm = (* compression permutation *) lazy (mk_perm64 [| 64; 64; 64; 64; 64; 64; 64; 64; 17; 20; 14; 27; 4; 8; 6; 31; 18; 9; 24; 13; 26; 22; 15; 7; 29; 11; 19; 10; 30; 23; 16; 5; 64; 64; 64; 64; 64; 64; 64; 64; 44; 55; 34; 40; 50; 58; 33; 43; 54; 48; 36; 51; 47; 52; 42; 59; 37; 56; 49; 45; 53; 39; 32; 35; |] ) (* OK *) (* des_cperm: This is a 56-to-48 bit permutation. The input number is a * 56 bit number represented as described above (using bits 4 to 59 of a * 64 bit number). * The output number has a special representation, using bits 8 to 31 and * bits 40 to 63 of a 64 bit number. This representation simplifies the * conversion to value48. *) let des_xperm = (* expansion permutation *) lazy (mk_perm48 (Array.map (fun n -> if n <= 16 then n+7 else n+15) [| 32; 1; 2; 3; 4; 5; 4; 5; 6; 7; 8; 9; 8; 9; 10; 11; 12; 13; 12; 13; 14; 15; 16; 17; 16; 17; 18; 19; 20; 21; 20; 21; 22; 23; 24; 25; 24; 25; 26; 27; 28; 29; 28; 29; 30; 31; 32; 1 |] )) (* (OK) *) (* 1..16: + 7 *) (* 17..32: + 15 *) (* des_xperm: This is a 32-to-48 bit permutation. The input number is a * value32 taken as value48, i.e. bits 8 to 23 and 32 to 47 are used. * The output number is a value48. *) let des_ixperm = (* combined iperm and xperm *) lazy (let iperm = Lazy.force des_iperm in let xperm = Lazy.force des_xperm in combine48_and_64 xperm iperm) let des_pboxperm = lazy (mk_perm32 [| 15; 6; 19; 20; 28; 11; 27; 16; 0; 14; 22; 25; 4; 17; 30; 9; 1; 7; 23; 13; 31; 26; 2; 8; 18; 12; 29; 5; 21; 10; 3; 24 |] ) (* (OK) *) (* des_pboxperm: a 32-to-32 bit permutation *) (********************* S-boxes ***************************) (* an S-box is an array with 64 numbers from 0 to 15 *) let mk_sbox p48 p32 shift a = (* transform the S-box notation found in the literature to a lookup table *) (* p48: a 48-bit permutation which should be applied immediately * p32: a 32-bit permutation which should be applied immediately * shift: either 0,4,8,12,16,20,24, or 28. *) let a' = Array.create 64 (0,0) in for k' = 0 to 63 do let k = ((k' land 0x1e) lsr 1) lor (k' land 0x20) lor ((k' land 1) lsl 4) in let x = a.(k) in let x' = if shift < 16 then (0, x lsl shift) else (x lsl (shift-16), 0) in a'.( k' ) <- do_perm48 p48 (do_perm32 p32 x') done; a' let sbox1 = lazy (let pboxperm = Lazy.force des_pboxperm in let xperm = Lazy.force des_xperm in mk_sbox xperm pboxperm 28 [| 14; 4; 13; 1; 2; 15; 11; 8; 3; 10; 6; 12; 5; 9; 0; 7; 0; 15; 7; 4; 14; 2; 13; 1; 10; 6; 12; 11; 9; 5; 3; 8; 4; 1; 14; 8; 13; 6; 2; 11; 15; 12; 9; 7; 3; 10; 5; 0; 15; 12; 8; 2; 4; 9; 1; 7; 5; 11; 3; 14; 10; 0; 6; 13 |]) (* (OK) *) let sbox2 = lazy (let pboxperm = Lazy.force des_pboxperm in let xperm = Lazy.force des_xperm in mk_sbox xperm pboxperm 24 [| 15; 1; 8; 14; 6; 11; 3; 4; 9; 7; 2; 13; 12; 0; 5; 10; 3; 13; 4; 7; 15; 2; 8; 14; 12; 0; 1; 10; 6; 9; 11; 5; 0; 14; 7; 11; 10; 4; 13; 1; 5; 8; 12; 6; 9; 3; 2; 15; 13; 8; 10; 1; 3; 15; 4; 2; 11; 6; 7; 12; 0; 5; 14; 9 |]) (* (OK) *) let sbox3 = lazy (let pboxperm = Lazy.force des_pboxperm in let xperm = Lazy.force des_xperm in mk_sbox xperm pboxperm 20 [| 10; 0; 9; 14; 6; 3; 15; 5; 1; 13; 12; 7; 11; 4; 2; 8; 13; 7; 0; 9; 3; 4; 6; 10; 2; 8; 5; 14; 12; 11; 15; 1; 13; 6; 4; 9; 8; 15; 3; 0; 11; 1; 2; 12; 5; 10; 14; 7; 1; 10; 13; 0; 6; 9; 8; 7; 4; 15; 14; 3; 11; 5; 2; 12 |]) (* (OK) *) let sbox4 = lazy (let pboxperm = Lazy.force des_pboxperm in let xperm = Lazy.force des_xperm in mk_sbox xperm pboxperm 16 [| 7; 13; 14; 3; 0; 6; 9; 10; 1; 2; 8; 5; 11; 12; 4; 15; 13; 8; 11; 5; 6; 15; 0; 3; 4; 7; 2; 12; 1; 10; 14; 9; 10; 6; 9; 0; 12; 11; 7; 13; 15; 1; 3; 14; 5; 2; 8; 4; 3; 15; 0; 6; 10; 1; 13; 8; 9; 4; 5; 11; 12; 7; 2; 14 |]) (* (OK) *) let sbox5 = lazy (let pboxperm = Lazy.force des_pboxperm in let xperm = Lazy.force des_xperm in mk_sbox xperm pboxperm 12 [| 2; 12; 4; 1; 7; 10; 11; 6; 8; 5; 3; 15; 13; 0; 14; 9; 14; 11; 2; 12; 4; 7; 13; 1; 5; 0; 15; 10; 3; 9; 8; 6; 4; 2; 1; 11; 10; 13; 7; 8; 15; 9; 12; 5; 6; 3; 0; 14; 11; 8; 12; 7; 1; 14; 2; 13; 6; 15; 0; 9; 10; 4; 5; 3 |]) (* (OK) *) let sbox6 = lazy (let pboxperm = Lazy.force des_pboxperm in let xperm = Lazy.force des_xperm in mk_sbox xperm pboxperm 8 [| 12; 1; 10; 15; 9; 2; 6; 8; 0; 13; 3; 4; 14; 7; 5; 11; 10; 15; 4; 2; 7; 12; 9; 5; 6; 1; 13; 14; 0; 11; 3; 8; 9; 14; 15; 5; 2; 8; 12; 3; 7; 0; 4; 10; 1; 13; 11; 6; 4; 3; 2; 12; 9; 5; 15; 10; 11; 14; 1; 7; 6; 0; 8; 13 |]) (* (OK) *) let sbox7 = lazy (let pboxperm = Lazy.force des_pboxperm in let xperm = Lazy.force des_xperm in mk_sbox xperm pboxperm 4 [| 4; 11; 2; 14; 15; 0; 8; 13; 3; 12; 9; 7; 5; 10; 6; 1; 13; 0; 11; 7; 4; 9; 1; 10; 14; 3; 5; 12; 2; 15; 8; 6; 1; 4; 11; 13; 12; 3; 7; 14; 10; 15; 6; 8; 0; 5; 9; 2; 6; 11; 13; 8; 1; 4; 10; 7; 9; 5; 0; 15; 14; 2; 3; 12 |]) (* (OK) *) let sbox8 = lazy (let pboxperm = Lazy.force des_pboxperm in let xperm = Lazy.force des_xperm in mk_sbox xperm pboxperm 0 [| 13; 2; 8; 4; 6; 15; 11; 1; 10; 9; 3; 14; 5; 0; 12; 7; 1; 15; 13; 8; 10; 3; 7; 4; 12; 5; 6; 11; 0; 14; 9; 2; 7; 11; 4; 1; 9; 12; 14; 2; 0; 6; 10; 13; 15; 3; 5; 8; 2; 1; 14; 7; 4; 10; 8; 13; 15; 12; 9; 0; 3; 5; 6; 11; |]) (* (OK) *) (******************* The algorithm ************************) type key = { data : string; k64 : value64; k56 : value64; k_enc : value48 array; k_dec : value48 array; fperm : perm64; ixperm : perm64; sbox1 : (int * int) array; sbox2 : (int * int) array; sbox3 : (int * int) array; sbox4 : (int * int) array; sbox5 : (int * int) array; sbox6 : (int * int) array; sbox7 : (int * int) array; sbox8 : (int * int) array; (* k_enc: encryption keys for 16 rounds; * k_dec: decryption keys for 16 rounds *) } let des key k x = let fperm = key.fperm in let ixperm = key.ixperm in let s1 = key.sbox1 in let s2 = key.sbox2 in let s3 = key.sbox3 in let s4 = key.sbox4 in let s5 = key.sbox5 in let s6 = key.sbox6 in let s7 = key.sbox7 in let s8 = key.sbox8 in let rec do_rounds i blast0 blast1 last0 last1 = let l48_0 = blast0 in let l48_1 = blast1 in let r48_0 = last0 in let r48_1 = last1 in if i < 16 then let k48_0, k48_1 = k.(i) in let y0 = k48_0 lxor r48_0 in let y1 = k48_1 lxor r48_1 in let x00,x01 = s1.( y0 lsr 18 ) in let x10,x11 = s2.( (y0 lsr 12) land 63 ) in let x20,x21 = s3.( (y0 lsr 6) land 63 ) in let x30,x31 = s4.( y0 land 63 ) in let x40,x41 = s5.( y1 lsr 18 ) in let x50,x51 = s6.( (y1 lsr 12) land 63 ) in let x60,x61 = s7.( (y1 lsr 6) land 63 ) in let x70,x71 = s8.( y1 land 63 ) in let p0 =x00 lor x10 lor x20 lor x30 lor x40 lor x50 lor x60 lor x70 in let p1 =x01 lor x11 lor x21 lor x31 lor x41 lor x51 lor x61 lor x71 in do_rounds (i+1) last0 last1 (p0 lxor l48_0) (p1 lxor l48_1) else (* TO COMPUTE: l32_0, l32_1 = do_perm (inverse xperm) (l48_0,l48_1) *) let l32_0 = ((l48_0 lsr 1) land 0x001f) lor ((l48_0 lsr 3) land 0x01e0) lor ((l48_0 lsr 5) land 0x1e00) lor ((l48_0 lsr 7) land 0xe000) in let l32_1 = ((l48_1 lsr 1) land 0x001f) lor ((l48_1 lsr 3) land 0x01e0) lor ((l48_1 lsr 5) land 0x1e00) lor ((l48_1 lsr 7) land 0xe000) in (* TO COMPUTE: r32_0, r32_1 = do_perm (inverse xperm) (r48_0,r48_1) *) let r32_0 = ((r48_0 lsr 1) land 0x001f) lor ((r48_0 lsr 3) land 0x01e0) lor ((r48_0 lsr 5) land 0x1e00) lor ((r48_0 lsr 7) land 0xe000) in let r32_1 = ((r48_1 lsr 1) land 0x001f) lor ((r48_1 lsr 3) land 0x01e0) lor ((r48_1 lsr 5) land 0x1e00) lor ((r48_1 lsr 7) land 0xe000) in (* --------- manually inlined code ---------- *) (* OLD: do_perm64 fperm (last0, last1, blast0, blast1) *) let (a0,b0,c0,d0) = fperm.( r32_0 lsr 8 ) in let (a1,b1,c1,d1) = fperm.( 256 lor (r32_0 land 0xff)) in let (a2,b2,c2,d2) = fperm.( 512 lor (r32_1 lsr 8) ) in let (a3,b3,c3,d3) = fperm.( 768 lor (r32_1 land 0xff) ) in let (a4,b4,c4,d4) = fperm.( 1024 lor (l32_0 lsr 8) ) in let (a5,b5,c5,d5) = fperm.( 1280 lor (l32_0 land 0xff) ) in let (a6,b6,c6,d6) = fperm.( 1536 lor (l32_1 lsr 8) ) in let (a7,b7,c7,d7) = fperm.( 1792 lor (l32_1 land 0xff) ) in (a0 lor a1 lor a2 lor a3 lor a4 lor a5 lor a6 lor a7, b0 lor b1 lor b2 lor b3 lor b4 lor b5 lor b6 lor b7, c0 lor c1 lor c2 lor c3 lor c4 lor c5 lor c6 lor c7, d0 lor d1 lor d2 lor d3 lor d4 lor d5 lor d6 lor d7) (* ------------------ end -------------------- *) in (* --------- manually inlined code ---------- *) (* OLD: let (l00_48, l01_48, r00_48, r01_48) = do_perm64 ixperm x in *) let (a,b,c,d) = x in let (a0,b0,c0,d0) = ixperm.( a lsr 8 ) in let (a1,b1,c1,d1) = ixperm.( 256 lor (a land 0xff)) in let (a2,b2,c2,d2) = ixperm.( 512 lor (b lsr 8) ) in let (a3,b3,c3,d3) = ixperm.( 768 lor (b land 0xff) ) in let (a4,b4,c4,d4) = ixperm.( 1024 lor (c lsr 8) ) in let (a5,b5,c5,d5) = ixperm.( 1280 lor (c land 0xff) ) in let (a6,b6,c6,d6) = ixperm.( 1536 lor (d lsr 8) ) in let (a7,b7,c7,d7) = ixperm.( 1792 lor (d land 0xff) ) in let l00_48 = a0 lor a1 lor a2 lor a3 lor a4 lor a5 lor a6 lor a7 in let l01_48 = b0 lor b1 lor b2 lor b3 lor b4 lor b5 lor b6 lor b7 in let r00_48 = c0 lor c1 lor c2 lor c3 lor c4 lor c5 lor c6 lor c7 in let r01_48 = d0 lor d1 lor d2 lor d3 lor d4 lor d5 lor d6 lor d7 in (* ------------------ end -------------------- *) do_rounds 0 l00_48 l01_48 r00_48 r01_48 let encrypt_ecb k x = des k k.k_enc x let encrypt_ecb_int32 k xl xr ret_xl ret_xr = let x = quadruple_of_int32 xl xr in let y = encrypt_ecb k x in int32_of_quadruple y ret_xl ret_xr let decrypt_ecb k x = des k k.k_dec x let decrypt_ecb_int32 k xl xr ret_xl ret_xr = let x = quadruple_of_int32 xl xr in let y = decrypt_ecb k x in int32_of_quadruple y ret_xl ret_xr let prepare key = let l_key = String.length key in if l_key <> 8 (* & l_key <> 7 *) then failwith "Crypt_des: invalid key length"; let iperm = Lazy.force des_iperm in let fperm = Lazy.force des_fperm in let kperm = Lazy.force des_kperm in let cperm = Lazy.force des_cperm in let xperm = Lazy.force des_xperm in let pboxperm = Lazy.force des_pboxperm in let s1 = Lazy.force sbox1 in let s2 = Lazy.force sbox2 in let s3 = Lazy.force sbox3 in let s4 = Lazy.force sbox4 in let s5 = Lazy.force sbox5 in let s6 = Lazy.force sbox6 in let s7 = Lazy.force sbox7 in let s8 = Lazy.force sbox8 in let k56, k64 = if l_key = 8 then begin check_parity key; let k64 = ( (Char.code(key.[0]) lsl 8) lor (Char.code(key.[1])), (Char.code(key.[2]) lsl 8) lor (Char.code(key.[3])), (Char.code(key.[4]) lsl 8) lor (Char.code(key.[5])), (Char.code(key.[6]) lsl 8) lor (Char.code(key.[7])) ) in do_perm64 kperm k64, k64 end else (* l_key = 7 *) (* This is currently not supported! *) failwith "Crypt_des" (* let k0 = Char.code key.[0] in let k1 = Char.code key.[1] in let k2 = Char.code key.[2] in let k3 = Char.code key.[3] in let k4 = Char.code key.[4] in let k5 = Char.code key.[5] in let k6 = Char.code key.[6] in ( (k0 lsl 4) lor (k1 lsr 4), ((k1 land 15) lsl 12) lor (k2 lsl 4) lor (k3 lsr 4), ((k3 land 15) lsl 12) lor (k4 lsl 4) lor (k5 lsr 4), ((k5 land 15) lsl 12) lor (k6 lsl 4) ) *) in (* compute encryption keys *) let shifts = [| 1; 1; 2; 2; 2; 2; 2; 2; 1; 2; 2; 2; 2; 2; 2; 1 |] in let cycle28 x n = (* shift 28 bit number x circularly left by n bits; n <= 2 *) let x' = x lsl n in (x' land 0xfffffff) lor (x' lsr 28) in let k = ref k56 in let k_enc = Array.create 16 (0,0) in let k_dec = Array.create 16 (0,0) in for n = 0 to 15 do let (k0,k1,k2,k3) = !k in let k_left = (k0 lsl 16) lor k1 in (* k_left: 28 bits *) let k_right = (k2 lsl 12) lor (k3 lsr 4) in (* k_right: 28 bits *) let s = shifts.(n) in let k_left' = cycle28 k_left s in let k_right' = cycle28 k_right s in k := ( k_left' lsr 16, k_left' land 0xffff, k_right' lsr 12, (k_right' land 0xfff) lsl 4 ); let (c0,c1,c2,c3) = do_perm64 cperm !k in let k48_0, k48_1 = ( (c0 lsl 16) lor c1, (c2 lsl 16) lor c3 ) in k_enc.(n) <- k48_0, k48_1; k_dec.(15 - n) <- k_enc.(n) done; { data = key; k64 = k64; k56 = k56; k_enc = k_enc; k_dec = k_dec; fperm = Lazy.force des_fperm; ixperm = Lazy.force des_ixperm; sbox1 = Lazy.force sbox1; sbox2 = Lazy.force sbox2; sbox3 = Lazy.force sbox3; sbox4 = Lazy.force sbox4; sbox5 = Lazy.force sbox5; sbox6 = Lazy.force sbox6; sbox7 = Lazy.force sbox7; sbox8 = Lazy.force sbox8; } let textkey k = k.data let is_weak k = let weak_keys = [ 0x0101, 0x0101, 0x0101, 0x0101; (* weak keys *) 0x1f1f, 0x1f1f, 0x0e0e, 0x0e0e; 0xe0e0, 0xe0e0, 0xf1f1, 0xf1f1; 0xfefe, 0xfefe, 0xfefe, 0xfefe; 0x01fe, 0x01fe, 0x01fe, 0x01fe; (* semiweak keys *) 0xfe01, 0xfe01, 0xfe01, 0xfe01; 0x1fe0, 0x1fe0, 0x0ef1, 0x0ef1; 0xe01f, 0xe01f, 0xf10e, 0xf10e; 0x01e0, 0x01e0, 0x01f1, 0x01f1; 0xe001, 0xe001, 0xf101, 0xf101; 0x1ffe, 0x1ffe, 0x0efe, 0x0efe; 0xfe1f, 0xfe1f, 0xfe0e, 0xfe0e; 0x011f, 0x011f, 0x010e, 0x010e; 0x1f01, 0x1f01, 0x0e01, 0x0e01; 0xe0fe, 0xe0fe, 0xf1fe, 0xf1fe; 0xfee0, 0xfee0, 0xfef1, 0xfef1; 0x1f1f, 0x0101, 0x0e0e, 0x0101; (* possibly weak keys *) 0x011f, 0x1f01, 0x010e, 0x0e01; 0x1f01, 0x011f, 0x0e01, 0x010e; 0x0101, 0x1f1f, 0x0101, 0x0e0e; 0xe0e0, 0x0101, 0xf1f1, 0x0101; 0xfefe, 0x0101, 0xfefe, 0x0101; 0xfee0, 0x1f01, 0xfef1, 0x0e01; 0xe0fe, 0x1f01, 0xf1fe, 0x0e01; 0xfee0, 0x011f, 0xfef1, 0x010e; 0xe0fe, 0x011f, 0xf1fe, 0x010e; 0xe0e0, 0x1f1f, 0xf1f1, 0x0e0e; 0xfefe, 0x1f1f, 0xfefe, 0x0e0e; 0xfe1f, 0xe001, 0xfe0e, 0xf101; 0xe01f, 0xfe01, 0xf10e, 0xfe01; 0xfe01, 0xe01f, 0xfe01, 0xf10e; 0xe001, 0xfe1f, 0xf101, 0xfe0e; 0x01e0, 0xe001, 0x01f1, 0xf101; 0x1ffe, 0xe001, 0x0efe, 0xf001; 0x1fe0, 0xfe01, 0x0ef1, 0xfe01; 0x01fe, 0xfe01, 0x01fe, 0xfe01; 0x1fe0, 0xe01f, 0x0ef1, 0xf10e; 0x01fe, 0xe01f, 0x01fe, 0xf10e; 0x01e0, 0xfe1f, 0x01f1, 0xfe0e; 0x1ffe, 0xfe1f, 0x0efe, 0xfe0e; 0xe001, 0x01e0, 0xf101, 0x01f1; 0xfe1f, 0x01e0, 0xfe0e, 0x01f1; 0xfe01, 0x1fe0, 0xfe01, 0x0ef1; 0xe01f, 0x1fe0, 0xf10e, 0x0ef1; 0xfe01, 0x01fe, 0xfe01, 0x01fe; 0xe01f, 0x01fe, 0xf10e, 0x01fe; 0xe001, 0x1ffe, 0xf101, 0x0efe; 0xfe1f, 0x1ffe, 0xfe0e, 0x0efe; 0x1ffe, 0x01e0, 0x0efe, 0x01f1; 0x01fe, 0x1fe0, 0x01fe, 0x0ef1; 0x1fe0, 0x01fe, 0x0ef1, 0x01fe; 0x01e0, 0x1ffe, 0x01f1, 0x0efe; 0x0101, 0xe0e0, 0x0101, 0xf1f1; 0x1f1f, 0xe0e0, 0x0e0e, 0xf1f1; 0x1f01, 0xfee0, 0x0e01, 0xfef1; 0x011f, 0xfee0, 0x010e, 0xfef1; 0x1f01, 0xe0fe, 0x0e01, 0xf1fe; 0x011f, 0xe0fe, 0x010e, 0xf1fe; 0x0101, 0xfefe, 0x0101, 0xfefe; 0x1f1f, 0xfefe, 0x0e0e, 0xfefe; 0xfefe, 0xe0e0, 0xfefe, 0xf1f1; 0xe0fe, 0xfee0, 0xf1fe, 0xfef1; 0xfee0, 0xe0fe, 0xfef1, 0xf1fe; 0xe0e0, 0xfefe, 0xf1f1, 0xfefe ] in List.mem k.k64 weak_keys end ;; module Cryptmodes = Cryptmodes_64.Make_modes(Cryptsystem) ;; (* ====================================================================== * history: * * $Log: crypt_des.ml,v $ * Revision 1.10 2001/03/10 16:43:21 gerd * int32 experiments * * Revision 1.9 1999/06/18 00:23:58 gerd * First release. * * Revision 1.8 1999/06/17 21:00:31 gerd * Some additions have been turned into lor operations (faster). * The Lazy.force calls in the 'des' functions have been avoided. * * Revision 1.7 1999/06/17 20:39:46 gerd * The initial iperm and xperm permutations have been combined * such that only one table lookup is necessary. * * Revision 1.6 1999/06/17 20:26:35 gerd * In previous revisions, in every 'do_rounds' loop cycle the 'xperm' * permutation was applied again to convert 32 bit numbers to 48 bit numbers. * Now the 'do_rounds' directly works with 48 bit numbers, and 32 bit * entites are converted on entry and on exit. Effectively, we have now * two 'xperm's and two inverse 'xperm's instead of 16 'xperm's before. * * Revision 1.5 1999/06/17 19:41:10 gerd * Logical operations differ in their speed because of Ocaml's * integer representation. lor and land are a bit faster than lxor. * Because of this I reduced the number of lxor operations. * * Revision 1.4 1999/06/17 16:51:33 gerd * The 'xperm' permutation is done by bit-shifting instead of * an array lookup. * * Revision 1.3 1999/06/17 15:57:02 gerd * Invocations of 'do_perm32', 'do_perm48', and 'do_perm64' have * been manually inlined. This speeds the algorithm up from 55 sec per * 1MB CBC-encryption to 38 sec. * * Revision 1.2 1999/06/17 15:24:24 gerd * Instead of calling 'f' sequently, there is now a loop. This * prevents the compiler from inlining the 16 invocations of 'f', which * leads to shorter code and MUCH better cache performance. * * Revision 1.1 1999/06/17 14:55:04 gerd * Added module for DES. * * *) cryptgps/crypt_des.mli100644 764 144 2621 6732206110 13753 0ustar gerdusers(* $Id: crypt_des.mli,v 1.1 1999/06/17 14:55:04 gerd Exp $ * ---------------------------------------------------------------------- * This module is part of the cryptgps package by Gerd Stolpmann. *) (* DES, created by the NSA, is a 64 bit block cipher, * so the following applies: *) module Cryptsystem : Cryptsystem_64.T;; module Cryptmodes : Cryptmodes_64.T with type key = Cryptsystem.key;; (* Key management functions: * * Although only 56 bits count a DES key is written with 64 bits. The * extra bits are used for parity checking. *) val check_parity : string -> unit (* Checks that the parity of the key given as string is ok. The string * must have a length of 8 characters. *) val set_parity : string -> string (* Sets the parity bits in the given key and returns a new string. *) (* - DES has been heavily studied and seems to have a rather good design * - DES has only 56 bit keys (this means DES should be considered a * weak algorithm today, but the variant 3DES is still secure) * - DES has been designed to be implemented in hardware, and software * implementations are relatively slow * - DES is an ANSI and (indirectly) an ISO standard. * - There are very few weak keys. *) (* ====================================================================== * History: * * $Log: crypt_des.mli,v $ * Revision 1.1 1999/06/17 14:55:04 gerd * Added module for DES. * *) cryptgps/crypt_3des.ml100664 764 144 11153 7252454651 13724 0ustar gerdusers(* $Id: crypt_3des.ml,v 1.2 2001/03/10 16:43:21 gerd Exp $ * ---------------------------------------------------------------------- * This module is part of the cryptgps package by Gerd Stolpmann. *) open Crypt_aux let check_parity key = match String.length key with 8 -> Crypt_des.check_parity key | 16 -> Crypt_des.check_parity (String.sub key 0 8); Crypt_des.check_parity (String.sub key 8 8) | 24 -> Crypt_des.check_parity (String.sub key 0 8); Crypt_des.check_parity (String.sub key 8 8); Crypt_des.check_parity (String.sub key 16 8) | _ -> failwith "Crypt_3des: invalid key length" ;; let set_parity key = match String.length key with 8 -> Crypt_des.set_parity key | 16 -> Crypt_des.set_parity (String.sub key 0 8) ^ Crypt_des.set_parity (String.sub key 8 8) | 24 -> Crypt_des.set_parity (String.sub key 0 8) ^ Crypt_des.set_parity (String.sub key 8 8) ^ Crypt_des.set_parity (String.sub key 16 8) | _ -> failwith "Crypt_3des: invalid key length" ;; module Cryptsystem : Cryptsystem_64.T = struct type key = { k1 : Crypt_des.Cryptsystem.key; k2 : Crypt_des.Cryptsystem.key; k3 : Crypt_des.Cryptsystem.key; n_keys : int } let encrypt_ecb k x = match k.n_keys with 1 -> Crypt_des.Cryptsystem.encrypt_ecb k.k1 x | 2 -> let x' = Crypt_des.Cryptsystem.encrypt_ecb k.k1 x in let x'' = Crypt_des.Cryptsystem.decrypt_ecb k.k2 x' in Crypt_des.Cryptsystem.encrypt_ecb k.k1 x'' | 3 -> let x' = Crypt_des.Cryptsystem.encrypt_ecb k.k1 x in let x'' = Crypt_des.Cryptsystem.decrypt_ecb k.k2 x' in Crypt_des.Cryptsystem.encrypt_ecb k.k3 x'' | _ -> failwith "Crypt_3des: invalid key length" let encrypt_ecb_int32 k xl xr ret_xl ret_xr = let x = quadruple_of_int32 xl xr in let y = encrypt_ecb k x in int32_of_quadruple y ret_xl ret_xr let decrypt_ecb k x = match k.n_keys with 1 -> Crypt_des.Cryptsystem.decrypt_ecb k.k1 x | 2 -> let x' = Crypt_des.Cryptsystem.decrypt_ecb k.k1 x in let x'' = Crypt_des.Cryptsystem.encrypt_ecb k.k2 x' in Crypt_des.Cryptsystem.decrypt_ecb k.k1 x'' | 3 -> let x' = Crypt_des.Cryptsystem.decrypt_ecb k.k1 x in let x'' = Crypt_des.Cryptsystem.encrypt_ecb k.k2 x' in Crypt_des.Cryptsystem.decrypt_ecb k.k3 x'' | _ -> failwith "Crypt_3des: invalid key length" let decrypt_ecb_int32 k xl xr ret_xl ret_xr = let x = quadruple_of_int32 xl xr in let y = decrypt_ecb k x in int32_of_quadruple y ret_xl ret_xr let prepare key = let l_key = String.length key in match l_key with 8 -> let k = Crypt_des.Cryptsystem.prepare key in { k1=k; k2=k; k3=k; n_keys=1 } | 16 -> let k1 = Crypt_des.Cryptsystem.prepare (String.sub key 0 8) in let k2 = Crypt_des.Cryptsystem.prepare (String.sub key 8 8) in { k1=k1; k2=k2; k3=k1; n_keys=2 } | 24 -> let k1 = Crypt_des.Cryptsystem.prepare (String.sub key 0 8) in let k2 = Crypt_des.Cryptsystem.prepare (String.sub key 8 8) in let k3 = Crypt_des.Cryptsystem.prepare (String.sub key 16 8) in { k1=k1; k2=k2; k3=k3; n_keys=3 } | _ -> failwith "Crypt_3des: invalid key length" let textkey k = match k.n_keys with 1 -> Crypt_des.Cryptsystem.textkey k.k1 | 2 -> Crypt_des.Cryptsystem.textkey k.k1 ^ Crypt_des.Cryptsystem.textkey k.k2 | 3 -> Crypt_des.Cryptsystem.textkey k.k1 ^ Crypt_des.Cryptsystem.textkey k.k2 ^ Crypt_des.Cryptsystem.textkey k.k3 | _ -> failwith "Crypt_3des: invalid key length" let is_weak k = match k.n_keys with 1 -> Crypt_des.Cryptsystem.is_weak k.k1 | 2 -> Crypt_des.Cryptsystem.is_weak k.k1 or Crypt_des.Cryptsystem.is_weak k.k2 or Crypt_des.Cryptsystem.textkey k.k1 = Crypt_des.Cryptsystem.textkey k.k2 | 3 -> Crypt_des.Cryptsystem.is_weak k.k1 or Crypt_des.Cryptsystem.is_weak k.k2 or Crypt_des.Cryptsystem.is_weak k.k3 or Crypt_des.Cryptsystem.textkey k.k1 = Crypt_des.Cryptsystem.textkey k.k2 or Crypt_des.Cryptsystem.textkey k.k1 = Crypt_des.Cryptsystem.textkey k.k3 or Crypt_des.Cryptsystem.textkey k.k2 = Crypt_des.Cryptsystem.textkey k.k3 | _ -> failwith "Crypt_3des: invalid key length" end ;; module Cryptmodes = Cryptmodes_64.Make_modes(Cryptsystem) ;; (* ====================================================================== * History: * * $Log: crypt_3des.ml,v $ * Revision 1.2 2001/03/10 16:43:21 gerd * int32 experiments * * Revision 1.1 1999/06/18 00:23:58 gerd * First release. * * *) cryptgps/crypt_3des.mli100644 764 144 3710 6732310636 14047 0ustar gerdusers(* $Id: crypt_3des.mli,v 1.1 1999/06/18 00:23:58 gerd Exp $ * ---------------------------------------------------------------------- * This module is part of the cryptgps package by Gerd Stolpmann. *) (* DES, created by the NSA, is a 64 bit block cipher. Triple-DES is a * variant that applies DES three times to the same input block. More * precisely, first the block is encrypted with key k1, then decrypted * with key k2 and then encrypted again with key k3. * It is best to choose k1,k2,k3 distinct. Sometimes k1=k3. * This implementation accepts strings with 8, 16, or 24 bytes as keys, * taking the first 8 bytes as k1, the second as k2, and the third as k3. * Please note that some bits are used as parity bits, such that the * effective key length is 56, resp. 112, resp. 168 bits. * * Triple-DES is 3 times slower than DES. *) module Cryptsystem : Cryptsystem_64.T;; module Cryptmodes : Cryptmodes_64.T with type key = Cryptsystem.key;; (* Key management functions: * * Although only 56 bits count a DES key is written with 64 bits. The * extra bits are used for parity checking. *) val check_parity : string -> unit (* Checks that the parity of the key given as string is ok. The string * must have a length of 8 or 16 or 24 characters. *) val set_parity : string -> string (* Sets the parity bits in the given key and returns a new string. *) (* - DES has been heavily studied and seems to have a rather good design * - DES has only 56 bit keys (this means DES should be considered a * weak algorithm today, but the variant 3DES is still secure) * - DES has been designed to be implemented in hardware, and software * implementations are relatively slow * - DES is an ANSI and (indirectly) an ISO standard. * - There are very few weak keys. *) (* ====================================================================== * History: * * $Log: crypt_3des.mli,v $ * Revision 1.1 1999/06/18 00:23:58 gerd * First release. * *) cryptgps/README100644 764 144 6410 7252455220 12142 0ustar gerdusers------------------------------------------------- cryptgps: some symmetric cryptographic algorithms ------------------------------------------------- This library implements Blowfish, DES, and Triple-DES. REQUIREMENTS The Makefile in this distribution requires that the 'findlib' package is already installed. 'findlib' is a small tool that simplifies platform- independent installation. You can get 'findlib' from: http://www.ocaml-programming.de, or http://www.npc.de/ocaml/linkdb (Or you can change the Makefile, if you like.) COMPILATION & INSTALLATION Type make all to compile a bytecode archive. make opt compiles a native archive. make install installs the bytecode, and if present, the native archive. The installation directory is determined by the 'findlib' tool. make uninstall removes the installation. USAGE The three modules Crypt_blowfish, Crypt_des, and Crypt_3des have all the following inner structure. The inner module Cryptsystem contains the core cryptographic routines, you normally need only the key preparation part. The inner module Cryptmodes implements "modes" of encryption/decryption. The core algorithms only encrypt/decrypt 64-bit blocks, and a "cryptographic mode" extends this to strings of arbitrary length. let k = Crypt_blowfish.Cryptsystem.prepare "abcdefgh" The function 'prepare' converts the key given as string to an internal format. Key preparation may be a lengthy procedure. let ivec = (0,0,0,0) The initialization vector is a non-secret random number. This means that you can transmit it with the encrypted data. A good choice is the current time (0,0,0,0 is bad...). Some modes require not to use the same ivec more than once for a given key in order to get maximum security. (The ivec is a quadruple of 16 bit numbers, from MSB to LSB.) To decrypt the message you must use the same ivec as on encryption. let ivec', i', s' = Crypt_blowfish.Cryptmodes.encrypt_cfb64 k ivec 0 s Here, "Cipher-feedback mode" with 64 bits is used. s' is the encrypted version of s. ivec' and i' are needed for cascaded invocations of cfb64. Cascading means to encrypt a large string by calling the encryption function with several smaller substrings. For example, if s = s1 ^ s2, you can do: let ivec', i', s1' = Crypt_blowfish.Cryptmodes.encrypt_cfb64 k ivec 0 s1 in let ivec'', i'', s2' = Crypt_blowfish.Cryptmodes.encrypt_cfb64 k ivec' ai' s2 Then is s' = s1' ^ s2'. Cascading is useful with slow I/O devices. SPEED Blowfish is three times faster than DES which is three times faster than Triple-DES. The algorithms have been optimized (my first DES algorithm needed 170 seconds to encrypt 1 MB, the distributed version only 15 seconds - measured on a 486/133). A Comparison with ssleay has shown that my library is approximately 8 to 10 times slower (ocamlopt). As Ocaml does not have 32 bit integers, all 32 bit calculations must be performed using two 16 bit numbers; this effect explains a factor of 2. The integer representation expects a '1' in the LSB of every integer word which makes Ocaml another bit slower. ssleay uses static arrays which are often a bit faster; such a feature is not available in Ocaml. LICENSE See the file "LICENSE". CHANGES 0.2: Experimental support for int32 calculations: Blowfish32 0.1.2: Updated URLs in documentation. cryptgps/crypt_blowfish32.ml100664 764 144 60206 7252454624 15053 0ustar gerdusers(* $Id: crypt_blowfish32.ml,v 1.1 2001/03/10 16:43:00 gerd Exp $ * ---------------------------------------------------------------------- * This module is part of the cryptgps package by Gerd Stolpmann. *) (* This is the int32 version of Blowfish. *) open Crypt_aux module Cryptsystem : Cryptsystem_64.T = struct type key = { data : string; p : int32 array; (* subkeys: 18 elements of 16 bits *) p_rev : int32 array; (* subkeys in reverse order *) s1 : int32 array; s2 : int32 array; s3 : int32 array; s4 : int32 array; (* the four s-boxes: sN, where N=0,1,2,3 denotes the box *) xlxr : (int32, Bigarray.int32_elt, Bigarray.c_layout) Bigarray.Array1.t; } let encrypt_ecb_int32 k xl xr ret_xl ret_xr = let xlxr = k.xlxr in (* let xlxr = Bigarray.Array1.create Bigarray.int32 Bigarray.c_layout 2 in *) Bigarray.Array1.set xlxr 0 xl; Bigarray.Array1.set xlxr 1 xr; (* xlxr.(0): The slot for xl; * xlxr.(1): The slot for xr *) (* Note: We use bigarrays here to store xl and xr because ocamlopt * avoids heap allocations in the for loop in this case. *) for i = 0 to 15 do let xl' = Int32.logxor (Bigarray.Array1.get xlxr 0) k.p.(i) in let xl'_msb = Int32.to_int (Int32.shift_right_logical xl' 16) in let xl'_lsb = Int32.to_int xl' in let a = (xl'_msb lsr 8) land 0xff in let b = xl'_msb land 0xff in let c = (xl'_lsb lsr 8) land 0xff in let d = xl'_lsb land 0xff in let xr' = Int32.logxor (Int32.add (Int32.logxor (Int32.add k.s1.(a) k.s2.(b)) k.s3.(c) ) k.s4.(d) ) (Bigarray.Array1.get xlxr 1) in (* xl := xr'; xr := xl'; *) Bigarray.Array1.set xlxr 0 xr'; Bigarray.Array1.set xlxr 1 xl'; done; let r = Int32.logxor (Bigarray.Array1.get xlxr 1) k.p.(17) in let l = Int32.logxor (Bigarray.Array1.get xlxr 0) k.p.(16) in ret_xl := r; (* sic! *) ret_xr := l (* sic! *) let encrypt_ecb k x = let xl = ref Int32.zero in let xr = ref Int32.zero in int32_of_quadruple x xl xr; encrypt_ecb_int32 k !xl !xr xl xr; quadruple_of_int32 !xl !xr let decrypt_ecb_int32 k xl xr ret_xl ret_xr = let k' = { k with p = k.p_rev } in encrypt_ecb_int32 k' xl xr ret_xl ret_xr let decrypt_ecb k x = let xl = ref Int32.zero in let xr = ref Int32.zero in int32_of_quadruple x xl xr; decrypt_ecb_int32 k !xl !xr xl xr; quadruple_of_int32 !xl !xr let prepare key = let l_key = String.length key in if l_key = 0 or l_key > 56 then failwith "Crypt_blowfish: invalid key length"; let p_lsb = [| 0x6a88; 0x08d3; 0x8a2e; 0x7344; 0x3822; 0x31d0; 0xfa98; 0x6c89; 0x21e6; 0x1377; 0x66cf; 0x0c6c; 0x29b7; 0x50dd; 0xd5b5; 0x0917; 0xd5d9; 0xfb1b |] in let p_msb = [| 0x243f; 0x85a3; 0x1319; 0x0370; 0xa409; 0x299f; 0x082e; 0xec4e; 0x4528; 0x38d0; 0xbe54; 0x34e9; 0xc0ac; 0xc97c; 0x3f84; 0xb547; 0x9216; 0x8979 |] in let s1_lsb = [| 0x0ba6; 0xb5ac; 0x72db; 0xdfb7; 0xafed; 0x7e96; 0x9045; 0x7f99; 0x9947; 0x6cf7; 0xf2e2; 0xfc16; 0x20d8; 0x4e69; 0xfea3; 0x3d7e; 0x748f; 0xb658; 0xcd58; 0x4aee; 0xa41d; 0x59b5; 0xd539; 0x6013; 0xb023; 0x85f0; 0x7918; 0x38ef; 0xdcb0; 0x180e; 0x0e8b; 0x8a3e; 0x77c1; 0x4b27; 0x2fda; 0x5c60; 0x25f3; 0xab94; 0x9862; 0x1440; 0x396a; 0x10b6; 0x5c34; 0xe8ce; 0x86af; 0xe993; 0x1411; 0xbc2a; 0xc55d; 0x31f6; 0x3e16; 0x931e; 0xba33; 0xcf5c; 0x5381; 0x8677; 0x4898; 0xb9af; 0xe81b; 0x2193; 0x09cc; 0xa991; 0xac60; 0x8032; 0x5d5d; 0x75b1; 0x2302; 0x1b88; 0x3e81; 0xacc5; 0x6ff3; 0x4239; 0x4482; 0x2004; 0xf04a; 0x9b5e; 0x6842; 0x6c9a; 0x9c61; 0x88f0; 0xa0d2; 0x2f68; 0xa728; 0x33a3; 0x0b6c; 0x3be4; 0xf050; 0x2a98; 0x651d; 0x0176; 0x593e; 0x0e88; 0x8619; 0x9fb4; 0xa5c3; 0x5ebe; 0x75d8; 0x2073; 0x449f; 0x6aa6; 0xaa62; 0x7706; 0xdf72; 0x023d; 0xd724; 0x1248; 0xead3; 0xc09b; 0x72c9; 0x1b7b; 0x79d8; 0xdef7; 0x501a; 0x4c3b; 0xe0bd; 0x06ba; 0x4fb6; 0x60c4; 0x9ec2; 0x2463; 0x6faf; 0x53b5; 0xb2eb; 0xec6f; 0x511f; 0x952c; 0x4544; 0xbd09; 0xd004; 0x4afd; 0x2807; 0x4bb3; 0xa857; 0x740f; 0x5f39; 0xfbdb; 0xc0bd; 0x320a; 0x00c6; 0x7279; 0x25fe; 0xa3cc; 0xe9f8; 0x22f8; 0x16df; 0x6b15; 0x1ec8; 0x52ab; 0xb5fa; 0x8760; 0x7b48; 0xdf82; 0x57bb; 0x8ca0; 0x562e; 0x69db; 0xa8f6; 0xffc3; 0x32c6; 0x5573; 0x27b0; 0x58c8; 0xa35d; 0x11a0; 0x3d98; 0x83b8; 0xb56c; 0xd35b; 0xe479; 0x4565; 0x49bc; 0x9790; 0xf2da; 0x7e33; 0x1341; 0xc6e8; 0xcada; 0x4c01; 0x9efe; 0x1fb4; 0xda4d; 0x9198; 0x8e71; 0xd5a0; 0xd1d0; 0x25e0; 0x5b2f; 0x94b7; 0xe2fb; 0x2b64; 0xb812; 0xf01c; 0x5ea0; 0xc31c; 0xf191; 0xc1ad; 0x2218; 0x1777; 0x2dfe; 0x1fa1; 0xcc0f; 0x74e8; 0xf3d6; 0xe299; 0x4fe0; 0xe0b7; 0x3b81; 0xa8d9; 0xa266; 0x7705; 0x7314; 0x1477; 0x2065; 0xfa86; 0x42f5; 0x35cf; 0xaf0c; 0x89a0; 0x1bd3; 0x7e49; 0x0e2d; 0xb35e; 0x00bb; 0xe0af; 0x369b; 0xb91e; 0x911d; 0xa6aa; 0x4389; 0x537f; 0x5ba2; 0xb9c5; 0x0376; 0xcfa9; 0x1968; 0x4a41; 0x2dca; 0xa94a; 0x0052; 0x2915; 0x573f; 0xc6e4; 0xa476; 0x7400; 0x6fb5; 0xe91f; 0xec6b; 0xd915; 0x6521; 0xf9b6; 0x052e; 0x5664; 0x2d5d; 0x8fa1; 0x4799; 0x076a; |] in let s1_msb = [| 0xd131; 0x98df; 0x2ffd; 0xd01a; 0xb8e1; 0x6a26; 0xba7c; 0xf12c; 0x24a1; 0xb391; 0x0801; 0x858e; 0x6369; 0x7157; 0xa458; 0xf493; 0x0d95; 0x728e; 0x718b; 0x8215; 0x7b54; 0xc25a; 0x9c30; 0x2af2; 0xc5d1; 0x2860; 0xca41; 0xb8db; 0x8e79; 0x603a; 0x6c9e; 0xb01e; 0xd715; 0xbd31; 0x78af; 0x5560; 0xe655; 0xaa55; 0x5748; 0x63e8; 0x55ca; 0x2aab; 0xb4cc; 0x1141; 0xa154; 0x7c72; 0xb3ee; 0x636f; 0x2ba9; 0x7418; 0xce5c; 0x9b87; 0xafd6; 0x6c24; 0x7a32; 0x2895; 0x3b8f; 0x6b4b; 0xc4bf; 0x6628; 0x61d8; 0xfb21; 0x487c; 0x5dec; 0xef84; 0xe985; 0xdc26; 0xeb65; 0x2389; 0xd396; 0x0f6d; 0x83f4; 0x2e0b; 0xa484; 0x69c8; 0x9e1f; 0x21c6; 0xf6e9; 0x670c; 0xabd3; 0x6a51; 0xd854; 0x960f; 0xab51; 0x6eef; 0x137a; 0xba3b; 0x7efb; 0xa1f1; 0x39af; 0x66ca; 0x8243; 0x8cee; 0x456f; 0x7d84; 0x3b8b; 0xe06f; 0x85c1; 0x401a; 0x56c1; 0x4ed3; 0x363f; 0x1bfe; 0x429b; 0x37d0; 0xd00a; 0xdb0f; 0x49f1; 0x0753; 0x8099; 0x25d4; 0xf6e8; 0xe3fe; 0xb679; 0x976c; 0x04c0; 0xc1a9; 0x409f; 0x5e5c; 0x196a; 0x68fb; 0x3e6c; 0x1339; 0x3b52; 0x6dfc; 0x9b30; 0xcc81; 0xaf5e; 0xbee3; 0xde33; 0x660f; 0x192e; 0xc0cb; 0x45c8; 0xd20b; 0xb9d3; 0x5579; 0x1a60; 0xd6a1; 0x402c; 0x679f; 0xfb1f; 0x8ea5; 0xdb32; 0x3c75; 0xfd61; 0x2f50; 0xad05; 0x323d; 0xfd23; 0x5331; 0x3e00; 0x9e5c; 0xca6f; 0x1a87; 0xdf17; 0xd542; 0x287e; 0xac67; 0x8c4f; 0x695b; 0xbbca; 0xe1ff; 0xb8f0; 0x10fa; 0xfd21; 0x4afc; 0x2dd1; 0x9a53; 0xb6f8; 0xd28e; 0x4bfb; 0xe1dd; 0xa4cb; 0x62fb; 0xcee4; 0xef20; 0x3677; 0xd07e; 0x2bf1; 0x95db; 0xae90; 0xeaad; 0x6b93; 0xd08e; 0xafc7; 0x8e3c; 0x8e75; 0x8ff6; 0xf212; 0x8888; 0x900d; 0x4fad; 0x688f; 0xd1cf; 0xb3a8; 0x2f2f; 0xbe0e; 0xea75; 0x8b02; 0xe5a0; 0xb56f; 0x18ac; 0xce89; 0xb4a8; 0xfd13; 0x7cc4; 0xd2ad; 0x165f; 0x8095; 0x93cc; 0x211a; 0xe6ad; 0x77b5; 0xc754; 0xfb9d; 0xebcd; 0x7b3e; 0xd641; 0xae1e; 0x0025; 0x2071; 0x2268; 0x57b8; 0x2464; 0xf009; 0x5563; 0x59df; 0x78c1; 0xd95a; 0x207d; 0x02e5; 0x8326; 0x6295; 0x11c8; 0x4e73; 0xb347; 0x7b14; 0x1b51; 0x9a53; 0xd60f; 0xbc9b; 0x2b60; 0x81e6; 0x08ba; 0x571b; 0xf296; 0x2a0d; 0xb663; 0xe7b9; 0xff34; 0xc585; 0x53b0; 0xa99f; 0x08ba; 0x6e85; |] in let s2_lsb = [| 0x70e9; 0x2944; 0x092e; 0x2623; 0xa6b0; 0xdf7d; 0x60b8; 0xb266; 0x8c71; 0x17ff; 0x526c; 0x9ee1; 0x02a5; 0x4c29; 0x1340; 0x3a3e; 0x989a; 0x9d65; 0xe4d6; 0x3fd6; 0x9c07; 0x30f5; 0x38e6; 0x5dc1; 0x2086; 0xeb26; 0xe9c6; 0xcc5e; 0x6b3f; 0xefc9; 0x1814; 0x70a1; 0x3584; 0xe286; 0x5305; 0x0737; 0x841c; 0xae5c; 0x44ec; 0xf2b8; 0xda37; 0x0c0d; 0x1f04; 0xb3ff; 0xf51a; 0x74b2; 0x7a58; 0x21bd; 0x13f9; 0x2ff6; 0x4773; 0x4701; 0xe581; 0xdadc; 0x7634; 0xdda7; 0x6146; 0x030e; 0xc73e; 0x1e41; 0xcd99; 0x0e2f; 0xbba1; 0xb331; 0x8b38; 0xb908; 0x0d03; 0x04bf; 0x1290; 0x7c79; 0xb072; 0x89af; 0x771f; 0x0810; 0xae12; 0x3f2e; 0x721f; 0x7124; 0xdde6; 0xcd87; 0x4718; 0xda17; 0x9abc; 0x7d8c; 0xec3a; 0x1dfa; 0x4366; 0xc3d2; 0x1847; 0xd908; 0x3b37; 0xba16; 0x4d43; 0xc451; 0x0002; 0xe4dd; 0xf89e; 0x4e55; 0x77d6; 0x199b; 0x56f1; 0xc76b; 0x183b; 0xa509; 0xe6ed; 0xfbfa; 0xbf2c; 0x3c6e; 0x4570; 0x6fb1; 0x5e0a; 0x2ab3; 0xe71c; 0x06fa; 0xdcb9; 0x1d0f; 0x89d6; 0xc825; 0xc978; 0xb36a; 0x0eba; 0xea78; 0x3c53; 0x2df4; 0x4ea7; 0x2b3d; 0x260f; 0x7960; 0xa708; 0x12b6; 0xfe6e; 0x1f66; 0x4595; 0xc883; 0x37d1; 0xff28; 0xddef; 0x5aa5; 0x2185; 0x9802; 0xa50f; 0x953b; 0x7dad; 0x2f84; 0xb628; 0x6170; 0x4775; 0x1510; 0xa830; 0xbd96; 0xfe1e; 0x63cf; 0x5c90; 0xa239; 0x9e0b; 0xde14; 0x86bc; 0x2ca7; 0x5cab; 0x846e; 0x1eaf; 0xf0ca; 0x69b9; 0xbb50; 0x5a32; 0xb4b3; 0xe9d5; 0xb8f7; 0x0b19; 0xa099; 0x997e; 0x7da8; 0x889a; 0x2d77; 0x935f; 0x1281; 0x8829; 0x1fd6; 0xdfa1; 0xba99; 0x84a5; 0x7263; 0xc3ff; 0x4696; 0x0aeb; 0x3054; 0x48e4; 0x3128; 0xf2ef; 0xffea; 0xed61; 0x3c73; 0x14d9; 0xb7e3; 0x5d14; 0x13e0; 0xe2b6; 0xabea; 0x4f15; 0x4fd0; 0xf442; 0xbbb5; 0x3b1d; 0x2105; 0x799e; 0x4dc7; 0x476a; 0x6250; 0xa1f2; 0x2646; 0x83a0; 0xb6a3; 0x24c3; 0x7492; 0x8a0b; 0xb285; 0xbf00; 0x489d; 0xb174; 0x0e00; 0x8d2a; 0xf5ea; 0xf43e; 0x7061; 0xf092; 0x7e41; 0xecf1; 0x3bdb; 0x3759; 0x7460; 0xf2a7; 0x326e; 0x8084; 0x509e; 0xd855; 0x9735; 0xa7aa; 0x06c2; 0xabfc; 0xcadc; 0x7a2e; 0x3484; 0x6705; 0x9ec9; 0xdbd3; 0x88cd; 0xda79; 0x4340; 0x3465; 0x38d8; 0xf89e; 0xff20; 0x21e7; 0x3d4a; 0x9f2b; 0xadf7; |] in let s2_msb = [| 0x4b7a; 0xb5b3; 0xdb75; 0xc419; 0xad6e; 0x49a7; 0x9cee; 0x8fed; 0xecaa; 0x699a; 0x5664; 0xc2b1; 0x1936; 0x7509; 0xa059; 0xe418; 0x3f54; 0x5b42; 0x6b8f; 0x99f7; 0xa1d2; 0xefe8; 0x4d2d; 0xf025; 0x4cdd; 0x8470; 0x6382; 0x021e; 0x0968; 0x3eba; 0x3c97; 0x6b6a; 0x687f; 0x52a0; 0xb79c; 0xaa50; 0x3e07; 0x7fde; 0x8e7d; 0x5716; 0xb03a; 0xf050; 0xf01c; 0x0200; 0xae0c; 0x3cb5; 0x2583; 0xdc09; 0xd191; 0x7ca9; 0x9432; 0x22f5; 0x3ae5; 0x37c2; 0xc8b5; 0x9af3; 0xa944; 0x0fd0; 0xecc8; 0xa475; 0xe238; 0x3bea; 0x3280; 0x183e; 0x4e54; 0x4f6d; 0x6f42; 0xf60a; 0x2cb8; 0x2497; 0x5679; 0xbcaf; 0xde9a; 0xd993; 0xb38b; 0xdccf; 0x5512; 0x2e6b; 0x501a; 0x9f84; 0x7a58; 0x7408; 0xbc9f; 0xe94b; 0xec7a; 0xdb85; 0x6309; 0xc464; 0xef1c; 0x3215; 0xdd43; 0x24c2; 0x12a1; 0x2a65; 0x5094; 0x133a; 0x71df; 0x1031; 0x81ac; 0x5f11; 0x0435; 0xd7a3; 0x3c11; 0x5924; 0xf28f; 0x97f1; 0x9eba; 0x1e15; 0x86e3; 0xeae9; 0x860e; 0x5a3e; 0x771f; 0x4e3d; 0x2965; 0x99e7; 0x803e; 0x5266; 0x2e4c; 0x9c10; 0xc615; 0x94e2; 0xa5fc; 0x1e0a; 0xf2f7; 0x361d; 0x1939; 0x19c2; 0x5223; 0xf713; 0xebad; 0xeac3; 0xe3bc; 0xa67b; 0xb17f; 0x018c; 0xc332; 0xbe6c; 0x6558; 0x68ab; 0xeece; 0xdb2f; 0x2aef; 0x5b6e; 0x1521; 0x2907; 0xecdd; 0x619f; 0x13cc; 0xeb61; 0x0334; 0xaa03; 0xb573; 0x4c70; 0xd59e; 0xcbaa; 0xeecc; 0x6062; 0x9cab; 0xb2f3; 0x648b; 0x19bd; 0xa023; 0x655a; 0x4068; 0x3c2a; 0x319e; 0xc021; 0x9b54; 0x875f; 0x95f7; 0x623d; 0xf837; 0x97e3; 0x11ed; 0x1668; 0x0e35; 0xc7e6; 0x96de; 0x7858; 0x57f5; 0x1b22; 0x9b83; 0x1ac2; 0xcdb3; 0x532e; 0x8fd9; 0x6dbc; 0x58eb; 0x34c6; 0xfe28; 0xee7c; 0x5d4a; 0xe864; 0x4210; 0x203e; 0x45ee; 0xa3aa; 0xdb6c; 0xfacb; 0xc742; 0xef6a; 0x654f; 0x41cd; 0xd81e; 0x8685; 0xe44b; 0x3d81; 0xcf62; 0x5b8d; 0xfc88; 0xc1c7; 0x7f15; 0x69cb; 0x4784; 0x5692; 0x095b; 0xad19; 0x1462; 0x2382; 0x5842; 0x0c55; 0x1dad; 0x233f; 0x3372; 0x8d93; 0xd65f; 0x6c22; 0x7cde; 0xcbee; 0x4085; 0xce77; 0xa607; 0x19f8; 0xe8ef; 0x61d9; 0xa969; 0xc50c; 0x5a04; 0x800b; 0x9e44; 0xc345; 0xfdd5; 0x0e1e; 0xdb73; 0x1055; 0x675f; 0xe367; 0xc5c4; 0x713e; 0x3d28; 0xf16d; 0x153e; 0x8fb0; 0xe6e3; 0xdb83; |] in let s3_lsb = [| 0x5a68; 0x40f7; 0x261c; 0x2934; 0x20f7; 0xd4f7; 0x6b2e; 0x0068; 0x2471; 0xf46a; 0xd4b7; 0x61af; 0xf62e; 0x4546; 0x4f74; 0x8840; 0xfc1d; 0x91af; 0xddd3; 0x2f45; 0x09ec; 0x9785; 0x6dd0; 0x8504; 0x27b3; 0x3941; 0x47e6; 0x0a9a; 0x7825; 0x29f4; 0x86da; 0x6dfb; 0x1462; 0x6900; 0xc0a4; 0x8dee; 0xfea2; 0xad8c; 0xe006; 0xd6b6; 0x1e7c; 0x5fec; 0xa399; 0x2a42; 0x9e35; 0x85b9; 0xd7ab; 0x4e8b; 0xfaf7; 0x1856; 0x6631; 0x97b2; 0xfa74; 0x4332; 0xe7f7; 0x20fb; 0xf54e; 0xb397; 0x56ac; 0x9527; 0x3a3a; 0x8d87; 0xa9b7; 0x954b; 0x67bc; 0x9a58; 0x2963; 0xdb33; 0x4a56; 0x25f9; 0x7e1c; 0x317c; 0xe802; 0x2f70; 0x155c; 0x2ce3; 0x1548; 0x6d22; 0x133f; 0x86dc; 0xc9ee; 0x1f0f; 0x79a4; 0x6e17; 0x51eb; 0xc0d1; 0xc18f; 0x3564; 0x7834; 0x9c60; 0xe8a3; 0x6c1b; 0xb4c2; 0x329e; 0x4fd1; 0x8115; 0x95e0; 0x92e1; 0x0b62; 0xb922; 0xa20e; 0x0d99; 0x0c8c; 0xf728; 0x7845; 0x94fd; 0x0862; 0xf5f0; 0xa36f; 0x48fa; 0xfd27; 0x8d1e; 0x6341; 0xff74; 0x6eab; 0xfd37; 0xdc60; 0xddf8; 0xe14c; 0x6b0d; 0x5510; 0x2c37; 0xd43b; 0xe804; 0x0dc7; 0xffa3; 0x0f92; 0xed0b; 0x9ffb; 0x7d9c; 0xcf0b; 0x5ea3; 0x2f88; 0xad24; 0x79bf; 0xd6eb; 0x2eb3; 0x5979; 0xe297; 0x312d; 0xada7; 0x2b3b; 0x4ccc; 0xf11c; 0x4237; 0x51e7; 0xbbe6; 0x6350; 0x1018; 0xedfa; 0xbdd8; 0xc3c9; 0x1659; 0x1386; 0xec6e; 0xea2a; 0x674e; 0xa85f; 0xe988; 0xc3fe; 0x8057; 0xc086; 0x7bf8; 0x604d; 0x8346; 0x1fb0; 0xae04; 0xfccc; 0x6b33; 0xab71; 0x4187; 0x5e5f; 0x57be; 0xae24; 0x4299; 0x2e61; 0xf48f; 0xfda2; 0xef38; 0xbdc2; 0xf9c3; 0x8e74; 0xf255; 0xd9b9; 0x2661; 0xdf84; 0x0e79; 0x95e2; 0x598e; 0x5770; 0x5591; 0xde4c; 0xace1; 0x05d0; 0x6248; 0xa99e; 0x19b6; 0xdc09; 0x09a1; 0x4633; 0x1f02; 0xbe8c; 0xa025; 0xfe10; 0x3d1d; 0xa4df; 0xf20f; 0xf169; 0xda83; 0x06fe; 0xce9b; 0x7f52; 0x5e01; 0x83fa; 0xb5c4; 0xd027; 0x8c27; 0x8641; 0x4c06; 0x06b5; 0x7a28; 0x86e0; 0x58aa; 0x7d62; 0x9ed7; 0xea63; 0xdd94; 0x1634; 0xee56; 0xb6de; 0x7da1; 0x1d76; 0xe409; 0x0188; 0x0a3d; 0x7c24; 0x725f; 0x9db9; 0x5bb4; 0xb8fc; 0x5578; 0xa5b5; 0x7cd3; 0x0fc4; 0xef5e; 0xe6f8; 0x14d9; 0x133c; 0xc7e7; 0x4ec4; 0xbfce; 0xc837; 0x3234; 0x8212; 0xfa8e; 0x00e0; |] in let s3_msb = [| 0xe93d; 0x9481; 0xf64c; 0x9469; 0x4115; 0x7602; 0xbcf4; 0xd4a2; 0xd408; 0x3320; 0x43b7; 0x5000; 0x1e39; 0x9724; 0x1421; 0xbf8b; 0x4d95; 0x96b5; 0x70f4; 0x66a0; 0xbfbc; 0x03bd; 0x7fac; 0x31cb; 0x96eb; 0x55fd; 0xda25; 0xabca; 0x2850; 0x5304; 0x0a2c; 0xe9b6; 0x68dc; 0xd748; 0x680e; 0x27a1; 0x4f3f; 0xe887; 0xb58c; 0x7af4; 0xaace; 0xd337; 0xce78; 0x406b; 0x20fe; 0xd9f3; 0xee39; 0x3b12; 0x1dc9; 0x4b6d; 0x26a3; 0xeae3; 0x3a6e; 0xdd5b; 0x6841; 0xca78; 0xfb0a; 0xd8fe; 0x4540; 0xba48; 0x5553; 0x2083; 0xfe6b; 0xd096; 0x55a8; 0xa115; 0xcca9; 0x99e1; 0xa62a; 0x3f31; 0x5ef4; 0x9029; 0xfdf8; 0x0427; 0x80bb; 0x0528; 0x95c1; 0xe4c6; 0x48c1; 0xc70f; 0x07f9; 0x4104; 0x4047; 0x5d88; 0x325f; 0xd59b; 0xf2bc; 0x4111; 0x257b; 0x602a; 0xdff8; 0x1f63; 0x0e12; 0x02e1; 0xaf66; 0xcad1; 0x6b23; 0x333e; 0x3b24; 0xeebe; 0x85b2; 0xe6ba; 0xde72; 0x2da2; 0xd012; 0x95b7; 0x647d; 0xe7cc; 0x5449; 0x877d; 0xc39d; 0xf33e; 0x0a47; 0x992e; 0x3a6f; 0xf4f8; 0xa812; 0xa1eb; 0x991b; 0xdb6e; 0xc67b; 0x6d67; 0x2765; 0xdcd0; 0xf129; 0xcc00; 0xb539; 0x690f; 0x667b; 0xcedb; 0xa091; 0xd915; 0xbb13; 0x515b; 0x7b94; 0x763b; 0x3739; 0xcc11; 0x8026; 0xf42e; 0x6842; 0xc66a; 0x1275; 0x782e; 0x6a12; 0xb792; 0x06a1; 0x4bfb; 0x1a6b; 0x11ca; 0x3d25; 0xe2e1; 0x4442; 0x0a12; 0xd90c; 0xd5ab; 0x64af; 0xda86; 0xbebf; 0x64e4; 0x9dbc; 0xf0f7; 0x6078; 0x6003; 0xd1fd; 0xf638; 0x7745; 0xd736; 0x8342; 0xf01e; 0xb080; 0x3c00; 0x77a0; 0xbde8; 0x5546; 0xbf58; 0x4e58; 0xf2dd; 0xf474; 0x8789; 0x5366; 0xc8b3; 0xb475; 0x46fc; 0x7aeb; 0x8b1d; 0x846a; 0x915f; 0x466e; 0x20b4; 0x8cd5; 0xc902; 0xb90b; 0xbb82; 0x11a8; 0x7574; 0xb77f; 0xe0a9; 0x662d; 0xc432; 0xe85a; 0x09f0; 0x4a99; 0x1d6e; 0x1ab9; 0x0ba5; 0xa186; 0x2868; 0xdcb7; 0x5739; 0xa1e2; 0x4fcd; 0x5011; 0xa706; 0xa002; 0x0de6; 0x9af8; 0x773f; 0xc360; 0x61a8; 0xf017; 0xc0f5; 0x0060; 0x30dc; 0x11e6; 0x2338; 0x53c2; 0xc2c2; 0xbbcb; 0x90bc; 0xebfc; 0xce59; 0x6f05; 0x4b7c; 0x3972; 0x7c92; 0x86e3; 0x724d; 0x1ac1; 0xd39e; 0xed54; 0x08fc; 0xd83d; 0x4dad; 0x1e50; 0xb161; 0xa285; 0x6c51; 0x6fd5; 0x56e1; 0x362a; 0xddc6; 0xd79a; 0x9263; 0x670e; 0x4060; |] in let s4_lsb = [| 0xce37; 0xf5cf; 0x7737; 0x2d1b; 0x679e; 0x3742; 0x2740; 0x9bbe; 0x8e9d; 0x7315; 0x1c7e; 0xc47b; 0x1b6b; 0x9045; 0xb1be; 0x6eb4; 0xab2f; 0x6e79; 0x76d2; 0xc2c8; 0xf8ee; 0xde7d; 0x0a1d; 0x4dc6; 0xbbdb; 0x4650; 0x26e8; 0xe304; 0xd5f0; 0x519a; 0x8ce2; 0xee22; 0xc2b8; 0x2ef6; 0x03aa; 0xd0a4; 0x61ba; 0x6a4d; 0x1550; 0x5bd6; 0xa2f9; 0x3ae1; 0x9586; 0x62e9; 0xefd3; 0xf7da; 0x6f69; 0x0a59; 0xa915; 0x8601; 0xe6ad; 0xe593; 0xfd5a; 0xd797; 0xb7d9; 0x8b51; 0xac3a; 0xa67d; 0x3ed6; 0x2d28; 0x25cf; 0xb89b; 0xb472; 0xf54c; 0xac71; 0xa5e6; 0xacfd; 0xfa9b; 0xc48d; 0x57cc; 0x6629; 0x2e28; 0x0191; 0x6055; 0x0e44; 0x5e8c; 0x6dd4; 0x6dba; 0x6125; 0xf0bd; 0x9e15; 0x57a2; 0x1aec; 0x072a; 0x6d9b; 0x21f5; 0x66fb; 0xf319; 0xd928; 0xfdf5; 0x3482; 0x3cbb; 0x7711; 0xd9f8; 0x5167; 0x925f; 0x1751; 0xdc8e; 0x5862; 0xf991; 0x90c2; 0x7bce; 0xce64; 0xbe32; 0xe37e; 0x3d46; 0x5369; 0xe680; 0x0810; 0xb224; 0x2dfd; 0x2166; 0x460a; 0xc0dd; 0xdecf; 0xc8ae; 0xf7dd; 0x8d40; 0x017f; 0xe3bb; 0x6a7e; 0xff45; 0x0a44; 0xcdd5; 0xcea8; 0x84bb; 0x12ae; 0x6f47; 0xe463; 0x5d9e; 0x771b; 0x6370; 0x0d8d; 0x1357; 0x1671; 0x7d5d; 0xcb08; 0xe2cc; 0x466a; 0xaf84; 0x0428; 0x3a1d; 0x9fb4; 0xa048; 0x3b82; 0xab82; 0x1d4b; 0x27f8; 0x60b1; 0x3fdc; 0x792b; 0x25bd; 0x39e1; 0x794b; 0xc9b7; 0xbac9; 0xc87e; 0xd1f6; 0x11c3; 0xaac7; 0x8749; 0xbd9a; 0xdecb; 0xda38; 0xc32a; 0x3667; 0x317c; 0x2b4f; 0x59b7; 0xbb3a; 0x19ff; 0x459c; 0x222c; 0xfc2a; 0xfc71; 0x1525; 0x9361; 0x9ceb; 0x6459; 0xa8d1; 0x075e; 0x6a0c; 0x5065; 0xa442; 0x6e0e; 0xdb3b; 0xa0be; 0xe964; 0x9532; 0x92df; 0x342b; 0xf21e; 0x7441; 0x348c; 0x7120; 0x32d8; 0x9f8d; 0x2f2e; 0x6f47; 0xf11d; 0xda54; 0xd891; 0x79cf; 0x7e6f; 0xb166; 0x1d05; 0xd2c5; 0x2299; 0xf357; 0x7623; 0x3531; 0xcd02; 0x8162; 0xebb5; 0x3697; 0x73cc; 0x6292; 0x49d0; 0x901b; 0x5614; 0xc7bd; 0x140a; 0xd006; 0x7b9a; 0x53fd; 0x0f00; 0xbfe2; 0xd2f6; 0x6905; 0x0222; 0xcf7c; 0x9c2b; 0x3ec0; 0xe3d3; 0xbd60; 0xadf0; 0x209c; 0xce76; 0xa1c5; 0x6060; 0xfe4e; 0x8dd8; 0xf9b0; 0xaa7e; 0xc25c; 0x8a8c; 0x6ae4; 0xe1f9; 0xf869; 0xdea0; 0x252d; 0xe69f; 0x6132; 0xe25b; 0xdfe3; 0x72e6; |] in let s4_msb = [| 0x3a39; 0xd3fa; 0xabc2; 0x5ac5; 0x5cb0; 0x4fa3; 0xd382; 0x99bc; 0xd511; 0xbf0f; 0xd62d; 0xc700; 0xb78c; 0x21a1; 0xb26e; 0x6a36; 0x5748; 0xbc94; 0xc6a3; 0x6549; 0x530f; 0x468d; 0xd573; 0x4cd0; 0x2939; 0xa9ba; 0xac95; 0xbe5e; 0xa1fa; 0x6a2d; 0x63ef; 0x9a86; 0xc089; 0x4324; 0xa51e; 0x9cf2; 0x83c0; 0x9be9; 0x8fe5; 0xba64; 0x2826; 0xa73a; 0x4ba9; 0xef55; 0xc72f; 0xf752; 0x3f04; 0x77fa; 0x80e4; 0x87b0; 0x9b09; 0x3b3e; 0xe990; 0x9e34; 0x2cf0; 0x022b; 0x96d5; 0x017d; 0xd1cf; 0x7c7d; 0x1f9f; 0xadf2; 0x5ad6; 0x5a88; 0xe029; 0xe019; 0x47b0; 0xed93; 0xe8d3; 0x283b; 0xf8d5; 0x7913; 0x785f; 0xed75; 0xf796; 0xe3d3; 0x1505; 0x88f4; 0x03a1; 0x0564; 0xc3eb; 0x3c90; 0x9727; 0xa93a; 0x1b3f; 0x1e63; 0xf59c; 0x26dc; 0x7533; 0xb155; 0x0356; 0x8aba; 0x2851; 0xc20a; 0xabcc; 0xccad; 0x4de8; 0x3830; 0x379d; 0x9320; 0xea7a; 0xfb3e; 0x5121; 0x774f; 0xa8b6; 0xc329; 0x48de; 0x6413; 0xa2ae; 0xdd6d; 0x6985; 0x0907; 0xb39a; 0x6445; 0x586c; 0x1c20; 0x5bbe; 0x1b58; 0xccd2; 0x6bb4; 0xdda2; 0x3a59; 0x3e35; 0xbcb4; 0x72ea; 0xfa64; 0x8d66; 0xbf3c; 0xd29b; 0x542f; 0xaec2; 0xf64e; 0x740e; 0xe75b; 0xf872; 0xaf53; 0x4040; 0x4eb4; 0x34d2; 0x0115; 0xe1b0; 0x9598; 0x06b8; 0xce6e; 0x6f3f; 0x3520; 0x011a; 0x2772; 0x6115; 0xe793; 0xbb3a; 0x3445; 0xa088; 0x51ce; 0x2f32; 0xa01f; 0xe01c; 0xbcc7; 0xcf01; 0xa1e8; 0x1a90; 0xd44f; 0xd0da; 0xd50a; 0x0339; 0xc691; 0x8df9; 0xe0b1; 0xf79e; 0x43f5; 0xf2d5; 0x27d9; 0xbf97; 0x15e6; 0x0f91; 0x9b94; 0xfae5; 0xceb6; 0xc2a8; 0x12ba; 0xb6c1; 0xe305; 0x10d2; 0xcb03; 0xe0ec; 0x1698; 0x4c98; 0x3278; 0x9f1f; 0xe0d3; 0xd3a0; 0x8971; 0x1b0a; 0x4ba3; 0xc5be; 0xc376; 0xdf35; 0x9b99; 0xe60b; 0x0fe3; 0xe54c; 0x1eda; 0xce62; 0xcd3e; 0x1618; 0xfd2c; 0x848f; 0xf6fb; 0xf523; 0xa632; 0x93a8; 0x56cc; 0xacf0; 0x5a75; 0x6e16; 0x88d2; 0xde96; 0x81b9; 0x4c50; 0x71c6; 0xe6c6; 0x327a; 0x45e1; 0xc3f2; 0xc9aa; 0x62a8; 0xbb25; 0x35bd; 0x7112; 0xb204; 0xb6cb; 0xcd76; 0x5311; 0x1640; 0x38ab; 0x2547; 0xba38; 0xf746; 0x77af; 0x2075; 0x85cb; 0x8ae8; 0x7aaa; 0x4cf9; 0x1948; 0x02fb; 0x01c3; 0xd6eb; 0x90d4; 0xa65c; 0x3f09; 0xc208; 0xb74e; 0xce77; 0x578f; 0x3ac3; |] in let j = ref 0 in for i = 0 to 17 do let k0 = Char.code(key.[ !j ]) in let k1 = Char.code(key.[ (!j + 1) mod l_key ]) in let k2 = Char.code(key.[ (!j + 2) mod l_key ]) in let k3 = Char.code(key.[ (!j + 3) mod l_key ]) in j := (!j + 4) mod l_key; let d_msb = ( k0 lsl 8 ) lor k1 in let d_lsb = ( k2 lsl 8 ) lor k3 in p_lsb.( i ) <- p_lsb.( i ) lxor d_lsb; p_msb.( i ) <- p_msb.( i ) lxor d_msb done; let d = ref (0,0,0,0) in let to_int32 lsb msb = Int32.logor (Int32.shift_left (Int32.of_int msb) 16) (Int32.of_int lsb) in let to_int32_array lsb msb = let a = Array.make (Array.length lsb) Int32.zero in for i = 0 to Array.length lsb - 1 do a.(i) <- to_int32 lsb.(i) msb.(i) done; a in let k = { data = key; p = to_int32_array p_lsb p_msb; p_rev = Array.make 18 Int32.zero; s1 = to_int32_array s1_lsb s1_msb; s2 = to_int32_array s2_lsb s2_msb; s3 = to_int32_array s3_lsb s3_msb; s4 = to_int32_array s4_lsb s4_msb; xlxr = Bigarray.Array1.create Bigarray.int32 Bigarray.c_layout 2; } in for i = 0 to 8 do d := encrypt_ecb k !d; let (dl_msb, dl_lsb, dr_msb, dr_lsb) = !d in k.p.( 2*i ) <- to_int32 dl_lsb dl_msb; k.p.( 2*i+1 ) <- to_int32 dr_lsb dr_msb; done; for i = 0 to 127 do d := encrypt_ecb k !d; let (dl_msb, dl_lsb, dr_msb, dr_lsb) = !d in k.s1.( 2*i ) <- to_int32 dl_lsb dl_msb; k.s1.( 2*i+1 ) <- to_int32 dr_lsb dr_msb; done; for i = 0 to 127 do d := encrypt_ecb k !d; let (dl_msb, dl_lsb, dr_msb, dr_lsb) = !d in k.s2.( 2*i ) <- to_int32 dl_lsb dl_msb; k.s2.( 2*i+1 ) <- to_int32 dr_lsb dr_msb; done; for i = 0 to 127 do d := encrypt_ecb k !d; let (dl_msb, dl_lsb, dr_msb, dr_lsb) = !d in k.s3.( 2*i ) <- to_int32 dl_lsb dl_msb; k.s3.( 2*i+1 ) <- to_int32 dr_lsb dr_msb; done; for i = 0 to 127 do d := encrypt_ecb k !d; let (dl_msb, dl_lsb, dr_msb, dr_lsb) = !d in k.s4.( 2*i ) <- to_int32 dl_lsb dl_msb; k.s4.( 2*i+1 ) <- to_int32 dr_lsb dr_msb; done; for i = 0 to 17 do k.p_rev.( i ) <- k.p.( 17-i ); done; k let textkey k = k.data let is_weak k = (* A weak key is one in which two entries for a given S-box are identical *) (* Time: check takes 129540 loops. *) let check s = for i=0 to 254 do let a = s.(i) in for j=i+1 to 255 do if a = s.(j) then raise Not_found done done; () in try check k.s1; check k.s2; check k.s3; check k.s4; false with Not_found -> true end ;; module Cryptmodes = Cryptmodes_64.Make_modes_int32(Cryptsystem) ;; (* ====================================================================== * History: * * $Log: crypt_blowfish32.ml,v $ * Revision 1.1 2001/03/10 16:43:00 gerd * Initial revision. * *) cryptgps/crypt_blowfish32.mli100664 764 144 2057 7252454624 15204 0ustar gerdusers(* $Id: crypt_blowfish32.mli,v 1.1 2001/03/10 16:43:00 gerd Exp $ * ---------------------------------------------------------------------- * This module is part of the cryptgps package by Gerd Stolpmann. *) (* "Blowfish", created by Bruce Schneier, is a 64 bit block cipher, * so the following applies: *) module Cryptsystem : Cryptsystem_64.T;; module Cryptmodes : Cryptmodes_64.T with type key = Cryptsystem.key;; (* - Blowfish is one of the fastest ciphers. * - Blowfish supports keys from 8 bits to 448 bits. With longer keys * the algorithm does not slow down. * - There are weak keys. It is possible to recover some initialization * data for weak keys, but no way to exploit this knowlege has been * reported. * - Blowfish is public domain, i.e. free from patents. *) (* THIS VERSION OF BLOWFISH USES INT32 ARITHMETIC, AND IS EXPERIMENTAL. *) (* ====================================================================== * History: * * $Log: crypt_blowfish32.mli,v $ * Revision 1.1 2001/03/10 16:43:00 gerd * Initial revision. * *) cryptgps/crypt_aux.mli100664 764 144 551 7252441400 13760 0ustar gerdusers(* $Id$ * ---------------------------------------------------------------------- * *) val quadruple_of_int32 : int32 -> int32 -> (int * int * int * int) val int32_of_quadruple : (int * int * int * int) -> int32 ref -> int32 ref -> unit (* ====================================================================== * History: * * $Log$ * *) cryptgps/crypt_aux.ml100664 764 144 1457 7252442135 13643 0ustar gerdusers(* $Id$ * ---------------------------------------------------------------------- * *) let quadruple_of_int32 xl xr = let xl_msb = Int32.to_int(Int32.shift_right_logical xl 16) in let xl_lsb = (Int32.to_int xl) land 0xffff in let xr_msb = Int32.to_int(Int32.shift_right_logical xr 16) in let xr_lsb = (Int32.to_int xr) land 0xffff in (xl_msb,xl_lsb,xr_msb,xr_lsb) ;; let int32_of_quadruple (xl_msb,xl_lsb,xr_msb,xr_lsb) ret_xl ret_xr = let xl = Int32.logor (Int32.of_int xl_lsb) (Int32.shift_left (Int32.of_int xl_msb) 16) in let xr = Int32.logor (Int32.of_int xr_lsb) (Int32.shift_left (Int32.of_int xr_msb) 16) in ret_xl := xl; ret_xr := xr ;; (* ====================================================================== * History: * * $Log$ * *)