[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[minion-cvs] add example BEAR implementation)



Update of /home/minion/cvsroot/src/minion/lib/mixminion
In directory moria.seul.org:/tmp/cvs-serv10632/lib/mixminion

Modified Files:
	test.py benchmark.py Crypto.py 
Log Message:
(add example BEAR implementation)

Crypto.py:
	Add BEAR support for testing purposes.
	Simplify LIONESS keygen

test.py:
	Tests for BEAR
	Make pychecker happy

benchmark.py
	Timing for BEAR
	Timing for 1536-bit RSA keys


Index: test.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/test.py,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -d -r1.36 -r1.37
--- test.py	21 Nov 2002 16:55:49 -0000	1.36
+++ test.py	22 Nov 2002 00:21:20 -0000	1.37
@@ -353,7 +353,6 @@
 
 
 #----------------------------------------------------------------------
-import mixminion.Crypto
 from mixminion.Crypto import *
 
 class CryptoTests(unittest.TestCase):
@@ -403,7 +402,7 @@
         # Make sure that CH_OAEP(RSA()) inverts pk_encrypt.
         eq(msg, _ml.check_oaep_padding(
                     k512.crypt(pk_encrypt(msg,k512), 0, 0),
-                    mixminion.Crypto.OAEP_PARAMETER, 64))
+                    Crypto.OAEP_PARAMETER, 64))
 
 	# test signing
 	eq(pk_check_signature(pk_sign(msg, k1024),pub1024), msg)
@@ -436,7 +435,7 @@
         dec = lioness_decrypt
 
         # Check basic cipher properties.
-        key = ("ABCDE"*4,) *4
+        key = ("ABCDE"*4, "ABCDF"*4, "DECBA"*4, "VWXYZ"*4)
         plain = "The more it snows the more it goes on snowing"*10
         self.assertNotEquals(plain, enc(plain,key))
         self.assertNotEquals(plain, dec(plain,key))
@@ -464,6 +463,36 @@
         self.assertEquals(left+right, lioness_encrypt(plain,key))
         self.assertEquals(key, Keyset("ABCDE"*4).getLionessKeys("foo"))
 
+    def test_bear(self):
+        enc = bear_encrypt
+        dec = bear_decrypt
+
+        # Check basic cipher properties.
+        key = ("ABCDE"*4, "QRSTU"*4)
+        plain = "The more it snows the more it goes on snowing"*10
+        self.assertNotEquals(plain, enc(plain,key))
+        self.assertNotEquals(plain, dec(plain,key))
+        self.assertEquals(len(plain), len(enc(plain,key)))
+        self.assertEquals(len(plain), len(dec(plain,key)))
+        self.assertEquals(plain, dec(enc(plain,key),key))
+        self.assertEquals(plain, enc(dec(plain,key),key))
+
+        # Walk through a LIONESS encryption to check for correct values.
+        # Check getLionessKeys too.
+        s = "ABCDE"*4
+        key1 = sha1(s+"foo")
+        key2 = key1[:-1]+strxor(key1[-1], chr(1))
+
+        left = plain[:20]
+        right = plain[20:]
+        left = strxor(left, sha1(key1+right+key1))
+        right = ctr_crypt(right, sha1(left)[:16])
+        left = strxor(left, sha1(key2+right+key2))
+
+        key = (key1,key2)
+        self.assertEquals(left+right, bear_encrypt(plain,key))
+        self.assertEquals(key, Keyset("ABCDE"*4).getBearKeys("foo"))
+
     def test_keyset(self):
         s = sha1
         x = _ml.strxor
@@ -861,7 +890,7 @@
 
     def test_compression(self):
 	p = AESCounterPRNG()
