[Nym3-commit] r12 - trunk/crypto

nym3-devel@lists.noreply.org nym3-devel@lists.noreply.org
Sun, 02 May 2004 22:16:26 +0200


Author: weasel
Date: 2004-05-02 22:16:25 +0200 (Sun, 02 May 2004)
New Revision: 12

Added:
   trunk/crypto/test_weasel.ml
Modified:
   trunk/crypto/crypto.ml
Log:
add crypto tests and change crypto.ml a bit.
PRNG/counter is broken

Modified: trunk/crypto/crypto.ml
===================================================================
--- trunk/crypto/crypto.ml	2004-05-02 18:04:23 UTC (rev 11)
+++ trunk/crypto/crypto.ml	2004-05-02 20:16:25 UTC (rev 12)
@@ -2,7 +2,7 @@
  * 
  * Copyright (C) 2004 Erik Arneson
  *
- * $Id: crypto.ml,v 1.2 2004/04/27 04:47:20 erik Exp $ *)
+ * $Id$ *)
 
 open Cryptokit
 open Cipher
@@ -57,6 +57,14 @@
   in
     aux 0 (pred xlen)
 
+
+(**
+ * XOR two strings
+ *
+ * @param a string 1
+ * @param b string 2
+ * @return a strring of equal length where x[i] = a[i] XOR b[i] for all i
+ *)
 (* Use hidden side effects -- results in much cleaner notation. *)
 let xor_string s1 s2 =
   assert ((String.length s1) = (String.length s2));
@@ -72,9 +80,57 @@
   in
     aux 0
 
-let random_bytes len = 
+(**
+ * Get <code>len</code> random octets from a secure pseudo random number generator.
+ *
+ * @param len number of octets
+ * @return a string of n octets of your finest randomness
+ *)
+let random_bytes len =
   Random.string (Random.device_rng "/dev/urandom") len
 
