def CTR(arr, encrypt=True): ''' Counter Mode is xoring the message with a encrypted counter (IV + incr(0)) arr: array of bytearray of 8 bytes of data to encrypt/decrypt encrypt: true to encrypt ''' if encrypt: iv = IV(arr) else: iv = IV_action(arr) res = [] for i, message in enumerate(arr): config.WATCH_PERCENTAGE = ((len(arr) - (len(arr) - i)) / len(arr)) * 100 exTime = time.time() noc = bm.byte_operation(iv, (i + 1).to_bytes(8, "big"), "XOR") kas = kasu.kasumi(noc, True) coded = bm.byte_operation(message, kas, "XOR") res.append(coded) config.WATCH_GLOBAL_CIPHER += time.time() - exTime config.WATCH_BLOC_CIPHER = config.WATCH_GLOBAL_CIPHER / (i + 1) config.WATCH_BLOC_KASUMI = config.WATCH_GLOBAL_KASUMI / (i + 1) if encrypt: # Adding the IV to the encrypted data IV_action(res, iv, "store") return res
def GHASH64(H, A, C, X, i): n = len(C) m = len(A) if i <= m: # A1 = A[1-1] return gz2.poly_mult_mod_2( bti(bm.byte_operation(X, A[i - 1], "XOR")), H, p) elif i <= m + n: return gz2.poly_mult_mod_2( bti(bm.byte_operation(X, C[i - m - 1], "XOR")), H, p) elif i == m + n + 1: return gz2.poly_mult_mod_2( bti( bm.byte_operation( gz2.poly_mult_mod_2( bti(bm.byte_operation(X, lenb(A), "XOR")), H, p).to_bytes(8, "big"), lenb(C), "XOR")), H, p)
def CBC(arr, encrypt=True): """In CBC mode, each block of plaintext is XORed with the previous ciphertext block before being encrypted. """ # Initialisation Vector if encrypt: iv = IV(arr) else: iv = IV_action(arr) res = [] for i, message in enumerate(arr): config.WATCH_PERCENTAGE = ((len(arr) - (len(arr) - i)) / len(arr)) * 100 exTime = time.time() if i == 0: # Initialization if encrypt: res.append(kasu.kasumi(bm.byte_operation(iv, message, "XOR"))) else: res.append( bm.byte_operation(kasu.kasumi(message, False), iv, "XOR")) else: if encrypt: res.append( kasu.kasumi(bm.byte_operation(res[i - 1], message, "XOR"))) else: res.append( bm.byte_operation(kasu.kasumi(message, False), arr[i - 1], "XOR")) config.WATCH_GLOBAL_CIPHER += time.time() - exTime config.WATCH_BLOC_CIPHER = config.WATCH_GLOBAL_CIPHER / (i + 1) config.WATCH_BLOC_KASUMI = config.WATCH_GLOBAL_KASUMI / (i + 1) if encrypt: # Adding the IV to the encrypted data IV_action(res, iv, "store") return res else: return res
def sponge(N:bytearray, d:int): """ Sponge construction for hash functions. N: Thing to hash \n d: size of hash wanted \n return bytearray """ def pad(N, r): iN = bm.bytes_to_int(N) lN = int.bit_length(iN) # Number of 0 to add b = (r - ((lN + 3) % r)) % r # Padding using the SHA-3 pattern 10*1: a 1 bit, followed by zero or more 0 bits (maximum r − 1) and a final 1 bit. op = ((iN | (1 << b + lN + 1)) << 1) ^ 1 return bm.multitype_to_bytes(op) r = 8 d = int(d/8) blocks = bm.splitBytes(pad(N, r*8), r) S = bytearray(16) # Absorbing for block in blocks: S[:r] = bm.byte_operation(S[:r], block) S = md5(S) O = bytearray() # Squeezing while len(O) < d: O += S[:r] S = md5(S) # Truncating with the desired length return O[:d]
def GCM(arr, encrypt=True, aad=""): ''' GCM is CTR mode with authentification of additional data (AAD) authenticated with multiplication in a Galois Field arr: array of bytearray of 8 bytes of data to encrypt/decrypt encrypt: boolean, true to encypt aad: string of additional authenticated data ''' if encrypt: iv = IV(arr) else: iv = IV_action(arr) # Integrity Check Balue icv = IV_action(arr) # Additional authenticated data (AAD), which is denoted as A A = [] if encrypt: if (aad != ""): aadc = aad.encode() if len(aadc) > 1 << 64: raise Exception("Too much AAD") A = bm.splitBytes(aadc, 8) A[-1] = bm.fill_byte(A[-1], 8) else: header = arr[0] epos = int.from_bytes(header, "big") A = arr[1:epos] arr = arr[epos:] # Encrypted message C = [] # 1 + α + α3 + α4 + α64 - 64 field polynomial p = int( "10000000000000000000000000000000000000000000000000000000000001111", 2) def bti(b): return int.from_bytes(b, "big") def lenb(i): return (len(i) * 8).to_bytes(8, "big") def GHASH64(H, A, C, X, i): n = len(C) m = len(A) if i <= m: # A1 = A[1-1] return gz2.poly_mult_mod_2( bti(bm.byte_operation(X, A[i - 1], "XOR")), H, p) elif i <= m + n: return gz2.poly_mult_mod_2( bti(bm.byte_operation(X, C[i - m - 1], "XOR")), H, p) elif i == m + n + 1: return gz2.poly_mult_mod_2( bti( bm.byte_operation( gz2.poly_mult_mod_2( bti(bm.byte_operation(X, lenb(A), "XOR")), H, p).to_bytes(8, "big"), lenb(C), "XOR")), H, p) H = bti(kasu.kasumi(b'\x00' * 8)) Y = GHASH64(H, b'', [iv], b'\x00', 1).to_bytes(8, "big") E0 = kasu.kasumi(Y) n = len(arr) m = len(A) # equivalent of CTR mode for i in range(n): config.WATCH_PERCENTAGE = (((n * 2 + m + 1) - ((n * 2 + m + 1) - i)) / (n * 2 + m + 1)) * 100 exTime = time.time() # treats the rightmost 32bits of its argument as a nonnegative integer with the least significant bit on the right, and increments this value modulo 2^32 Y = Y[:4] + ( (int.from_bytes(Y[-4:], "big") + 1) % 1 << 32).to_bytes(4, "big") E = kasu.kasumi(Y) C.append(bm.byte_operation(arr[i], E, "XOR")) config.WATCH_GLOBAL_CIPHER += time.time() - exTime config.WATCH_BLOC_CIPHER = config.WATCH_GLOBAL_CIPHER / (i + 1) config.WATCH_BLOC_KASUMI = config.WATCH_GLOBAL_KASUMI / (i + 1) res = C # plaintext is in C when we decrypt, me must replace interaction with the ciphertext if not encrypt: C = arr # first init of X = GHASH64(i=0) = b'\x00' X = b'\x00' for i in range(n + m + 1): config.WATCH_PERCENTAGE = (((n * 2 + m + 1) - ((n * 2 + m + 1) - (i + n))) / (n * 2 + m + 1)) * 100 exTime = time.time() X = GHASH64(H, A, C, X, i + 1).to_bytes(8, "big") config.WATCH_GLOBAL_CIPHER += time.time() - exTime config.WATCH_BLOC_CIPHER = config.WATCH_GLOBAL_CIPHER / (i + 1) icvc = bm.byte_operation(E0, X, "XOR") if not encrypt: if icv != icvc: print( "\nWARNING: INTEGRITY CHECK CONTROL INCORRECT, AAD HAVE BEEN MODIFIED !!" ) if encrypt: IV_action(res, icvc, "store") # Adding the IV to the encrypted data IV_action(res, iv, "store") header = (1 + len(A)).to_bytes(8, "big") res = [header] + A + res return res