LFSR Class

Author @ Nikesh Bajaj Version : 1.0.7 Contact: n.bajaj@qmul.ac.uk

—–changelog——————- first created : Date: 22 Oct 2017 Updated on : 29 Apr 2021 (version:1.0.6)

: fixed bugs (1) not counting first outbit correctly (2) Exception in info method

: added test properties (1) Balance (2) Runlength (3) Autocorrelation

: improved functionalities : added Viz function : added A5/1 and Geffe Generator

Updated on03 Jan 2023 (version:1.0.7)

: Added Galois Configuration for LFSR : fixed bugs, improved documentation

class pylfsr.pylfsr.LFSR[source]

Linear Feedback Shift Register

class LFSR(fpoly=[5,2],initstate=’ones’,verbose=False)

Parameters

fpolyList, optional (default=[5,2])

Feedback polynomial, it has to be primitive polynomial of GF(2) field, for valid output of LFSR

Example: for 5-bit LFSR, fpoly=[5,2], [5,3], [5,4,3,2], etc

: for M-bit LFSR fpoly = [M,…]

to get the list of feedback polynomials check method ‘get_fpolyList’ or check Refeferece: Ref: List of some primitive polynomial over GF(2)can be found at http://www.partow.net/programming/polynomials/index.html http://www.ams.org/journals/mcom/1962-16-079/S0025-5718-1962-0148256-1/S0025-5718-1962-0148256-1.pdf http://poincare.matf.bg.ac.rs/~ezivkovm/publications/primpol1.pdf

initstatebinary np.array (row vector) or str =’ones’ or ‘random’, optional (default = ‘ones’))

Initial state vector of LFSR. initstate can not be all zeros.

default =’ones’

Initial state is intialized with ones and length of register is equal to degree of feedback polynomial

if state=’rand’ or ‘random’

Initial state is intialized with random binary sequence of length equal to degree of feedback polynomial

if passed as list or numpy array

initstate = [1,1,0,0,1]

Theoretically the length initial state vector should be equal to order of polynomial (M), however, it can easily be bigger than that which is why all the validation of state vector and fpoly allows bigger length of state vector, however small state vector will raise an error.

counter_start_zero: bool (default = True), whether to start counter with 0 or 1. If True, initial outbit is

set to -1, so is feedbackbit, until first .next() clock is excecuted. This initial output is not stacked in seq. The output sequence should be same, in anycase, for example if you need run 10 cycles, using runKCycle(10) methed.

verboseboolean, optional (default=False)

if True, state of LFSR will be printed at every cycle(iteration)

conf: str {‘fibonacci’, ‘galois’}, default conf=’fibonacci’

: configuration mode of LFSR, either fabonacci or galoisi. : Example of 16-bit LFSR:

seq_bit_index: int, index of shift register for output sequence. Default=-1, which means the last register

: seq_bit_index can varies from -M to M-1,for M-bit LFSR. For example 5-bit LFSR, seq_bit_index=-5,-4,-3,-2,-1, 0, 1, 2, 3, 4 : seq_bit_index=-1, means output sequence is taken out from last Register, -2, second last,

Attributes

countint

Count the cycle, starts with 0 if counter_start_zero True, else starts with 1

seqnp.array shape =(count,)

Output sequence stored in seq since first cycle if -1, no cycle has been excecuted, count=0 when counter_start_zero is True else last bit of initial state

outbitbinary bit

Current output bit, Last bit of current state if -1, no cycle has been excecuted, count =0, when counter_start_zero is True

feedbackbitbinary bit

if -1, no cycle has been excecuted, count =0, when counter_start_zero is True

Mint

length of LFSR, M-bit LFSR

expectedPeriodint (also saved as T)

Expected period of sequence if feedback polynomial is primitive and irreducible (as per reference) period will be 2^M -1

Tint (also saved as expectedPeriod)