+
+(**
+ * Hash the message provided in <code>m</code>.
+ *
+ * @param m a message
+ * @return the SHA-1 hash of <code>m</code>
+ *)
+let hash m =
+  hash_string (Hash.sha1()) m
+
+(**
+ * Return <code>n</code> "random" octets generated based on key <code>k</code>.
+ *
+ * Generates <code>n</code> "random" octets or a key stream based on
+ * <code>k</code>. The stream is generated by using AES in counter mode
+ * with key <code>k</code>.
+ * 
+ * @param k the key for AES counter mode
+ * @param n number of octets requested
+ * @return a keystream of n octets
+ *)
+let prng n k =
+  assert ((String.length k) = 16);
+  let m = String.make n (char_of_int 0)
+  and enc = aes ~mode:(OFB 1) ~iv:(String.make 16 (char_of_int 0))
+	     k Encrypt in
+  transform_string enc m
+
+(**
+ * Encrypt a message <code>m</code> using AES counter mode with key <code>k</code>.
+ *
+ * @param k the key for AES counter mode
+ * @param m the message to encrypt
+ * @return the encrypted message. (len(e) == len(m))
+ *)
+let encrypt k m =
+ assert ((String.length k) = 16);
+ let enc = aes ~mode:(OFB 1) ~iv:(String.make 16 (char_of_int 0))
+	     k Encrypt in
+   transform_string enc m
+
+
 (* Most of this module is stolen or otherwise adapted from Cryptokit's
    Bn module, which doesn't provide a public interface.  hex_to_nat is
    used by the OAEP tests to read in the large numbers from RSA's test
@@ -127,63 +183,58 @@
 
 end
 
-module Lioness = struct
 
-  type t = {
-    efunc: (string -> string -> string);
-    hfunc: (string -> string)
-  }
+let _k1_mask = k_mask 1 20
+let _k2_mask = k_mask 2 20
+let _k3_mask = k_mask 3 20
+let _epart km k msg =
+  encrypt (String.sub (hash (km ^ k ^ km)) 0 16) msg
+let _hpart km k msg =
+  xor_string msg (hash (km ^ k ^ km))
+(**
+ * Encrypt a message using our super pseudorandom permutation.
+ *
+ * Encrypt message <code>m</code> using an instance of the LIONESS
+ * super pseudorandom permutation (SPRP).
+ *
+ * This SPRP has the property that any change in the encrypted value
+ * will make the decryption look like random bits
+ *
+ * @param k the key for our SPRP function
+ * @param m the message to encrypt
+ * @return the encrypted message. (len(e) == len(m))
+ *)
+let sprpEncrypt k m =
+  assert ((String.length k) = 20);
+  let lm = String.sub m 0 20
+  and rm = String.sub m 20 ((String.length m) - 20) in
+  let r1 = _epart k lm rm in
+  let l1 = _hpart (xor_string k _k1_mask) r1 lm in
+  let r2 = _epart (xor_string k _k2_mask) l1 r1 in
+  let l2 = _hpart (xor_string k _k3_mask) r2 l1 in
+    l2 ^ r2
 
-  let create ef hf =
-    { efunc = ef;
-      hfunc = hf }
+(**
+ * Decrypt a message using our super pseudorandom permutation.
+ *
+ * Decrypt message <code>m</code> using our instance of the LIONESS
+ * super pseudorandom permutation (SPRP).
+ *
+ * @param k the key for our SPRP function
+ * @param m the message to decrypt
+ * @return the decrypted message. (len(e) == len(m))
+ *)
+let sprpDecrypt k m =
+  assert ((String.length k) = 20);
+  let lm = String.sub m 0 20
+  and rm = String.sub m 20 ((String.length m) - 20) in
+  let l1 = _hpart (xor_string k _k3_mask) rm lm in
+  let r1 = _epart (xor_string k _k2_mask) l1 rm in
+  let l2 = _hpart (xor_string k _k1_mask) r1 l1 in
+  let r2 = _epart k l2 r1 in
+    l2 ^ r2
 
-  let sprp () =
-    { efunc = (fun k m ->
-		 let enc = aes ~mode:(OFB 1) ~iv:(String.make 16 (char_of_int 0))
-			     k Encrypt in
-		   transform_string enc m);
-      hfunc = (hash_string (Hash.sha1()))
-    }
 
-  let k1_mask = k_mask 1 20
-  let k2_mask = k_mask 2 20
-  let k3_mask = k_mask 3 20
-
-  let encrypt_part ef hf km k msg =
-    ef (String.sub (hf (km ^ k ^ km)) 0 16) msg
-
-  let hash_part hf km k msg =
-    xor_string msg (hf (km ^ k ^ km))
-
-  (* ef is an encryption function, hf is a hash function, k is the key,
-     m is the message. *)
-  let encrypt lt k m =
-    assert ((String.length k) = 20);
-    let epart = encrypt_part lt.efunc lt.hfunc
-    and hpart = hash_part lt.hfunc
-    and lm = String.sub m 0 20
-    and rm = String.sub m 20 ((String.length m) - 20) in
-    let r1 = epart k lm rm in
-    let l1 = hpart (xor_string k k1_mask) r1 lm in
-    let r2 = epart (xor_string k k2_mask) l1 r1 in
-    let l2 = hpart (xor_string k k3_mask) r2 l1 in
-      l2 ^ r2
-
-  let decrypt lt k m =
-    assert ((String.length k) = 20);
-    let epart = encrypt_part lt.efunc lt.hfunc
-    and hpart = hash_part lt.hfunc
-    and lm = String.sub m 0 20
-    and rm = String.sub m 20 ((String.length m) - 20) in
-    let l1 = hpart (xor_string k k3_mask) rm lm in
-    let r1 = epart (xor_string k k2_mask) l1 rm in
-    let l2 = hpart (xor_string k k1_mask) r1 l1 in
-    let r2 = epart k l2 r1 in
-      l2 ^ r2
-
-end
-
 module Counter = struct
 
   type direction =

Added: trunk/crypto/test_weasel.ml
===================================================================
--- trunk/crypto/test_weasel.ml	2004-05-02 18:04:23 UTC (rev 11)
+++ trunk/crypto/test_weasel.ml	2004-05-02 20:16:25 UTC (rev 12)
@@ -0,0 +1,105 @@
+(* test.ml -- RSA-OAEP PKCS#1 compliance testing for crypto.ml
+ * 
+ * Copyright (C) Erik Arneson 2004
+ *
+ * $Id: test.ml 9 2004-04-29 19:41:27Z laurent $ *)
+
+open Crypto
+open Cryptokit
+
+let hex s = transform_string (Hexa.encode()) s
+let unhex s = transform_string (Hexa.decode()) s
+
+
+let testHash =
+	let s1 = ""
+	and s2 = "I couldn't possibly fail to disagree with you less."
+	and s3 = "Everyone writes on the walls except me. -Said to be graffiti seen in Pompeii"
+	and s4 = "Freedom of the press is for those who happen to own one." in
+	let r1 = Crypto.hash s1
+	and r2 = Crypto.hash s2
+	and r3 = Crypto.hash s3
+	and r4 = Crypto.hash s4
+	and h1 = unhex "da39a3ee5e6b4b0d3255bfef95601890afd80709"
+	and h2 = unhex "90ecb7803dd428bd64ed296600d650a981268f1c"
+	and h3 = unhex "fcdbe159e7c4c2d25f329a75c19c209fd27fc10d"
+	and h4 = unhex "12dbc37c1f71491a8fae55ae305ab888b852f70d" in
+
+	assert(r1 = h1);
+	assert(r2 = h2);
+	assert(r3 = h3);
+	assert(r4 = h4);
+	Printf.printf "."
+
+let testPRNG =
+	let key = unhex "02 13 24 35 46 57 68 79 8A 9B AC BD CE DF E0 F1"
+	and keystream1 = unhex
+		"CA F3 E8 F6 23 B9 87 20 D2 F7 A8 66 9C B6 DE 01 71
+		31 CC 3E 74 20 80 99 62 2D 7D DF 98 59 D7 5B A6 77 78 FE 3C 22 C1 B5 AE 1F 8E
+		79 78 72 3D 0F 51 B7 EA 19 F7 93 7F F6 DC 21 EC 2C 13 54 DD 98"
+	and keystream2 = unhex
+		"81 AE AE FB 58 E0 A2 FE 37 27 31 8E 5B C4 90 B9
+		86 99 95 78 C0 F6 BC AC 9A A6 16 DF BA 0B 4E 6C 0A 10 C5 8F 7B 67 54 19 D7 EA
+		8C 4A A7 0E C7 77 6B 25 51 68 88 1C 7C 4D EB 83 8C A0 3F 4A 85 32" in
+	let keystream0 = Crypto.prng 0x40 key in
+	(* and keystream0 = Crypto.prng key 0x300 in *)
+
+	Printf.printf "\n%s\n%s\n" (hex keystream1) (hex keystream0);
+	assert(keystream0 = keystream1);
+	(*assert(keystream0[0x2c0..0x40] = keystream2); *)
+	Printf.printf "."
+
+let testEncrypt =
+	let key = unhex "02 13 24 35 46 57 68 79 8A 9B AC BD CE DF E0 F1"
+	and msg = unhex "48 65 6C 6C 6F 20 77 6F 72 6C 64 21"
+	and ciphertext = unhex "82 96 84 9A 4C 99 F0 4F A0 9B CC 47" in
+	let result = Crypto.encrypt key msg in
+
+	assert( result = ciphertext );
+	Printf.printf "."
+
+let testSPRPEncrypt =
+	let key = unhex
+		"AE BB 71 FA E1 F4 70 6C 0C 60 83 83 83 26 70 E3 60 63 37 EA"
+	and msg = unhex
+		"49 20 6E 65 76 65 72 20 62 65 6C 69 65 76 65 20 69 6E
+		20 63 6F 64 65 20 75 6E 74 69 6C 20 69 74 27 73 20 72 75 6E 6E 69 6E 67 2C 20
+		61 6E 64 20 49 20 6E 65 76 65 72 20 62 65 6C 69 65 76 65 20 69 6E 20 74 68 65
+		20 6E 65 78 74 20 72 65 6C 65 61 73 65 20 75 6E 74 69 6C 20 69 74 27 73 20 6F
+		75 74 2E"
+	and ciphertext = unhex
+		"1D 46 61 E1 CC 16 FA 17 5C B8 06 66 19 17 4C 09 44 B7
+		BC BC 57 8B 2E EB 06 19 4C E1 F0 0F 67 1B 1B A2 76 E9 3E 77 BF 7C 00 3D A2 91
+		3A 23 62 0A 4C DE 7A 52 E8 29 03 2A 93 B7 1F EC 5C A8 5C 84 7A 3F 45 A5 80 0A
+		0B B6 B5 DF E1 25 B0 DE CC 10 4D 46 45 EF 11 F7 CF 44 01 66 9D EC 36 BF CE 46
+		97 60 3D" in
+	let encrypted = Crypto.sprpEncrypt key msg in
+
+	assert(encrypted = ciphertext);
+	Printf.printf "."
+
+let testSPRPDecrypt =
+	let key = unhex
+		"AE BB 71 FA E1 F4 70 6C 0C 60 83 83 83 26 70 E3 60 63 37 EA"
+	and msg = unhex
+		"49 20 6E 65 76 65 72 20 62 65 6C 69 65 76 65 20 69 6E
+		20 63 6F 64 65 20 75 6E 74 69 6C 20 69 74 27 73 20 72 75 6E 6E 69 6E 67 2C 20
+		61 6E 64 20 49 20 6E 65 76 65 72 20 62 65 6C 69 65 76 65 20 69 6E 20 74 68 65
+		20 6E 65 78 74 20 72 65 6C 65 61 73 65 20 75 6E 74 69 6C 20 69 74 27 73 20 6F
+		75 74 2E"
+	and plaintext = unhex
+		"F3 5E 91 70 2F 43 14 9F E0 A0 3B 18 8E A9 FC 17 0A 3A
+		3F C0 EB A5 18 F6 03 4E E3 88 F7 B7 C3 2E 01 80 E1 D7 A1 86 B5 7D D8 38 B8 4D
+		DD 3E 3D D2 D2 15 CA 31 71 DF F7 85 7C 1C 95 20 5A B6 19 22 16 54 F1 4E 09 8E
+		BC 8E C1 02 F6 F5 CE EB 34 53 7F 52 A1 7B 3A 04 78 D8 4C 9C 18 34 FD 5D 63 DD
+		F0 E4 FD" in
+	let decrypted = Crypto.sprpDecrypt key msg in
+
+	assert(decrypted = plaintext);
+	Printf.printf "."
+
+let _ = 
+	testHash;
+	testSPRPEncrypt;
+	testSPRPDecrypt;
+	Printf.printf "\n"