Makefile, ocbgen: Support Ukrainian `Kalyna' block cipher.
authorMark Wooding <mdw@distorted.org.uk>
Sun, 16 Jul 2017 14:08:00 +0000 (15:08 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sun, 16 Jul 2017 14:58:58 +0000 (15:58 +0100)
Interesting because it has 512-bit blocks.  Requires a Python
implementation of Kalyna, not included; see

https://git.distorted.org.uk/~mdw/kalyna-python/

for suitable bindings to the reference implementation.  Define
`HAVE_KALYNA' to enable the extra magic.

Makefile
ocbgen

index 6f980be..7b7e554 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -80,6 +80,34 @@ rijndael256_K0                = $(misc256_K0)
 rijndael256_K1          = $(misc256_K1)
 rijndael256_KSZS        = $(aes_KSZS)
 
+ifdef HAVE_KALYNA
+BLKC                   += $(KALYNA)
+endif
+
+KALYNA                 += kalyna128
+kalyna128_PRETTY        = Kalyna-128
+kalyna128_NAME          = kalyna128
+kalyna128_BLKSZ                 = 128
+kalyna128_K0            = $(misc128_K0)
+kalyna128_K1            = $(misc128_K1)
+kalyna128_KSZS          = 128 256
+
+KALYNA                 += kalyna256
+kalyna256_PRETTY        = Kalyna-256
+kalyna256_NAME          = kalyna256
+kalyna256_BLKSZ                 = 256
+kalyna256_K0            = $(misc256_K0)
+kalyna256_K1            = $(misc256_K1)
+kalyna256_KSZS          = 256 512
+
+KALYNA                 += kalyna512
+kalyna512_PRETTY        = Kalyna-512
+kalyna512_NAME          = kalyna512
+kalyna512_BLKSZ                 = 512
+kalyna512_K0            = $(misc512_K0)
+kalyna512_K1            = $(misc512_K1)
+kalyna512_KSZS          = 512
+
 define def-lraes
 LRAES                  += $1
 BLKC                   += lraes$1
diff --git a/ocbgen b/ocbgen
index a0c360f..6368b30 100755 (executable)
--- a/ocbgen
+++ b/ocbgen
@@ -26,6 +26,8 @@ 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)
@@ -140,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):
@@ -549,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