-	longMsg = p.getBytes(100)*2 + str(dir(mixminion.Crypto))
+	longMsg = p.getBytes(100)*2 + str(dir(Crypto))
 
 	# Make sure compression is reversible.
 	for m in ("", "a", "\000", "xyzzy"*10, ("glossy glossolalia.."*2)[32],
@@ -883,7 +912,7 @@
     def test_payload_helpers(self):
 	"test helpers for payload encoding"
 	p = AESCounterPRNG()
-	for i in xrange(10):
+	for _ in xrange(10):
 	    t = BuildMessage._getRandomTag(p)
 	    self.assertEquals(20, len(t))
 	    self.assertEquals(0, ord(t[0])&0x80)
@@ -1098,10 +1127,10 @@
                 payload = lioness_decrypt(payload, pkey)
 
             if path is secrets1:
-		swapkey = mixminion.Crypto.lioness_keys_from_header(head2)
+		swapkey = Crypto.lioness_keys_from_header(head2)
 		payload = lioness_decrypt(payload, swapkey)
 
-                swapkey = mixminion.Crypto.lioness_keys_from_payload(payload)
+                swapkey = Crypto.lioness_keys_from_payload(payload)
                 head2 = lioness_decrypt(head2, swapkey)
 
         self.assert_(head2 == h2)
@@ -1122,10 +1151,10 @@
             head2 = lioness_decrypt(head2, hkey)
             payload = lioness_decrypt(payload, pkey)
 
-        swapkey = mixminion.Crypto.lioness_keys_from_header(head2)
+        swapkey = Crypto.lioness_keys_from_header(head2)
         payload = lioness_decrypt(payload, swapkey)
 
-        swapkey = mixminion.Crypto.lioness_keys_from_payload(payload)
+        swapkey = Crypto.lioness_keys_from_payload(payload)
         head2 = lioness_decrypt(head2, swapkey)
 
         self.assert_(head2 == h2)
@@ -1156,8 +1185,8 @@
             ks = Keyset(s)
             p = lioness_decrypt(p,ks.getLionessKeys(PAYLOAD_ENCRYPT_MODE))
             h2 = lioness_decrypt(h2,ks.getLionessKeys(HEADER_ENCRYPT_MODE))
-	p = lioness_decrypt(p,mixminion.Crypto.lioness_keys_from_header(h2))
-        h2 = lioness_decrypt(h2,mixminion.Crypto.lioness_keys_from_payload(p))
+	p = lioness_decrypt(p,Crypto.lioness_keys_from_header(h2))
+        h2 = lioness_decrypt(h2,Crypto.lioness_keys_from_payload(p))
 
         sec, tag = self.do_header_test(h2, withTag=1, *header_info_2)
         for s in sec:
@@ -1348,7 +1377,7 @@
 	for s in secrets_1:
 	    ks = Keyset(s)
 	    p = lioness_encrypt(p, ks.getLionessKeys(
- 	 	               mixminion.Crypto.PAYLOAD_ENCRYPT_MODE))
+ 	 	               Crypto.PAYLOAD_ENCRYPT_MODE))
 	comp = BuildMessage.compressData('Information???')
 	self.assertEquals(len(comp), ord(p[0])*256 +ord(p[1]))
 	self.assert_(p[22:].startswith(comp))
@@ -1361,7 +1390,7 @@
 	    s = prng.getBytes(16)
 	    ks = Keyset(s)
 	    p = lioness_encrypt(p, ks.getLionessKeys(
-		                      mixminion.Crypto.PAYLOAD_ENCRYPT_MODE))
+		                      Crypto.PAYLOAD_ENCRYPT_MODE))
 	comp = BuildMessage.compressData(payload)
 	self.assertEquals(len(comp), ord(p[0])*256 +ord(p[1]))
 	self.assert_(p[22:].startswith(comp))
@@ -2273,7 +2302,6 @@
             while not clientcon.isShutdown():
                 async.process(2)
 
-        severity = getLog().getMinSeverity()
         try:
 	    suspendLog() # suppress warning
             server.process(0.1)
@@ -2623,13 +2651,13 @@
         keydir = os.path.join(d, "key_key1")
         eq(inf, open(os.path.join(keydir, "ServerDesc")).read())
 	mixminion.ServerInfo.ServerKeyset(d, "key1", d) # Can we load?
