summaryrefslogtreecommitdiff
path: root/src/add_python/lilliput/helpers.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/add_python/lilliput/helpers.py')
-rw-r--r--src/add_python/lilliput/helpers.py92
1 files changed, 92 insertions, 0 deletions
diff --git a/src/add_python/lilliput/helpers.py b/src/add_python/lilliput/helpers.py
new file mode 100644
index 0000000..8677f06
--- /dev/null
+++ b/src/add_python/lilliput/helpers.py
@@ -0,0 +1,92 @@
+from .constants import BLOCK_BITS, BLOCK_BYTES
+from . import tbc
+
+
+def ArrayToBlockbytesMatrix(array):
+ vector = list(array)
+
+ blocks_nb = len(vector)//BLOCK_BYTES
+
+ block_starts = (
+ i*BLOCK_BYTES for i in range(blocks_nb)
+ )
+
+ matrix = [
+ vector[start:start+BLOCK_BYTES] for start in block_starts
+ ]
+
+ padding_len = len(vector)%BLOCK_BYTES
+
+ if padding_len > 0:
+ padding = vector[-padding_len:]
+ matrix.append(padding)
+
+ return matrix
+
+
+def BlockbytesMatrixToBytes(matrix):
+ return bytes(byte for block in matrix for byte in block)
+
+
+def XorState(state1, state2):
+ return [s1^s2 for (s1, s2) in zip(state1, state2)]
+
+
+def Padding10LSB(X):
+ zeroes = [0] * (BLOCK_BYTES-len(X)-1)
+ return zeroes + [0b10000000] + X
+
+
+def _tweakAssociatedData(t, i, padded):
+ t_bytes = t//8
+ tweak = [0]*(t_bytes)
+
+ mask = 0xff
+ for byte in range(t_bytes-1):
+ tweak[byte] = (i & mask) >> (byte * 8)
+ mask = mask << 8
+
+ mask = (0xf << (8 * t_bytes-1))
+ tweak[-1] = (i & mask) >> ((t_bytes-1)*8)
+ if not padded:
+ tweak[-1] |= 0x20
+ else:
+ tweak[-1] |= 0x60
+
+ return tweak
+
+
+def BuildAuth(t, A, key):
+ Auth = [0 for byte in range(0, BLOCK_BYTES)]
+ l_a = len(A)//BLOCK_BYTES
+ need_padding = len(A)%BLOCK_BYTES > 0
+
+ A = ArrayToBlockbytesMatrix(A)
+
+ for i in range(0, l_a):
+ tweak = _tweakAssociatedData(t, i, padded=False)
+ enc = tbc.encrypt(tweak, key, A[i])
+ Auth = XorState(Auth, enc)
+
+ if not need_padding:
+ return Auth
+
+ tweak = _tweakAssociatedData(t, l_a, padded=True)
+ ad_padded = Padding10LSB(A[l_a])
+ enc = tbc.encrypt(tweak, key, ad_padded)
+ Auth = XorState(Auth, enc)
+
+ return Auth
+
+
+class TagValidationError(Exception):
+ def __init__(self, announced, computed):
+ msg = '\n'.join((
+ 'Invalid tag:',
+ announced.hex().upper()+' (announced)',
+ computed.hex().upper()+' (computed)'
+ ))
+
+ super().__init__(msg)
+ self._announced = announced
+ self._computed = computed