def __call__(self, M, mode = "ECB"): r""" INPUT: - ``M`` - a StringMonoidElement - ``mode`` - ignored (default: 'ECB') EXAMPLES:: sage: FF = FiniteField(2) sage: P.<x> = PolynomialRing(FF) sage: LFSR = LFSRCryptosystem(FF) sage: IS_1 = [ FF(a) for a in [0,1,0,1,0,0,0] ] sage: e1 = LFSR((x^7 + x + 1,IS_1)) sage: IS_2 = [ FF(a) for a in [0,0,1,0,0,0,1,0,1] ] sage: e2 = LFSR((x^9 + x^3 + 1,IS_2)) sage: E = ShrinkingGeneratorCryptosystem() sage: e = E((e1,e2)) sage: B = BinaryStrings() sage: m = B.encoding("THECATINTHEHAT") sage: c = e(m) sage: c.decoding() "t\xb6\xc1'\x83\x17\xae\xc9ZO\x84V\x7fX" sage: e(e(m)) == m True sage: m.decoding() 'THECATINTHEHAT' """ B = self.domain() # = plaintext_space = ciphertext_space if not isinstance(M, StringMonoidElement) and M.parent() == B: raise TypeError("Argument M (= %s) must be a string in the plaintext space." % M) (e1, e2) = self.key() MStream = M._element_list g1 = e1.connection_polynomial() n1 = g1.degree() IS_1 = e1.initial_state() g2 = e2.connection_polynomial() n2 = g2.degree() IS_2 = e2.initial_state() k = 0 N = len(M) n = max(n1,n2) CStream = [] while k < N: r = max(N-k,2*n) KStream = lfsr_sequence(g1.list(), IS_1, r) DStream = lfsr_sequence(g2.list(), IS_2, r) for i in range(r-n): if DStream[i] != 0: CStream.append(int(MStream[k]+KStream[i])) k += 1 if k == N: break IS_1 = KStream[r-n-1:r-n+n1] IS_2 = DStream[r-n-1:r-n+n2] return B(CStream)
def __call__(self, M, mode = "ECB"): r""" Generate key stream from the binary string ``M``. INPUT: - ``M`` - a StringMonoidElement - ``mode`` - ignored (default: 'ECB') EXAMPLE:: sage: k = GF(2) sage: P.<x> = PolynomialRing( k ) sage: LFSR = LFSRCryptosystem( k ) sage: e = LFSR((x^2+x+1,[k(0), k(1)])) sage: B = e.domain() sage: m = B.encoding('The cat in the hat.') sage: e(m) 00111001110111101011111001001101110101011011101000011001100101101011001000000011100101101010111100000101110100111111101100000101110101111010111101000011 """ B = self.domain() # = plaintext_space = ciphertext_space if not isinstance(M, StringMonoidElement) and M.parent() == B: raise TypeError("Argument M (= %s) must be a string in the plaintext space." % M) (poly, IS) = self.key() n = B.ngens() # two for binary strings N = len(M) Melt = M._element_list Kelt = lfsr_sequence(poly.list(), IS, N) return B([ (Melt[i]+int(Kelt[i]))%n for i in range(N) ])