Expected period of sequence if feedback polynomial is primitive and irreducible (as per reference) period will be 2^M -1

feedpolystr

feedback polynomial

Methods

Clocking (running LFSR)::
  • next() : running one cycle

  • runKCycle(k) : running k cycles

  • runFullPeriod(): running a full period of cylces

Deprecated methods::
  • runFullCycle() :

  • set() : set fpoly and initialstate

  • changeFpoly(newfpoly) : change fpoly

  • change_conf(conf) : change configuration

Setters::
  • reset() :reset to initial settings

  • set_fpoly(fpoly) : change/set fpoly

  • set_conf(conf) : change/set configuration

  • set_state(state) : change/set state

  • set_seq_bit_index(bit_index) : change/set seq_bit_index

Getters::
  • getFullPeriod() : get a period

  • get_fPoly() : get feedback polynomial

  • get_initState() : get initial state

  • get_currentState() : get current state

  • getState() : get current state as string

  • get_outputSeq() : get output sequence

  • getSeq() : get output sequence as string

  • get_period() : get period

  • get_expectedPeriod() : get expected period

  • get_count() : get counter

Testing Properties
  • test_properties() : Test all the properties for a valid LFSR

  • balance_property(p) : Test Balance property for a given sequence p

  • runlength_property(p): Test Runlength property for a given sequence p

  • autocorr_property(p) : Test Autocorrelation property for a given sequence p

  • test_p(p) :Test three properties for a given sequence p

Displaying::
  • info(): Display all the attribuates of LFSR

  • Viz() : Display LFSR as a figure with a current state of LSFR with feedback polynomials and given configuration

Examples::

# For more detailed and updated examples, please check - https://lfsr.readthedocs.io/ #——————————————————- >>> import numpy as np >>> from pylfsr import LFSR

## Example ## 5 bit LFSR with x^5 + x^2 + 1 >>> L = LFSR() #default fpoly=[5,2], initstate=’ones’ >>> L = LFSR(fpoly=[5,2], initstate=’ones’)

### run one cycle >>> L.next() 1

### run 10 cycles >>> L.runKCycle(10) array([1, 1, 1, 1, 0, 0, 1, 1, 0, 1])

### run one period of cycles #>>> L.runFullCycle() # Depreciated >>> L.runFullPeriod() # doctest: +NORMALIZE_WHITESPACE array([1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0,

1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1])

## Displaying Info >>> L.info() 5 bit LFSR with feedback polynomial x^5 + x^2 + 1 Expected Period (if polynomial is primitive) = 31 Current :

State : [1 1 1 1 1] Count : 0 Output bit : -1 feedback bit : -1

## Displaying Info with print >>>print(L) LFSR ( x^5 + x^2 + 1) ================================================== initstate = [1. 1. 1. 1. 1.] fpoly = [5, 2] conf = fibonacci order = 5 expectedPeriod = 31 seq_bit_index = -1 count = 1 state = [0 1 1 1 1] outbit = 1 feedbackbit = 0 seq = [1] counter_start_zero = True

## Displaying Info with repr >>>repr(L) “LFSR(‘fpoly’=[5, 2], ‘initstate’=ones,’conf’=fibonacci, ‘seq_bit_index’=-1,’verbose’=False, ‘counter_start_zero’=True)”

>>> L.info()  
5 bit LFSR with feedback polynomial  x^5 + x^2 + 1
Expected Period (if polynomial is primitive) =  31
Current :
 State        :  [0 0 1 0 0]
 Count        :  42
 Output bit   :  1
 feedback bit :  0
 Output Sequence 111110011010010000101011101100011111001101

## Example ## 5-bit LFSR with custom state vector and feedback polynomial >>> state = np.array([0,0,0,1,0]) >>> fpoly = [5,4,3,2] >>> L1 = LFSR(fpoly=fpoly,initstate =state, verbose=True) >>> L1.info() # doctest: +NORMALIZE_WHITESPACE 5 bit LFSR with feedback polynomial x^5 + x^4 + x^3 + x^2 + 1 Expected Period (if polynomial is primitive) = 31 Current :

