[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"