README: Include some useful documentation.
[ocb-tv] / ocbgen
diff --git a/ocbgen b/ocbgen
index acdd997..6368b30 100755 (executable)
--- a/ocbgen
+++ b/ocbgen
@@ -25,6 +25,9 @@
 from sys import argv, stderr
 from struct import pack
 from itertools import izip
+from contextlib import contextmanager
+try: from kalyna import Kalyna
+except ImportError: Kalyna = None
 import catacomb as C
 
 R = C.FibRand(0)
@@ -139,6 +142,35 @@ def blocks0(x, w):
   return v, tl
 
 ###--------------------------------------------------------------------------
+### Kalyna decoration.
+
+KALYNA = {}
+
+if Kalyna is not None:
+
+  class KalynaCipher (type):
+    def __new__(cls, blksz):
+      assert blksz in [16, 32, 64]
+      name = 'Kalyna-%d' % (8*blksz)
+      me = type(name, (KalynaBase,), {})
+      me.name = name
+      me.blksz = blksz
+      if blksz == 64: me.keysz = C.KeySZSet(64)
+      else: me.keysz = C.KeySZSet(2*blksz, [blksz])
+      return me
+
+  class KalynaBase (object):
+    def __init__(me, k):
+      me._k = Kalyna(k, me.blksz)
+    def encrypt(me, m):
+      return C.ByteString(me._k.encrypt(m))
+    def decrypt(me, m):
+      return C.ByteString(me._k.decrypt(m))
+
+  for i in [16, 32, 64]:
+    KALYNA['kalyna%d' % (8*i)] = KalynaCipher(i)
+
+###--------------------------------------------------------------------------
 ### Luby--Rackoff large-block ciphers.
 
 class LubyRackoffCipher (type):
@@ -153,25 +185,35 @@ class LubyRackoffCipher (type):
     me.bc = bc
     return me
 
+@contextmanager
+def muffle():
+  global VERBOSE, LRVERBOSE
+  _v, _lrv = VERBOSE, LRVERBOSE
+  try:
+    VERBOSE = LRVERBOSE = False
+    yield None
+  finally:
+    VERBOSE, LRVERBOSE = _v, _lrv
+
 class LubyRackoffBase (object):
   NR = 4 # for strong-PRP security
   def __init__(me, k):
     if LRVERBOSE: print 'K = %s' % hex(k)
     bc, blksz = me.__class__.bc, me.__class__.blksz
-    E = bc(k)
+    with muffle(): E = bc(k)
     me.f = []
     ksz = len(k)
     i = C.MP(0)
     for j in xrange(me.NR):
       b = C.WriteBuffer()
       while b.size < ksz:
-        x = E.encrypt(i.storeb(bc.blksz))
+        with muffle(): x = E.encrypt(i.storeb(bc.blksz))
         b.put(x)
         if LRVERBOSE: print 'E(K; [%d]) = %s' % (i, hex(x))
         i += 1
       kj = C.ByteString(C.ByteString(b)[0:ksz])
       if LRVERBOSE: print 'K_%d = %s' % (j, hex(kj))
-      me.f.append(bc(kj))
+      with muffle(): me.f.append(bc(kj))
   def encrypt(me, m):
     bc, blksz = me.__class__.bc, me.__class__.blksz
     assert len(m) == blksz
@@ -179,7 +221,7 @@ class LubyRackoffBase (object):
     if LRVERBOSE: print 'L_0, R_0 = %s, %s' % (hex(l), hex(r))
     for j in xrange(me.NR):
       l0 = pad0star(l, bc.blksz)
-      t = me.f[j].encrypt(l0)
+      with muffle(): t = me.f[j].encrypt(l0)
       l, r = r ^ t[:blksz/2], l
       if LRVERBOSE:
         print 'E(K_%d; L_%d || 0^*) = %s' % (j, j, hex(t))
@@ -191,7 +233,7 @@ class LubyRackoffBase (object):
     l, r = C.ByteString(c[:blksz/2]), C.ByteString(c[blksz/2:])
     for j in xrange(me.NR - 1, -1, -1):
       l0 = pad0star(l, bc.blksz)
-      t = me.f[j].encrypt(l0)
+      with muffle(): t = me.f[j].encrypt(l0)
       if LRVERBOSE:
         print 'L_%d, R_%d = %s, %s' % (j + 1, j + 1, hex(l), hex(r))
         print 'E(K_%d; L_%d || 0^*) = %s' % (j + 1, j + 1, hex(t))
@@ -202,6 +244,7 @@ class LubyRackoffBase (object):
 LRAES = {}
 for i in [8, 12, 16, 24, 32]:
   LRAES['lraes%d' % (8*i)] = LubyRackoffCipher(C.rijndael, i)
+LRAES['dlraes512'] = LubyRackoffCipher(LubyRackoffCipher(C.rijndael, 32), 64)
 
 ###--------------------------------------------------------------------------
 ### PMAC.
@@ -386,7 +429,8 @@ OCB3_STRETCH = { 8: (5, 25),
                  12: (6, 33),
                  16: (6, 8),
                  24: (7, 40),
-                 32: (7, 120) }
+                 32: (7, 120),
+                 64: (8, 240) }
 
 def ocb3(E, n, h, m, tsz = None):
   blksz = E.__class__.blksz
@@ -536,7 +580,7 @@ ocb = MODEMAP[opt]
 
 bcname = arg()
 bc = None
-for d in LRAES, C.gcprps:
+for d in LRAES, KALYNA, C.gcprps:
   try: bc = d[bcname]
   except KeyError: pass
   else: break