State : [0 0 0 1 0] Count : 0 Output bit : -1 feedback bit : -1

### run 10000 cycles >>> tempseq = L.runKCycle(10000) # generate 10000 bits from current state

### verbosity ON >>>state = np.array([0,0,0,1,0]) >>>fpoly = [5,4,3,2] >>>L1 = LFSR(fpoly=fpoly,initstate=state, verbose=True) >>> tempseq = L1.runKCycle(10) S: [0 0 0 1 0] S: [1 0 0 0 1] S: [1 1 0 0 0] S: [1 1 1 0 0] S: [0 1 1 1 0] S: [1 0 1 1 1] S: [1 1 0 1 1] S: [1 1 1 0 1] S: [1 1 1 1 0] S: [1 1 1 1 1] >>> tempseq array([0, 1, 0, 0, 0, 1, 1, 1, 0, 1])

## Example ## TO visualize the process with 3-bit LFSR, with default counter_start_zero = True >>> state = [1,1,1] >>> fpoly = [3,2] >>> L = LFSR(initstate=state,fpoly=fpoly,counter_start_zero=True) >>> print(‘count state outbit seq’) >>> print(‘-’*50) >>> for _ in range(15): >>> print(L.count,L.state,’’,L.outbit,L.seq,sep=’ ‘) >>> L.next() >>> print(‘-’*50) >>> print(‘Output: ‘,L.seq) count state outbit seq ————————————————– 0 [1 1 1] -1 [-1] 1 [0 1 1] 1 [1] 2 [0 0 1] 1 [1 1] 3 [1 0 0] 1 [1 1 1] 4 [0 1 0] 0 [1 1 1 0] 5 [1 0 1] 0 [1 1 1 0 0] 6 [1 1 0] 1 [1 1 1 0 0 1] 7 [1 1 1] 0 [1 1 1 0 0 1 0] 8 [0 1 1] 1 [1 1 1 0 0 1 0 1] 9 [0 0 1] 1 [1 1 1 0 0 1 0 1 1] 10 [1 0 0] 1 [1 1 1 0 0 1 0 1 1 1] 11 [0 1 0] 0 [1 1 1 0 0 1 0 1 1 1 0] 12 [1 0 1] 0 [1 1 1 0 0 1 0 1 1 1 0 0] 13 [1 1 0] 1 [1 1 1 0 0 1 0 1 1 1 0 0 1] 14 [1 1 1] 0 [1 1 1 0 0 1 0 1 1 1 0 0 1 0] ————————————————– Output: [1 1 1 0 0 1 0 1 1 1 0 0 1 0 1]

## Example ## To visualize the process with 3-bit LFSR, with counter_start_zero = False >>> state = [1,1,1] >>> fpoly = [3,2] >>> L = LFSR(initstate=state,fpoly=fpoly,counter_start_zero=False) >>> print(‘count state outbit seq’) >>> print(‘-’*50) >>> for _ in range(15): >>> print(L.count,L.state,’’,L.outbit,L.seq,sep=’ ‘) >>> L.next() >>> print(‘-’*50) >>> print(‘Output: ‘,L.seq) count state outbit seq ————————————————– 1 [1 1 1] 1 [1] 2 [0 1 1] 1 [1 1] 3 [0 0 1] 1 [1 1 1] 4 [1 0 0] 0 [1 1 1 0] 5 [0 1 0] 0 [1 1 1 0 0] 6 [1 0 1] 1 [1 1 1 0 0 1] 7 [1 1 0] 0 [1 1 1 0 0 1 0] 8 [1 1 1] 1 [1 1 1 0 0 1 0 1] 9 [0 1 1] 1 [1 1 1 0 0 1 0 1 1] 10 [0 0 1] 1 [1 1 1 0 0 1 0 1 1 1] 11 [1 0 0] 0 [1 1 1 0 0 1 0 1 1 1 0] 12 [0 1 0] 0 [1 1 1 0 0 1 0 1 1 1 0 0] 13 [1 0 1] 1 [1 1 1 0 0 1 0 1 1 1 0 0 1] 14 [1 1 0] 0 [1 1 1 0 0 1 0 1 1 1 0 0 1 0] ————————————————– Output: [1 1 1 0 0 1 0 1 1 1 0 0 1 0 1]

