Linear feedback shift register (LFSR) sequence commands¶
Stream ciphers have been used for a long time as a source of pseudo-random number generators.
S. Golomb [Go1967] gives a list of three statistical properties that a sequence of
numbers
In the case where
Assume
balance:
.low autocorrelation:
(For sequences satisfying these first two properties, it is known that
must hold.)proportional runs property: In each period, half the runs have length
, one-fourth have length , etc. Moreover, there are as many runs of ’s as there are of ’s.
A general feedback shift register is a map
where
for some given constants
Example of an LFSR: Let
be given polynomials in
We can compute a recursion formula which allows us to rapidly compute the
coefficients of
The coefficients of
Example: For instance, if
then
The coefficients of
The sequence of berlekamp_massey.py
.
AUTHORS:
David Joyner (2005-11-24): initial creation.
Timothy Brock (2005-11): added
lfsr_sequence
with code modified from Python Cookbook, http://aspn.activestate.com/ASPN/Python/Cookbook/Timothy Brock (2006-04-17): added
lfsr_autocorrelation
andlfsr_connection_polynomial
.
- sage.crypto.lfsr.lfsr_autocorrelation(L, p, k)[source]¶
INPUT:
L
– a periodic sequence of elements of ZZ or GF(2); must have lengthp
– the period ofk
– integer between and
OUTPUT: autocorrelation sequence of
EXAMPLES:
sage: F = GF(2) sage: o = F(0) sage: l = F(1) sage: key = [l,o,o,l]; fill = [l,l,o,l]; n = 20 sage: s = lfsr_sequence(key,fill,n) sage: lfsr_autocorrelation(s,15,7) 4/15 sage: lfsr_autocorrelation(s,int(15),7) 4/15
>>> from sage.all import * >>> F = GF(Integer(2)) >>> o = F(Integer(0)) >>> l = F(Integer(1)) >>> key = [l,o,o,l]; fill = [l,l,o,l]; n = Integer(20) >>> s = lfsr_sequence(key,fill,n) >>> lfsr_autocorrelation(s,Integer(15),Integer(7)) 4/15 >>> lfsr_autocorrelation(s,int(Integer(15)),Integer(7)) 4/15
F = GF(2) o = F(0) l = F(1) key = [l,o,o,l]; fill = [l,l,o,l]; n = 20 s = lfsr_sequence(key,fill,n) lfsr_autocorrelation(s,15,7) lfsr_autocorrelation(s,int(15),7)
- sage.crypto.lfsr.lfsr_connection_polynomial(s)[source]¶
INPUT:
s
– a sequence of elements of a finite field of even length
OUTPUT:
C(x)
– the connection polynomial of the minimal LFSR
This implements the algorithm in section 3 of J. L. Massey’s article [Mas1969].
EXAMPLES:
sage: F = GF(2) sage: F Finite Field of size 2 sage: o = F(0); l = F(1) sage: key = [l,o,o,l]; fill = [l,l,o,l]; n = 20 sage: s = lfsr_sequence(key,fill,n); s [1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0] sage: lfsr_connection_polynomial(s) x^4 + x + 1 sage: from sage.matrix.berlekamp_massey import berlekamp_massey sage: berlekamp_massey(s) x^4 + x^3 + 1
>>> from sage.all import * >>> F = GF(Integer(2)) >>> F Finite Field of size 2 >>> o = F(Integer(0)); l = F(Integer(1)) >>> key = [l,o,o,l]; fill = [l,l,o,l]; n = Integer(20) >>> s = lfsr_sequence(key,fill,n); s [1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0] >>> lfsr_connection_polynomial(s) x^4 + x + 1 >>> from sage.matrix.berlekamp_massey import berlekamp_massey >>> berlekamp_massey(s) x^4 + x^3 + 1
F = GF(2) F o = F(0); l = F(1) key = [l,o,o,l]; fill = [l,l,o,l]; n = 20 s = lfsr_sequence(key,fill,n); s lfsr_connection_polynomial(s) from sage.matrix.berlekamp_massey import berlekamp_massey berlekamp_massey(s)
Notice that
berlekamp_massey
returns the reverse of the connection polynomial (and is potentially must faster than this implementation).
- sage.crypto.lfsr.lfsr_sequence(key, fill, n)[source]¶
Create an LFSR sequence.
INPUT:
key
– list of finite field elements,fill
– the list of the initial terms of the LFSR sequence,n
– number of terms of the sequence that the function returns
OUTPUT:
The LFSR sequence defined by
for .EXAMPLES:
sage: F = GF(2); l = F(1); o = F(0) sage: F = GF(2); S = LaurentSeriesRing(F,'x'); x = S.gen() sage: fill = [l,l,o,l]; key = [1,o,o,l]; n = 20 sage: L = lfsr_sequence(key,fill,20); L [1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0] sage: from sage.matrix.berlekamp_massey import berlekamp_massey sage: g = berlekamp_massey(L); g x^4 + x^3 + 1 sage: (1)/(g.reverse()+O(x^20)) 1 + x + x^2 + x^3 + x^5 + x^7 + x^8 + x^11 + x^15 + x^16 + x^17 + x^18 + O(x^20) sage: (1+x^2)/(g.reverse()+O(x^20)) 1 + x + x^4 + x^8 + x^9 + x^10 + x^11 + x^13 + x^15 + x^16 + x^19 + O(x^20) sage: (1+x^2+x^3)/(g.reverse()+O(x^20)) 1 + x + x^3 + x^5 + x^6 + x^9 + x^13 + x^14 + x^15 + x^16 + x^18 + O(x^20) sage: fill = [l,l,o,l]; key = [l,o,o,o]; n = 20 sage: L = lfsr_sequence(key,fill,20); L [1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1] sage: g = berlekamp_massey(L); g x^4 + 1 sage: (1+x)/(g.reverse()+O(x^20)) 1 + x + x^4 + x^5 + x^8 + x^9 + x^12 + x^13 + x^16 + x^17 + O(x^20) sage: (1+x+x^3)/(g.reverse()+O(x^20)) 1 + x + x^3 + x^4 + x^5 + x^7 + x^8 + x^9 + x^11 + x^12 + x^13 + x^15 + x^16 + x^17 + x^19 + O(x^20)
>>> from sage.all import * >>> F = GF(Integer(2)); l = F(Integer(1)); o = F(Integer(0)) >>> F = GF(Integer(2)); S = LaurentSeriesRing(F,'x'); x = S.gen() >>> fill = [l,l,o,l]; key = [Integer(1),o,o,l]; n = Integer(20) >>> L = lfsr_sequence(key,fill,Integer(20)); L [1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0] >>> from sage.matrix.berlekamp_massey import berlekamp_massey >>> g = berlekamp_massey(L); g x^4 + x^3 + 1 >>> (Integer(1))/(g.reverse()+O(x**Integer(20))) 1 + x + x^2 + x^3 + x^5 + x^7 + x^8 + x^11 + x^15 + x^16 + x^17 + x^18 + O(x^20) >>> (Integer(1)+x**Integer(2))/(g.reverse()+O(x**Integer(20))) 1 + x + x^4 + x^8 + x^9 + x^10 + x^11 + x^13 + x^15 + x^16 + x^19 + O(x^20) >>> (Integer(1)+x**Integer(2)+x**Integer(3))/(g.reverse()+O(x**Integer(20))) 1 + x + x^3 + x^5 + x^6 + x^9 + x^13 + x^14 + x^15 + x^16 + x^18 + O(x^20) >>> fill = [l,l,o,l]; key = [l,o,o,o]; n = Integer(20) >>> L = lfsr_sequence(key,fill,Integer(20)); L [1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1] >>> g = berlekamp_massey(L); g x^4 + 1 >>> (Integer(1)+x)/(g.reverse()+O(x**Integer(20))) 1 + x + x^4 + x^5 + x^8 + x^9 + x^12 + x^13 + x^16 + x^17 + O(x^20) >>> (Integer(1)+x+x**Integer(3))/(g.reverse()+O(x**Integer(20))) 1 + x + x^3 + x^4 + x^5 + x^7 + x^8 + x^9 + x^11 + x^12 + x^13 + x^15 + x^16 + x^17 + x^19 + O(x^20)
F = GF(2); l = F(1); o = F(0) F = GF(2); S = LaurentSeriesRing(F,'x'); x = S.gen() fill = [l,l,o,l]; key = [1,o,o,l]; n = 20 L = lfsr_sequence(key,fill,20); L from sage.matrix.berlekamp_massey import berlekamp_massey g = berlekamp_massey(L); g (1)/(g.reverse()+O(x^20)) (1+x^2)/(g.reverse()+O(x^20)) (1+x^2+x^3)/(g.reverse()+O(x^20)) fill = [l,l,o,l]; key = [l,o,o,o]; n = 20 L = lfsr_sequence(key,fill,20); L g = berlekamp_massey(L); g (1+x)/(g.reverse()+O(x^20)) (1+x+x^3)/(g.reverse()+O(x^20))