-        packetKey = mixminion.Crypto.pk_PEM_load(
+        packetKey = Crypto.pk_PEM_load(
             os.path.join(keydir, "mix.key"))
         eq(packetKey.get_public_key(),
            info['Server']['Packet-Key'].get_public_key())
-        mmtpKey = mixminion.Crypto.pk_PEM_load(
+        mmtpKey = Crypto.pk_PEM_load(
             os.path.join(keydir, "mmtp.key"))
-        eq(mixminion.Crypto.sha1(mmtpKey.encode_key(1)),
+        eq(Crypto.sha1(mmtpKey.encode_key(1)),
            info['Incoming/MMTP']['Key-Digest'])
 
         # Now check the digest and signature
@@ -2638,7 +2666,7 @@
         x = sha1(pat.sub(r'\1', inf))
 
         eq(info['Server']['Digest'], x)
-        eq(x, mixminion.Crypto.pk_check_signature(info['Server']['Signature'],
+        eq(x, Crypto.pk_check_signature(info['Server']['Signature'],
                                                   identityPK))
 
         # Now with a shorter configuration
@@ -2657,7 +2685,7 @@
 							     "key2",
 							     d)
         # Now with a bad signature
-        sig2 = mixminion.Crypto.pk_sign(sha1("Hello"), identity)
+        sig2 = Crypto.pk_sign(sha1("Hello"), identity)
         sig2 = base64.encodestring(sig2).replace("\n", "")
         sigpat = re.compile('^Signature:.*$', re.M)
         badSig = sigpat.sub("Signature: %s" % sig2, inf)
@@ -2677,7 +2705,6 @@
 
 #----------------------------------------------------------------------
 # Modules annd ModuleManager
-from mixminion.Modules import *
 
 # test of an example module that we load dynamically from
 EXAMPLE_MODULE_TEXT = \
@@ -2922,17 +2949,17 @@
 	# Test creating identity key
 	identity = keyring.getIdentityKey()
 	fn = os.path.join(home, "keys", "identity.key")
-	identity2 = mixminion.Crypto.pk_PEM_load(fn)
-	self.assertEquals(mixminion.Crypto.pk_get_modulus(identity),
-			  mixminion.Crypto.pk_get_modulus(identity2))
+	identity2 = Crypto.pk_PEM_load(fn)
+	self.assertEquals(Crypto.pk_get_modulus(identity),
+			  Crypto.pk_get_modulus(identity2))
 	# (Make sure warning case can occur.)
 	pk = getRSAKey(0,128)
-	mixminion.Crypto.pk_PEM_save(pk, fn)
+	Crypto.pk_PEM_save(pk, fn)
 	suspendLog()
 	keyring.getIdentityKey()
 	msg = resumeLog()
 	self.failUnless(len(msg))
-	mixminion.Crypto.pk_PEM_save(identity, fn)
+	Crypto.pk_PEM_save(identity, fn)
 
 	# Now create a keyset
 	keyring.createKeys(1)
@@ -2980,7 +3007,7 @@
 	    keyring.getTLSContext()
 
 	# Test getPacketHandler
-	ph = keyring.getPacketHandler()
+	_ = keyring.getPacketHandler()
 
     def testIncomingQueue(self):
 	# Test deliverMessage.
@@ -3022,6 +3049,7 @@
     [ "Lisa",	  "3 days",  "10.0.0.11", (-10,-1,5) ],
 ]
 
+_EXAMPLE_DESCRIPTORS_TIME = 0
 def getExampleServerDescriptors():
     if _EXAMPLE_DESCRIPTORS:
  	return _EXAMPLE_DESCRIPTORS

Index: benchmark.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/benchmark.py,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- benchmark.py	13 Oct 2002 18:44:51 -0000	1.10
+++ benchmark.py	22 Nov 2002 00:21:20 -0000	1.11
@@ -186,6 +186,28 @@
     print "lioness D (32K)", timeit((
         lambda lkey=lkey: lioness_decrypt(s32K, lkey)), 100)
 
+    bkey = Keyset("keymaterial foo bar baz").getBearKeys("T")
+    print "bear E (1K)", timeit((
+        lambda bkey=bkey: bear_encrypt(s1K, bkey)), 1000)
+    print "bear E (2K)", timeit((
+        lambda bkey=bkey: bear_encrypt(s1K, bkey)), 1000)
+    print "bear E (4K)", timeit((
+        lambda bkey=bkey: bear_encrypt(s4K, bkey)), 1000)
+    print "bear E (28K)", timeit((
+        lambda bkey=bkey: bear_encrypt(s28K, bkey)), 100)
+    print "bear E (32K)", timeit((
+        lambda bkey=bkey: bear_encrypt(s32K, bkey)), 100)
+    print "bear D (1K)", timeit((
+        lambda bkey=bkey: bear_decrypt(s1K, bkey)), 1000)
+    print "bear D (2K)", timeit((
+        lambda bkey=bkey: bear_decrypt(s1K, bkey)), 1000)
+    print "bear D (4K)", timeit((
+        lambda bkey=bkey: bear_decrypt(s4K, bkey)), 1000)
+    print "bear D (28K)", timeit((
+        lambda bkey=bkey: bear_decrypt(s28K, bkey)), 100)
+    print "bear D (32K)", timeit((
+        lambda bkey=bkey: bear_decrypt(s32K, bkey)), 100)
+
     if hasattr(_ml, 'add_oaep_padding'):
         print "OAEP_add (70->128B) (C)",
         print timeit((lambda: _ml.add_oaep_padding(s70b,OAEP_PARAMETER,128)),
@@ -231,8 +253,7 @@
     print "Pad+RSA private decrypt", \
           timeit((lambda enc=enc,rsa=rsa: pk_decrypt(enc, rsa)),100)
 
-
-    for (bits,it) in ((2048,10),(4096,10)):
+    for (bits,it) in ((1536,15), (2048,10),(4096,10)):
         t = time()
 	print "[generating key...]"
         rsa2 = pk_generate(bits)

Index: Crypto.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/Crypto.py,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- Crypto.py	14 Oct 2002 03:03:42 -0000	1.22
+++ Crypto.py	22 Nov 2002 00:21:20 -0000	1.23
@@ -18,7 +18,8 @@
 from mixminion.Common import MixError, MixFatalError, floorDiv, ceilDiv, getLog
 
 __all__ = [ 'CryptoError', 'init_crypto', 'sha1', 'ctr_crypt', 'prng',
-            'strxor', 'lioness_encrypt', 'lioness_decrypt', 'trng',
+            'strxor', 'lioness_encrypt', 'lioness_decrypt',
+            'bear_encrypt', 'bear_decrypt', 'trng',
             'pk_encrypt', 'pk_decrypt', 'pk_sign', 'pk_check_signature',
 	    'pk_generate', 'openssl_seed',
             'pk_get_modulus', 'pk_from_modulus',
@@ -78,8 +79,8 @@
     return _ml.aes_ctr128_crypt(key,"",idx,count)
 
 def lioness_encrypt(s,(key1,key2,key3,key4)):
-    """Given a 16-byte key2 and key4, and a 20-byte key1 and key3, encrypts
-       s using the LIONESS super-pseudorandom permutation.
+    """Given four 20-byte keys, encrypts s using the LIONESS
+       super-pseudorandom permutation.
     """
 
     assert len(key1) == len(key3) == DIGEST_LEN
@@ -121,6 +122,38 @@
     right = ctr_crypt(right, _ml.sha1("".join([key1,left,key1]))[:AES_KEY_LEN])
     return left + right
 
+def bear_encrypt(s,(key1,key2)):
+    """Given four 20-byte keys, encrypts s using the BEAR
+       pseudorandom permutation.
+    """
+
+    assert len(key1) == len(key2) == DIGEST_LEN
+    assert len(s) > DIGEST_LEN
+
+    left = s[:DIGEST_LEN]
+    right = s[DIGEST_LEN:]
+    del s
+    left = _ml.strxor(left, _ml.sha1("".join((key1,right,key1))))
+    right = ctr_crypt(right, _ml.sha1(left)[:AES_KEY_LEN])
+    left = _ml.strxor(left, _ml.sha1("".join((key2,right,key2))))
+    return left + right
+
+def bear_decrypt(s,(key1,key2)):
+    """Given four 20-byte keys, decrypts s using the BEAR
+       pseudorandom permutation.
+    """
+
+    assert len(key1) == len(key2) == DIGEST_LEN
+    assert len(s) > DIGEST_LEN
+
+    left = s[:DIGEST_LEN]
+    right = s[DIGEST_LEN:]
+    del s
+    left = _ml.strxor(left, _ml.sha1("".join((key2,right,key2))))
+    right = ctr_crypt(right, _ml.sha1(left)[:AES_KEY_LEN])
+    left = _ml.strxor(left, _ml.sha1("".join((key1,right,key1))))
+    return left + right
+
 def openssl_seed(count):
     """Seeds the openssl rng with 'count' bytes of real entropy."""
     _ml.openssl_seed(trng(count))
@@ -366,11 +399,17 @@
            specification."""
         z19 = "\x00"*19
         key1 = sha1(self.master+mode)
-        key2 = _ml.strxor(sha1(self.master+mode), z19+"\x01")
-        key3 = _ml.strxor(sha1(self.master+mode), z19+"\x02")
-        key4 = _ml.strxor(sha1(self.master+mode), z19+"\x03")
-
+        key2 = _ml.strxor(key1, z19+"\x01")
+        key3 = _ml.strxor(key1, z19+"\x02")
+        key4 = _ml.strxor(key1, z19+"\x03")
+        
         return (key1, key2, key3, key4)
+
+    def getBearKeys(self,mode):
+        z19 = "\x00"*19
+        key1 = sha1(self.master+mode)
+        key2 = _ml.strxor(key1, z19+"\x01")
+        return (key1, key2)
 
 def lioness_keys_from_payload(payload):
     '''Given a payload, returns the LIONESS keys to encrypt the off-header