## Example ## To visualize LFSR L.Viz(show=False, show_labels=False,title=’R1’)

## Galois Configuration L = LFSR(initstate=’ones’,fpoly=[5,3],conf=’galois’) L.Viz()

## Example ## Change/Set conf in between >>>L1 = LFSR(initstate=’ones’,fpoly=[5,3],conf=’fibonacci’) >>>L1.set_fpoly(fpoly=[5,3]) >>>L1.set_state(state=[1,1,0,0,1]) >>>L1.set_conf(conf=’galois’)

## Example ## 23 bit LFSR with custum state and feedback polynomial

>>> fpoly = [23,19]
>>> L1 = LFSR(fpoly=fpoly,initstate ='ones', verbose=False)
>>> L1.info()
23 bit LFSR with feedback polynomial  x^23 + x^19 + 1
Expected Period (if polynomial is primitive) =  8388607
Current :
 State        :  [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
 Count        :  0
 Output bit   :  -1
 feedback bit :  -1
>>> seq = L1.runKCycle(100)
>>> seq
array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
   1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
   1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
   1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0,
   1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1])
>>> #L.changeFpoly(newfpoly =[23,21])
>>> L.set_fpoly(fpoly =[23,21])
>>> seq1 = L.runKCycle(20)

## Example ## testing the properties >>> state = [1,1,1,1,0] >>> fpoly = [5,3] >>> L = LFSR(initstate=state,fpoly=fpoly) >>> L.info() 5 bit LFSR with feedback polynomial x^5 + x^3 + 1 Expected Period (if polynomial is primitive) = 31 Current :

State : [1 1 1 1 0] Count : 0 Output bit : -1 feedback bit : -1

>>>result = L.test_properties(verbose=1) 1. Periodicity ——————

  • Expected period = 2^M-1 = 31

  • Pass?: True

2. Balance Property

  • Number of 1s = Number of 0s+1 (in a period): (N1s,N0s) = (16, 15)

  • Pass?: True

3. Runlength Property

  • Number of Runs in a period should be of specific order, e.g. [4,2,1,1]

  • Runs: [8 4 2 1 1]

  • Pass?: True

4. Autocorrelation Property

  • Autocorrelation of a period should be noise-like, specifically, 1 at k=0, -1/m everywhere else

  • Pass?: True

>>> p = L.getFullPeriod()
>>> p
array([0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0,
   0, 1, 0, 0, 1, 0, 1, 1, 0])
>>> L.balance_property(p.copy())
(True, (16, 15))
>>> L.runlength_property(p.copy())
(True, array([8, 4, 2, 1, 1]))
>>> L.autocorr_property(p.copy())[0]
True

## Example 7 ## testing the properties for non-primitive polynomial >>> state = [1,1,1,1,0] >>> fpoly = [5,1] >>> L = LFSR(initstate=state,fpoly=fpoly) >>> result = L.test_properties(verbose=1) 1. Periodicity ——————

  • Expected period = 2^M-1 = 31

  • Pass?: False

2. Balance Property

  • Number of 1s = Number of 0s+1 (in a period): (N1s,N0s) = (17, 14)

  • Pass?: False

3. Runlength Property

  • Number of Runs in a period should be of specific order, e.g. [4,2,1,1]

  • Runs: [10 2 1 1 2]

  • Pass?: False

