symm/eax.h, symm/eax-def.h: Implement the EAX authenticated encryption mode.
[catacomb] / utils / advmodes
index 96e5f5b..3af744e 100755 (executable)
@@ -103,6 +103,8 @@ def blocks0(x, w):
   if len(tl) == w: v.append(tl); tl = EMPTY
   return v, tl
 
+def dummygen(bc): return []
+
 CUSTOM = {}
 
 ###--------------------------------------------------------------------------
@@ -266,6 +268,63 @@ def cmacgen(bc):
           (3*bc.blksz - 5,)]
 
 ###--------------------------------------------------------------------------
+### Counter mode.
+
+def ctr(E, m, c0):
+  blksz = E.__class__.blksz
+  y = C.WriteBuffer()
+  c = C.MP.loadb(c0)
+  while y.size < len(m):
+    y.put(E.encrypt(c.storeb(blksz)))
+    c += 1
+  return C.ByteString(m) ^ C.ByteString(y)[:len(m)]
+
+###--------------------------------------------------------------------------
+### EAX.
+
+def eaxenc(E, n, h, m, tsz = None):
+  if VERBOSE:
+    print 'k = %s' % hex(k)
+    print 'n = %s' % hex(n)
+    print 'h = %s' % hex(h)
+    print 'm = %s' % hex(m)
+    dump_omac(E)
+  if tsz is None: tsz = E.__class__.blksz
+  c0 = omac(E, 0, n)
+  y = ctr(E, m, c0)
+  ht = omac(E, 1, h)
+  yt = omac(E, 2, y)
+  if VERBOSE:
+    print 'c0 = %s' % hex(c0)
+    print 'ht = %s' % hex(ht)
+    print 'yt = %s' % hex(yt)
+  return y, C.ByteString((c0 ^ ht ^ yt)[:tsz])
+
+def eaxdec(E, n, h, y, t):
+  if VERBOSE:
+    print 'k = %s' % hex(k)
+    print 'n = %s' % hex(n)
+    print 'h = %s' % hex(h)
+    print 'y = %s' % hex(y)
+    print 't = %s' % hex(t)
+    dump_omac(E)
+  c0 = omac(E, 0, n)
+  m = ctr(E, y, c0)
+  ht = omac(E, 1, h)
+  yt = omac(E, 2, y)
+  if VERBOSE:
+    print 'c0 = %s' % hex(c0)
+    print 'ht = %s' % hex(ht)
+    print 'yt = %s' % hex(yt)
+  if t == (c0 ^ ht ^ yt)[:len(t)]: return m,
+  else: return None,
+
+def eaxgen(bc):
+  return [(0, 0, 0), (1, 0, 0), (0, 1, 0), (0, 0, 1),
+          (bc.blksz, 3*bc.blksz, 3*bc.blksz),
+          (bc.blksz - 1, 3*bc.blksz - 5, 3*bc.blksz + 5)]
+
+###--------------------------------------------------------------------------
 ### Main program.
 
 class struct (object):
@@ -275,7 +334,9 @@ class struct (object):
 binarg = struct(mk = R.block, parse = C.bytes, show = safehex)
 intarg = struct(mk = lambda x: x, parse = int, show = None)
 
-MODEMAP = { 'cmac': (cmacgen, [binarg], cmac) }
+MODEMAP = { 'eax-enc': (eaxgen, 3*[binarg] + [intarg], eaxenc),
+            'eax-dec': (dummygen, 4*[binarg], eaxdec),
+            'cmac': (cmacgen, [binarg], cmac) }
 
 mode = argv[1]
 bc = None
@@ -287,6 +348,7 @@ if bc is None: raise KeyError, argv[2]
 if len(argv) == 3:
   VERBOSE = False
   gen, argty, func = MODEMAP[mode]
+  if mode.endswith('-enc'): mode = mode[:-4]
   print '%s-%s {' % (bc.name, mode)
   for ksz in keylens(bc.keysz):
     for argvals in gen(bc):
@@ -305,6 +367,8 @@ else:
   gen, argty, func = MODEMAP[mode]
   args = [t.parse(a) for t, a in izip(argty, argv[4:])]
   rets = func(bc(k), *args)
-  for r in rets: print hex(r)
+  for r in rets:
+    if r is None: print "X"
+    else: print hex(r)
 
 ###----- That's all, folks --------------------------------------------------