CSS-cipher/main.py
2024-04-21 15:28:24 +02:00

53 lines
1.7 KiB
Python

#!/usr/bin/env python3
from random import randint
from math import log2
class lfsr(object):
def __init__(self, state, taps):
self.state = state
self.taps = taps
# getters and setters (private attributes)
def get_state(self):
return self.__state
def set_state(self, value):
self.__state = value
state = property(fget=get_state, fset=set_state, doc="lfsr state (current bits value in lfsr)")
def get_taps(self):
return self.__taps
def set_taps(self, valeur):
self.__taps = valeur
taps = property(fget=get_taps, fset=set_taps, doc="lfsr taps (bit positions affecting next state)")
def shift(self):
'''
calculate next state and return the output bit
'''
feedback = sum(self.state[tap] for tap in self.taps) % 2
output = self.state[-1]
self.state = [feedback] + self.state[:-1]
return output
def test_lfsr17():
key = [randint(0, 1) for _ in range(16)] # first 16 bits
key.append(1) # prevent initial state from being {0}^17
taps = [16-0, 16-14]
lfsr17 = lfsr(key, taps)
states = [lfsr17.state]
for _ in range(2**17-2):
lfsr17.shift()
states.append(lfsr17.state)
sorted_states = sorted(states, key=lambda x: tuple(x))
for i in range(2**17-2):
if sorted_states[i] == sorted_states[i+1]: # compare each state with the next state in the sorted list, if 2 states are identical they should be next to each other
print(f'state {sorted_states[i]} appears at least 2 times')
return False
n_state = len(sorted_states)
n_state_log = log2(n_state+1)
print(f'all {n_state} = 2^({n_state_log})-1 states are different')
return True
test_lfsr17()