4. Autocorrelation Property

  • Autocorrelation of a period should be noise-like, specifically, 1 at k=0, -1/m everywhere else

  • Pass?: False

Viz(ax=None, show=True, fs=25, show_labels=False, title='', title_loc='left', box_color='lightblue', alpha=0.5, output_arrow_color='C2', output_arrow_style='h', show_outseq=True)[source]

Display LFSR

ax: axis to plot, if None, new axis will be created, (default None) show: if True, plt.show() will be excecuted, (default True) fs: fontsize (default 25) show_label: if true, will display names title: str, title of figure, default ‘’, title_loc, alignment of title, ‘left’, ‘right’, ‘center’, (default ‘left’)

__init__(fpoly=[5, 2], initstate='ones', conf='fibonacci', seq_bit_index=-1, verbose=False, counter_start_zero=True)[source]
autocorr_property(p, plot=False)[source]

Autocorrelation Property: For sequence of period T of LSFR with valid feedback polynomial, the autocorrelation is a noise like, that is, 1 with zero (or T) lag (shift), -1/T (almost zero) else.

unlike usual, for binary, the correlation value between two sequence of same length bx, by is computed as follow; match = sum(bx == by) (number of mataches) mismatch = sum(bx!= by) (number of mismatches) ‘’ rxy = (match - mismatch)/ length(bx) ‘’

Parameters

p: array-like, a sequence of a period from LFSR

plot: bool (default False), if True, it will plot the autocorrelation function,

which will require matplotlib library. Turn it of if matplotlib is not installed

Returns

result: bool, True if seq p satisfies Autocorrelation Property else False (shift, rxx): tuple of sequence of shift corresponding autocorrelation values

balance_property(p)[source]

Balance Property: In a period of LFSR with a valid feedback polynomial, the number of 1s should be equal to number of 0s +1

‘’ N1s == N0s + 1 ‘’

Test balance property for a given full period of seq, p.

Parameters

p: array-like, a sequence of a period from LFSR

Returns

result: bool, True if seq p satisfies Balance Property else False (N1s, N0s): tuple, number of 1s and number of 0s

changeFpoly(newfpoly, reset=False, enforce=False)[source]

NOTE: Will be deprecated in future version, use “set_fpoly” instead

Changing Feedback polynomial : Useful to change feedback polynomial in between as in A5/1 stream cipher

Parameters

newfpolylist like, [5,4,2,1]

changing the feedback polynomial

resetboolean default=False

if True, reset all the Parameters: count and seq etc …. if False, leave the LFSR as it is only change the feedback polynomial for further use, as used in ‘Enhancement of A5/1: Using variable feedback polynomials of LFSR’

enforce: bool (defaule=False)

: test if new polynomial is for same LFSR or not

check()[source]

Check if - degree of feedback polynomial <= length of LFSR >=1 - given intistate of LFSR is correct - configuration is valid - output sequence bit index

check_state()[source]

check if current state vector is valid

getFullPeriod()[source]

Get a seq of a full period from LSFR, by executing next() method T times. The current state of LFSR is used to generate T bits.

Calling this function also update the count, current state and output sequence of main LFSR object

Returns

seq (T bits), binary output sequence of last T bits

static get_Ifpoly(fpoly)[source]

Get image of feebback polynomial Get the image of primitive polynomial Parameters ———- fpoly: polynomial as list e.g. [5,2] for x^5 + x^2 + 1

: should be a valid primitive polynomial

Returns

ifpoly: polynomial as list e.g. [5,3] for x^5 + x^3 + 1

get_count()[source]

get counter value

get_currentState()[source]

get current state of LFSR

get_expectedPeriod()[source]

get period of sequence

get_fPoly()[source]

get feedback polynomial

get_fpolyList(m=None)[source]

Get the list of primitive polynomials as feedback polynomials for m-bit LFSR. Only list of primary primitive polynomials are retuned, not full list (half list), since for each primary primitive polynomial an image polymial can be computed using ‘get_Ifpoly’ method

