lab 4 - lfsrs (feb 21)

some helper code for this lab is in this file fivebit.py. here is a summary of the functions included in my code--not all of them are necessarily helpful for this lab:

here are also some pre-defined objects for you:

note: for the purposes of this lab, we will work with an n-bit string as a list of 0's and 1's (of type int). this is not the most efficient way to with bit strings, but it is convenient for us to (1) work with general n, and (2) doing arithmetic mod 2. in practice, you would do the latter with bits with bitwise operators

task 1: write a function xor(v,w), which returns the xor (addition mod 2) of 2 strings of the same length. if the strings do not consist of 0s and 1s or are not of the same length, return or print an error. test your code out on a few strings of 0s and 1s of the same length and at least one input of different lengths.

task 2: write a function lfsr(a, seed, N), where a and seed are strings of 0s and 1s of the same length (say n), and N is an integer at least as big as n. this function shoud return a list of length N of 0's and 1's which are the first N bits b[0], b[1], ... , b[N-1] of the lfsr with initial value seed and recurrence b[k] = a[0]b[k-n] + a[1]b[k-n+1] + ... a[n-1]b[k-1] (mod 2). test your function with coefficient lists a = [1,0,0], a = [1,0,1] and a = [1,1,1] with seed = [0,0,1]. what is the period of the resulting sequence in each case?

task 3: write a function printstates(a,seed,N) that prints out the first N states of the register for lfsr(a,seed,*). on each line, print out the state (n-bits where n=len(a) followed by the line number. e.g., printstates([1,1],[0,1],4) should return something like

0 1 | 0
1 1 | 1
1 0 | 2
0 1 | 3

(you may format your printout a bit differently if you prefer). then test this on the cases: (i) a = [1,1,0,0], seed = [1,1,0,0], N = 16, (ii) a = [1,1,0,0], seed = [1,0,1,0], N = 16 and (iii) a = [1,0,1,1,1], seed = [1,0,0,0,0], N = 32. what are the period lengths in each case?

task 4: write a function maxlfsrs(n) that returns a list of the coefficient lists (denote a in the previous task) for the maximal length n-bit lfsrs, i.e., those with period length 2^n-1 for a nonzero seed. determine how many maximal length lfsrs there are on n-bits for n = 2, 3, 4, 5, 6. compare this to the total number of n-bit lfsrs.

task 5: encrypt and decrypt the string text (included in the helper code file) by xoring with the lfsr with parameters a = [1,0,1,1,1], seed = [1,0,0,0,0]. do a frequency analysis of the resulting ciphertext to compare (qualitatively) if the frequency count is closer to a uniform distribution than for a shift or substitution cipher. note: the included functions for frequency counting only count letters, whereas now some of your ciphertext may include digits. you can count the number of times, say '3' occurs in a string s with the command s.count('3'). how do you think the distribution of frequency counts compares to that of a vigenere cipher of appropriate length? what security advantages, if any, does this scheme have over a vigenere cipher? (in particular, think about bits of data for the key (seed) and the period of the lfsr.) are there any apparent disadvantages?

lab 4 homework: complete the above tasks (due fri feb 28)



labs page
course home