/// <summary> /// Reverse 64 bits of keystream into possible cipher states /// Variation mentioned in the paper. Somewhat optimized version /// </summary> /// <param name="ks2"></param> /// <param name="ks3"></param> /// <returns></returns> public static List <Crypto1State> LfsrRecovery64(uint ks2, uint ks3) { var oks = new byte[32]; var eks = new byte[32]; var hi = new byte[32]; var low = 0u; var win = 0u; var table = new uint[1 << 16]; var statelist = new List <Crypto1State>(); for (var i = 30; i >= 0; i -= 2) { oks[i >> 1] = ks2.BeBit(i); oks[16 + (i >> 1)] = ks3.BeBit(i); } for (var i = 31; i >= 0; i -= 2) { eks[i >> 1] = ks2.BeBit(i); eks[16 + (i >> 1)] = ks3.BeBit(i); } for (var i = 0xfffffu; (int)i >= 0; i--) { if (Filter(i) != oks[0]) { continue; } var tail = 0; table[tail] = i; for (var j = 1; tail >= 0 && j < 29; j++) { ExtendTableSimple(table, ref tail, oks[j]); } if (tail < 0) { continue; } for (var j = 0; j < 19; ++j) { low = low << 1 | EvenParity32(i & S1[j]); } for (var j = 0; j < 32; ++j) { hi[j] = EvenParity32(i & T1[j]); } for (; tail >= 0; --tail) { for (var j = 0; j < 3; j++) { table[tail] = table[tail] << 1; table[tail] |= EvenParity32((i & C1[j]) ^ (table[tail] & C2[j])); if (Filter(table[tail]) != oks[29 + j]) { goto continue2; } } for (var j = 0; j < 19; j++) { win = win << 1 | EvenParity32(table[tail] & S2[j]); } win ^= low; for (var j = 0; j < 32; ++j) { win = win << 1 ^ hi[j] ^ EvenParity32(table[tail] & T2[j]); if (Filter(win) != eks[j]) { goto continue2; } } table[tail] = table[tail] << 1 | EvenParity32(LF_POLY_EVEN & table[tail]); var s = new Crypto1State() { Odd = table[tail] ^ EvenParity32(LF_POLY_ODD & win), Even = win }; statelist.Add(s); continue2 :; } } return(statelist); }
public Crypto1(Crypto1State state) { _state = state; }
public Crapto1(Crypto1State state) : base(state) { }