Parameters

m: 1<int<32, if None, list of feedback polynomials for 1 < m < 32 is return as a dictionary

Returns

fpoly_list: list of polynomial if m is not None else a dictionary

get_initState()[source]

get initial state of LFSR

get_outputSeq()[source]

get output sequence as array

get_period()[source]

get period of sequence

info()[source]

Display the information about LFSR with current state of variables

next(verbose=False)[source]

Run one cycle on LFSR with given feedback polynomial and update the count, state, feedback bit, output bit and seq

Returns

output bit : binary

reset()[source]

Reseting LFSR to its initial state and count

runFullCycle()[source]

NOTE: Will be deprecated in future version due to misnomer, use “runFullPeriod” instead

Run a full cycle (T = 2^M-1) on LFSR from current state

Returns

seq : binary output sequence since start: shape = (count,)

runFullPeriod(verbose=False)[source]

Run a full period of cycles (T = 2^M-1) on LFSR from current state

Returns

seq : binary output sequence since start: shape = (count,)

runKCycle(k, verbose=False)[source]

Run k cycles and update all the Parameters

Parameters

k : int

Returns

tempseq : shape =(k,), output binary sequence of k cycles

runlength_property(p, verbose=0)[source]

Run Length Property: In a period of LSFR with valid feedback polynomial, the number of runs of different length are in specific order.

‘’ number of (M-k) bit runs = ⌈ 2^(k-1) ⌉ , for k = 0 to M-1 ‘’

where ⌈ ⌉ is a ceiling function That is, for M bit LFSR,

  • number of M bit runs : 1

  • number of (M-1) bit runs : 1

  • number of (M-2) bit runs : 2

  • number of (M-3) bit runs : 4

… so on

Parameters

p: array-like, a sequence of a period from LFSR

Returns

result: bool, True if seq p satisfies Run Length Property else False runs: list, list of runs

set(fpoly, state='ones', enforce=False)[source]

NOTE: Will be deprecated in future version, use “set_fpoly” and “set_state” instead

Set feedback polynomial and state

Parameters

fpolylist

feedback polynomial like [5,4,3,2]

statenp.array, like np.array([1,0,0,1,1])
default =’ones’

Initial state is intialized with ones and length of register is equal to degree of feedback polynomial

if state=’rand’

Initial state is intialized with random binary sequence of length equal to degree of feedback polynomial

enforce: bool (defaule=False)

: test if (1) new polynomial is for same LFSR or not (2) state vector is same length or not : Setting enforce=True, allows the change of feedback polynomial from M-bit to K-bit LFSR, for example changing from 5-bit to 3-bit etc

in that case, make sure to change initial state vector accordingly

set_conf(conf, reset=False)[source]

Set Configuration

Change configuration, useful to change configuration in between

Parameters

conf: str {‘fibonacci’, ‘galois’}, default conf=’fibonacci’

resetboolean default=False

if True, reset all the Parameters: count and seq etc …. if False, leave the LFSR as it is only change configuration

set_fpoly(fpoly, reset=False, enforce=False)[source]

Set Feedback polynomial

Useful to change feedback polynomial in between as in A5/1 stream cipher, to increase the complexity

Parameters

fpolylist like, [5,4,2,1], should be same

changing the feedback polynomial

resetboolean default=False

if True, reset all the Parameters: count and seq etc …. if False, leave the LFSR as it is only change the feedback polynomial for further use, as used in ‘Enhancement of A5/1: Using variable feedback polynomials of LFSR’

enforce: bool (defaule=False)

: test if new polynomial is for same LFSR or not : Setting enforce=True allows to change feedback polynomial from M-bit to any other bit, given that state vector is changed accordingly. : check details of initstate in help(LFSR) doc

set_seq_bit_index(bit_index)[source]

Set Output bit index: for output sequence as index

seq_bit_index: int in range from -M to M-1

