summaryrefslogtreecommitdiff
path: root/python/lilliput/lilliput_ae_1.py
diff options
context:
space:
mode:
authorKévin Le Gouguec <kevin.legouguec@airbus.com>2019-03-22 10:38:19 +0100
committerKévin Le Gouguec <kevin.legouguec@airbus.com>2019-03-22 10:38:19 +0100
commitbac28f498c5fee10720c8ed71988434e05d9197f (patch)
tree017de97abfb609163669a89c754bb813c50ec891 /python/lilliput/lilliput_ae_1.py
parentdd934c63386c8fa22a5b0944e0256c435d55938c (diff)
downloadlilliput-ae-implem-bac28f498c5fee10720c8ed71988434e05d9197f.tar.xz
[implem-python] Création d'un paquet "lilliput"
Diffstat (limited to 'python/lilliput/lilliput_ae_1.py')
-rw-r--r--python/lilliput/lilliput_ae_1.py155
1 files changed, 155 insertions, 0 deletions
diff --git a/python/lilliput/lilliput_ae_1.py b/python/lilliput/lilliput_ae_1.py
new file mode 100644
index 0000000..0da2a95
--- /dev/null
+++ b/python/lilliput/lilliput_ae_1.py
@@ -0,0 +1,155 @@
+"""
+ OCB 3 for lilliput ae i
+"""
+
+from enum import Enum
+
+from .constants import BLOCK_BYTES, NONCE_BYTES
+from .helpers import (
+ ArrayToBlockbytesMatrix,
+ BlockbytesMatrixToBytes,
+ BuildAuth,
+ Padding10LSB,
+ TagValidationError,
+ XorState
+)
+from . import tbc
+
+
+TWEAK_BITS = 192
+TWEAK_BYTES = TWEAK_BITS//8
+
+
+def LowPart(array, number_bits):
+ shifted = 0
+ for byte in range(0, len(array)):
+ shifted |= (array[byte] << (8 * byte))
+
+ mask = 0
+ for bit in range(0, number_bits):
+ mask |= (0x1 << bit)
+
+ lower_part = shifted & mask
+
+ will_pad = 0
+ if number_bits % 8 != 0:
+ will_pad = 1
+
+ lower_part_byte = []
+ nb_bytes = number_bits//8 + will_pad
+ for byte in range(nb_bytes):
+ lower_part_byte.append(lower_part & 0xff)
+ lower_part = lower_part >> 8
+
+ return lower_part_byte
+
+
+class _MessageTweak(Enum):
+ BLOCK = 0b000
+ NO_PADDING = 0b0001
+ PAD = 0b0100
+ FINAL = 0b0101
+
+
+def TweakMessage(N, j, padding):
+ tweak = [0 for byte in range(0, TWEAK_BYTES)]
+ for byte in range(NONCE_BYTES-1, -1, -1):
+ tweak[byte + (TWEAK_BYTES-NONCE_BYTES)] |= (N[byte] & 0xf0) >> 4
+ tweak[byte + (TWEAK_BYTES-NONCE_BYTES-1)] |= (N[byte] & 0x0f) << 4
+
+ tweak[TWEAK_BYTES-NONCE_BYTES-1] |= ((j >> 64) & 0xf)
+ for byte in range(TWEAK_BYTES-NONCE_BYTES-2, -1, -1):
+ tweak[byte] = (j >> (8 * byte)) & 0xff
+
+ tweak[-1] |= padding.value<<4
+
+ return tweak
+
+
+def TreatMessageEnc(M, N, key):
+ checksum = [0 for byte in range(0, BLOCK_BYTES)]
+
+ l = len(M)//BLOCK_BYTES
+ padding_bytes = len(M)%BLOCK_BYTES
+
+ M = ArrayToBlockbytesMatrix(M)
+ C = []
+
+ for j in range(0, l):
+ checksum = XorState(checksum, M[j])
+ tweak = TweakMessage(N, j, _MessageTweak.BLOCK)
+ C.append(tbc.encrypt(tweak, key, M[j]))
+
+ if padding_bytes == 0:
+ tweak = TweakMessage(N, l, _MessageTweak.NO_PADDING)
+ Final = tbc.encrypt(tweak, key, checksum)
+
+ else:
+ m_padded = Padding10LSB(M[l])
+ checksum = XorState(checksum, m_padded)
+ tweak = TweakMessage(N, l, _MessageTweak.PAD)
+ pad = tbc.encrypt(tweak, key, [0 for byte in range(0, BLOCK_BYTES)])
+
+ lower_part = LowPart(pad, padding_bytes*8)
+ C.append(XorState(M[l], lower_part))
+ tweak_final = TweakMessage(N, l+1, _MessageTweak.FINAL)
+ Final = tbc.encrypt(tweak_final, key, checksum)
+
+ return (Final, C)
+
+
+def TreatMessageDec(C, N, key):
+ checksum = [0 for byte in range(0, BLOCK_BYTES)]
+
+ l = len(C)//BLOCK_BYTES
+ padding_bytes = len(C)%BLOCK_BYTES
+
+ C = ArrayToBlockbytesMatrix(C)
+ M = []
+
+ for j in range(0, l):
+ tweak = TweakMessage(N, j, _MessageTweak.BLOCK)
+ M.append(tbc.decrypt(tweak, key, C[j]))
+ checksum = XorState(checksum, M[j])
+
+ if padding_bytes == 0:
+ tweak = TweakMessage(N, l, _MessageTweak.NO_PADDING)
+ Final = tbc.encrypt(tweak, key, checksum)
+
+ else:
+ tweak = TweakMessage(N, l, _MessageTweak.PAD)
+ pad = tbc.encrypt(tweak, key, [0 for byte in range(0, BLOCK_BYTES)])
+ lower_part = LowPart(pad, padding_bytes*8)
+ M.append(XorState(C[l], lower_part))
+
+ m_padded = Padding10LSB(M[l])
+ checksum = XorState(checksum, m_padded)
+ tweak_final = TweakMessage(N, l+1, _MessageTweak.FINAL)
+ Final = tbc.encrypt(tweak_final, key, checksum)
+
+ return (Final, M)
+
+
+################################################################################
+def encrypt(A, M, N, key):
+ K = list(key)
+
+ Auth = BuildAuth(TWEAK_BITS, A, K)
+ (Final, C) = TreatMessageEnc(M, N, K)
+ tag = XorState(Auth, Final)
+
+ return BlockbytesMatrixToBytes(C), bytes(tag)
+
+
+def decrypt(A, C, N, tag, key):
+ K = list(key)
+ tag = list(tag)
+
+ Auth = BuildAuth(TWEAK_BITS, A, K)
+ (Final, M) = TreatMessageDec(C, N, K)
+ tag2 = XorState(Auth, Final)
+
+ if tag != tag2:
+ raise TagValidationError(tag, tag2)
+
+ return BlockbytesMatrixToBytes(M)