def dbl(s): """ The SIV 'doubling' operation on a 16 octet input string """ assert len(s) == 16 d = string_to_int(s) if d & 0x80000000000000000000000000000000: # xor only if high bit set d = ((d << 1) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) ^ 0x87 else: d = (d << 1) return int_to_string(d, padto=16)
def dbl(s): """ The SIV 'doubling' operation on a 16 octet input string """ assert len(s)==16 d = string_to_int(s) if d & 0x80000000000000000000000000000000: # xor only if high bit set d = ((d<<1) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) ^ 0x87 else: d = (d<<1) return int_to_string(d, padto=16)
def siv_encrypt(key, pt, ad_list): """ """ blksize=16 # AES block size keysize = len(key)/2 # SIV key is two keys of equal size for CMAC and CTR key1 = key[0:keysize] # leftmost half of key key2 = key[-keysize:] # rightmost half of key ad = ad_list + [pt] iv = s2v(key1, ad ) q = string_to_int(iv) & 0xffffffffffffffff7fffffff7fffffffL # clear 32nd and 64th bits m = (len(pt)+blksize-1)/blksize x = '' aes = AES.new(key2, AES.MODE_ECB) for i in range(m): x = x + aes.encrypt( int_to_string(q+i, padto=blksize) ) x = x[0:len(pt)] # trim x to leftmost to match plain text which may not be block aligned ct = xor(pt,x) return iv + ct # concatenate initialization vector and cipher text
def siv_encrypt(key, pt, ad_list): """ """ blksize = 16 # AES block size keysize = len( key) / 2 # SIV key is two keys of equal size for CMAC and CTR key1 = key[0:keysize] # leftmost half of key key2 = key[-keysize:] # rightmost half of key ad = ad_list + [pt] iv = s2v(key1, ad) q = string_to_int( iv) & 0xffffffffffffffff7fffffff7fffffffL # clear 32nd and 64th bits m = (len(pt) + blksize - 1) / blksize x = '' aes = AES.new(key2, AES.MODE_ECB) for i in range(m): x = x + aes.encrypt(int_to_string(q + i, padto=blksize)) x = x[0:len( pt )] # trim x to leftmost to match plain text which may not be block aligned ct = xor(pt, x) return iv + ct # concatenate initialization vector and cipher text
def subkey(key, CIPH=AES): """ CMAC subkey generation """ ciph = CIPH.new(key) block_size = ciph.block_size assert block_size == 16 # only 128 bit blocks (16 octet) supported el = string_to_int( ciph.encrypt('\x00'*block_size) ) if el & 0x80000000000000000000000000000000 == 0: k1 = (el<<1) else: # xor only if high bit set k1 = ((el<<1) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) ^ 0x87 if k1 & 0x80000000000000000000000000000000 == 0: k2 = (k1<<1) else: # xor only if high bit set k2 = ((k1<<1) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) ^ 0x87 k1 = int_to_string(k1) k2 = int_to_string(k2) return k1, k2
def subkey(key, CIPH=AES): """ CMAC subkey generation """ ciph = CIPH.new(key) block_size = ciph.block_size assert block_size == 16 # only 128 bit blocks (16 octet) supported el = string_to_int(ciph.encrypt('\x00' * block_size)) if el & 0x80000000000000000000000000000000 == 0: k1 = (el << 1) else: # xor only if high bit set k1 = ((el << 1) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) ^ 0x87 if k1 & 0x80000000000000000000000000000000 == 0: k2 = (k1 << 1) else: # xor only if high bit set k2 = ((k1 << 1) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) ^ 0x87 k1 = int_to_string(k1) k2 = int_to_string(k2) return k1, k2
def siv_decrypt(key, encrypted_string, ad_list): """ """ blksize = 16 # AES block size iv = encrypted_string[:16] # leftmost 128 bits (16 octets) ct = encrypted_string[16:] keysize = len(key)/2 # SIV key is two keys of equal size for CMAC and CTR key1 = key[0:keysize] # leftmost half of key key2 = key[-keysize:] # rightmost half of key q = string_to_int(iv) & 0xffffffffffffffff7fffffff7fffffffL m = (len(ct)+blksize-1)/blksize x = '' aes = AES.new(key2, AES.MODE_ECB) for i in range(m): x = x + aes.encrypt( int_to_string(q+i, padto=blksize) ) x = x = x[0:len(ct)] pt = xor(ct,x) ad = ad_list + [pt] t = s2v( key1, ad ) if t == iv: return pt else: raise 'SIV Integrity Check Error'
def siv_decrypt(key, encrypted_string, ad_list): """ """ blksize = 16 # AES block size iv = encrypted_string[:16] # leftmost 128 bits (16 octets) ct = encrypted_string[16:] keysize = len( key) / 2 # SIV key is two keys of equal size for CMAC and CTR key1 = key[0:keysize] # leftmost half of key key2 = key[-keysize:] # rightmost half of key q = string_to_int(iv) & 0xffffffffffffffff7fffffff7fffffffL m = (len(ct) + blksize - 1) / blksize x = '' aes = AES.new(key2, AES.MODE_ECB) for i in range(m): x = x + aes.encrypt(int_to_string(q + i, padto=blksize)) x = x = x[0:len(ct)] pt = xor(ct, x) ad = ad_list + [pt] t = s2v(key1, ad) if t == iv: return pt else: raise 'SIV Integrity Check Error'