set_state(state, return_state=False, enforce=False)[source]

Set Current state

Parameters

state: str, list or np.array

: if str state=’ones’ or state=’random’ : if list or np.array, it should be binary and length equal to max of polynomial degree

return_state: bool, if True, return state vector. Useful when state=’random’ is passed, to keep track of newly inilized state vector enforce: bool (defaule=False)

: test if new state vector has same length as old one :

test_p(p, verbose=1)[source]
Test all the three properties for seq p :
  1. Balance Property

  2. Runlegth Property

  3. Autocorrelation Property

Parameters

p : array-like, a sequence of a period from LFSR verbose = 0 : no printing details

= 1 : print details = 2 : print and plot more details

Returns

result: bool, True if all three are satisfied else False

update()[source]

Updatating order, period and feedpoly string

pylfsr.pylfsr.PlotLFSR(state, fpoly, conf='fibonacci', seq='', ob=None, fb=None, fs=25, ax=None, show_labels=False, title='', title_loc='left', box_color='lightblue', alpha=0.5)[source]

—– Plot LFSR —- state: current state of LFSR fpoly: feedback polynomial of LFSR seq: str, output sequence ob: output bit fb: feedback bit ax: axis to plot, if None, new axis will be created, (default None)

show: if True, plt.show() will be excecuted, (default True) fs: fontsize (default 25) show_label: if true, will display names title: str, title of figure, default ‘’, title_loc, alignment of title, ‘left’, ‘right’, ‘center’, (default ‘left’) box_color: color of register box, default=’lightblue’

pylfsr.pylfsr.dispLFSR(state, fpoly, conf='fibonacci', seq='', out_bit_index=-1, ob=None, fb=None, fs=25, ax=None, show_labels=False, title='', title_loc='left', box_color='lightblue', alpha=0.5, output_arrow_color='C0', output_arrow_style='h')[source]

—– Display LFSR —-

parameters

state: current state of LFSR fpoly: feedback polynomial of LFSR seq: str, output sequence ob: output bit fb: feedback bit ax: axis to plot, if None, new axis will be created, (default None) show: if True, plt.show() will be excecuted, (default True) fs: fontsize (default 25) show_label: if true, will display names title: str, title of figure, default ‘’, title_loc, alignment of title, ‘left’, ‘right’, ‘center’, (default ‘left’) box_color: color of register box, default=’lightblue’

Genarators

Sequence Generators based on LFSR

Author @ Nikesh Bajaj Date: 03 Jan 2023 Version : 1.0.7 Github : https://github.com/Nikeshbajaj/Linear_Feedback_Shift_Register Contact: n.bajaj@qmul.ac.uk

class pylfsr.seq_generators.A5_1[source]

A5/1 GSM Stream Cipher

#TODO

1.doc 2.check the output sequence

Ref: https://en.wikipedia.org/wiki/A5/1

Example

import numpy as np import matplotlib.pyplot as plt from pylfsr import A5_1

A5 = A5_1(key=’random’) print(‘key: ‘,A5.key) A5.R1.Viz(title=’R1’) A5.R2.Viz(title=’R2’) A5.R3.Viz(title=’R3’)

print(‘key: ‘,A5.key) print() print(‘count cbit clk R1_R2_R3 outbit seq’) print(‘-’*80) for _ in range(15):

print(A5.count,A5.getCbits(),A5.clock_bit,A5.getLastbits(),A5.outbit,A5.getSeq(),sep=’ ‘) A5.next()

print(‘-’*80) print(‘Output: ‘,A5.seq)

A5.runKCycle(1000) A5.getSeq()

__init__(key='random', k1='ones', k2='random', k3='ones', counter_start_zero=True)[source]
next()[source]

#TODO check the output sequence

runKCycle(k)[source]

Run k cycles and update all the Parameters

Parameters

k : int

Returns

tempseq : shape =(k,), output binary sequence of k cycles

