public static List <Crypto1State> LfsrRecovery32(uint ks2, uint @in) { var oks = 0u; var eks = 0u; for (var i = 31; i >= 0; i -= 2) { oks = oks << 1 | ks2.BeBit(i); } for (var i = 30; i >= 0; i -= 2) { eks = eks << 1 | ks2.BeBit(i); } var odd = new uint[sizeof(uint) << 21]; var even = new uint[sizeof(uint) << 21]; var statelist = new List <Crypto1State>(1 << 18); var oddTail = 0; var evenTail = 0; for (var i = 1u << 20; (int)i >= 0; --i) { if (Filter(i) == (oks & 1)) { odd[++oddTail] = i; } if (Filter(i) == (eks & 1)) { even[++evenTail] = i; } } for (var i = 0; i < 4; i++) { ExtendTableSimple(odd, ref oddTail, (oks >>= 1) & 1); ExtendTableSimple(even, ref evenTail, (eks >>= 1) & 1); } @in = (@in >> 16 & 0xff) | (@in << 16) | (@in & 0xff00); Recover(odd, oddTail, oks, even, evenTail, eks, 11, statelist, @in << 1); return(statelist); }
public uint Crypto1Word(uint @in = 0, bool isEncrypted = false) { uint ret = 0; for (int i = 0; i < 32; ++i) { ret |= (uint)Crypto1Bit(@in.BeBit(i), isEncrypted) << (i ^ 24); } return(ret); }
public uint LfsrRollbackWord(uint @in = 0, bool isEncrypted = false) { uint ret = 0; for (var i = 31; i >= 0; --i) { ret |= (uint)LfsrRollbackBit(@in.BeBit(i), isEncrypted) << (i ^ 24); } return(ret); }
/// <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); }