Test Vector
Key=80000000000000000000
IV=00000000000000000000
Keystream=38EB86FF730D7A9CAF8DF13A4420540D
Key=00400000000000000000
IV=00000000000000000000
Keystream=61208D286BC1DC431171EDA5CAF79D95
Key=00002000000000000000
IV=00000000000000000000
Keystream=C8F9031DABF8DB03FF120D05512B5F24
Key=00000010000000000000
IV=00000000000000000000
Keystream=F7E523040E86EA2C46A2BE705BFC6259
Source Code
from collections import deque
from itertools import repeat
from sys import version_info
class Trivium:
def __init__(self, key, iv):
"""in the beginning we need to transform the key as well as
the IV.
Afterwards we initialize the state."""
self.state = None
self.counter = 0
self.key = key # self._setLength(key)
self.iv = iv # self._setLength(iv)
# Initialize state
# len 100
init_list = list(map(int, list(self.key)))
init_list += list(repeat(0, 20))
# len 84
init_list += list(map(int, list(self.iv)))
init_list += list(repeat(0, 4))
# len 111
init_list += list(repeat(0, 108))
init_list += list([1, 1, 1])
self.state = deque(init_list)
# Do 4 full cycles, drop output
for i in range(4*288):
self._gen_keystream()
def encrypt(self, message):
"""To be implemented"""
pass
def decrypt(self, cipher):
"""To be implemented"""
pass
def keystream(self):
"""output keystream
only use this when you know what you are doing!!"""
while self.counter < 2**64:
self.counter += 1
yield self._gen_keystream()
def _setLength(self, input_data):
"""we cut off after 80 bits, alternatively we pad these with
zeros."""
input_data = "{0:080b}".format(input_data)
if len(input_data) > 80:
input_data = input_data[:(len(input_data)-81):-1]
else:
input_data = input_data[::-1]
return input_data
def _gen_keystream(self):
"""this method generates triviums keystream"""
a_1 = self.state[90] & self.state[91]
a_2 = self.state[181] & self.state[182]
a_3 = self.state[292] & self.state[293]
t_1 = self.state[65] ^ self.state[92]
t_2 = self.state[168] ^ self.state[183]
t_3 = self.state[249] ^ self.state[294]
out = t_1 ^ t_2 ^ t_3
s_1 = a_1 ^ self.state[177] ^ t_1
s_2 = a_2 ^ self.state[270] ^ t_2
s_3 = a_3 ^ self.state[68] ^ t_3
self.state.rotate(1)
self.state[0] = s_3
self.state[100] = s_1
self.state[184] = s_2
return out
import sys
k1="0F62B5085BAE0154A7FA"
i1="288FF65DC42B92F960C7"
print "Key: "+k1
print "IV: "+i1
def main():
KEY = hex_to_bits(k1)[::-1]
IV = hex_to_bits(i1)[::-1]
trivium = Trivium(KEY, IV)
# Check python version
if version_info[0] == 2:
next_key_bit = trivium.keystream().next
elif version_info[0] == 3:
next_key_bit = trivium.keystream().__next__
else:
print("invalid python version")
return
for i in range(1):
keystream = []
for j in range(128):
keystream.append(next_key_bit())
print "Stream: "+bits_to_hex(keystream)
# Convert strings of hex to strings of bytes and back, little-endian
style
_allbytes = dict([("%02X" % i, i) for i in range(256)])
def _hex_to_bytes(s):
return [_allbytes[s[i:i+2].upper()] for i in range(0, len(s),
2)]
def hex_to_bits(s):
return [(b >> i) & 1 for b in _hex_to_bytes(s)
for i in range(8)]
def bits_to_hex(b):
return "".join(["%02X" % sum([b[i + j] << j for j in range(8)])
for i in range(0, len(b), 8)])
if __name__ == "__main__":
main()