class pylfsr.seq_generators.Geffe[source]

Geffe Generator

Combining K LFSR in non-linear manner linear complexity

Parameters

K+1 LFSRs

kLFSR_list: list of K LFSR, output of one of these is choosen at any time, depending on cLFSR cLFSR: clocking LFSR

K should be power of 2. 2,4,8,… 128

Ref: Schneier, Bruce. Applied cryptography: protocols, algorithms, and source code in C. john wiley & sons, 2007. Chaper 16

Example

import numpy as np import matplotlib.pyplot as plt from pylfsr import Geffe, LFSR

kLFSR = [LFSR(initstate=’random’) for _ in range(8)] cLFSR = LFSR(initstate=’random’)

GG = Geffe(kLFSR_list=kLFSR, cLFSR=cLFSR)

print(‘key: ‘,GG.getState()) print() for _ in range(50):

print(GG.count,GG.m_count,GG.outbit_k,GG.sel_k,GG.outbit,GG.getSeq(),sep=’ ‘) GG.next()

GG.runKCycle(1000) GG.getSeq()

__init__(kLFSR_list, cLFSR)[source]
runKCycle(k)[source]

Run k cycles and update all the Parameters

Parameters

k : int

Returns

tempseq : shape =(k,), output binary sequence of k cycles

class pylfsr.seq_generators.Geffe3[source]

Geffe Generator

Combining three LFSR in non-linear manner linear complexity: If the LFSRs have lengths n1, n2, and n3, respectively, then the linear complexity of the generator is = (n1 + 1)n2 + n1n3

output bit at any time is

b = (r1 ^ r2) • ((¬ r1) ^ r3)

where r1,r2,r3 are the outbit of three LFSRs respectively

Ref: Schneier, Bruce. Applied cryptography: protocols, algorithms, and source code in C. john wiley & sons, 2007. Chaper 16

__init__(R1, R2, R3)[source]
runKCycle(k)[source]

Run k cycles and update all the Parameters

Parameters

k : int

Returns

tempseq : shape =(k,), output binary sequence of k cycles

Utilities

Utilities for LFSR

Author @ Nikesh Bajaj Date: 03 Jan 2023 Version : 1.0.7 Github : https://github.com/Nikeshbajaj/Linear_Feedback_Shift_Register Contact: n.bajaj@qmul.ac.uk

pylfsr.utils.deprecated(reason)[source]

This is a decorator which can be used to mark functions as deprecated. It will result in a warning being emitted when the function is used.

pylfsr.utils.get_Ifpoly(fpoly)[source]

Get image of feebback polynomial Get the image of primitive polynomial Parameters ———- fpoly: polynomial as list e.g. [5,2] for x^5 + x^2 + 1

: should be a valid primitive polynomial

Returns

ifpoly: polynomial as list e.g. [5,3] for x^5 + x^3 + 1

pylfsr.utils.get_fpolyList(m=None)[source]

Get the list of primitive polynomials as feedback polynomials for m-bit LFSR. Only list of primary primitive polynomials are retuned, not full list (half list), since for each primary primitive polynomial an image polymial can be computed using ‘get_Ifpoly’ method

Parameters

m: 1<int<32, if None, list of feedback polynomials for 1 < m < 32 is return as a dictionary

Returns

fpoly_list: list of polynomial if m is not None else a dictionary

pylfsr.utils.lempel_ziv_complexity(seq)[source]

Lempel-Ziv Complexity. It is defined as the number of different patterns exists in a given stream.

As an example: s = ‘1001111011000010’ patterns ==> 1, 0, 01, 11, 10, 110, 00, 010 #patterns = 8

pylfsr.utils.lempel_ziv_patterns(seq)[source]

Lempel-Ziv patterns. It is defined as a set of different patterns exists in a given sequence.

As an example: s = ‘1001111011000010’ patterns ==> 1, 0, 01, 11, 10, 110, 00, 010