Skip to content

GHASH

GHASH

  • Used for the tag in GCM algorithm

Implementation

import os
from cryptopals_lib import fixedlen_xor, to_blocks, bytes_to_int, int_to_bytes

class GMAC():
	def __init__(self, authentication_key):
		self.length = 16
		self.authentication_key = authentication_key

	def mult_Galios_Feild(self, y):
		"""Multiply two polynomials in GF(2^m)/g(w)
		   g(w) = w^128 + w^7 + w^2 + w + 1
		   (operands and result bits reflected)"""
		temp_key = bytes_to_int(self.authentication_key)
		y = bytes_to_int(y)
		z = 0
		#print(temp_key,y,z)
		while y & ((1<<128)-1):
			if y & (1<<127):
				z ^= temp_key
			y <<= 1
			if temp_key & 1:
				temp_key = (temp_key>>1)^(0xe1<<120)
			else:
				temp_key >>= 1
		return z

	def xor_Mult_with_key(self, p, q):
		test = fixedlen_xor(p,q)
		test = self.mult_Galios_Feild(test)
		test = int_to_bytes(test).rjust(self.length, b'\x00')
		return test

	def gLen(self, s):
		#Get Byte length * 8
		return (len(s) << 3).to_bytes(2, byteorder="big")

	def digest(self, additional_authenticated_data, input_data):
		output = b"\x00"*16

		#Pad additional_authenticated_data
		additional_authenticated_data_padded = additional_authenticated_data + bytes((self.length-len(additional_authenticated_data)%self.length)%self.length)

		#Pad Input Data
		input_data_padded = input_data + bytes((self.length-len(input_data)%self.length)%self.length)

		#For each block of Padded additional_authenticated_data xor and mult with the auth key
		for aad_block in to_blocks(additional_authenticated_data_padded, self.length):
			output = self.xor_Mult_with_key(output, aad_block)

		#For each block of Padded input_data xor and mult with the auth key
		for input_block in to_blocks(input_data_padded, self.length):
			output = self.xor_Mult_with_key(output, input_block)

		#Also XOR and mult with the length of the data
		len_input = self.gLen(additional_authenticated_data) + self.gLen(input_data)
		return self.xor_Mult_with_key(output, len_input.rjust(self.length, b'\x00'))


if __name__ == '__main__':
	gmac = GMAC(os.urandom(16))
	message = b"This is a testMessage"

	output = gmac.digest(b"\x00"*16, message)

	print("GMAC({},{}) = {}".format(gmac.authentication_key, message, output))


	#Assert from web.mit.edu/freebsd/head/contrib/wpa/src/crypto/aes-gcm.c

Attacks

Cycling Attacks

https://eprint.iacr.org/2011/202.pdf