using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections; namespace A5project { class A5Enc { private bool[] reg = new bool[19]; private bool[] reg2 = new bool[22]; private bool[] reg3 = new bool[23]; //, public A5Enc(bool[][] startState) { reg = startState[0]; reg2 = startState[1]; reg3 = startState[2]; } public A5Enc() { for (int i = 0; i < 19; i++) reg[i] = false; for (int i = 0; i < 22; i++) reg2[i] = false; for (int i = 0; i < 23; i++) reg3[i] = false; } // , A5 public void KeySetup(byte[] key, int[] frame) { for (int i = 0; i < 19; i++) reg[i] = false; for (int i = 0; i < 22; i++) reg2[i] = false; for (int i = 0; i < 23; i++) reg3[i] = false; BitArray KeyBits = new BitArray(key); BitArray FrameBits = new BitArray(frame); bool[] b = new bool[64]; for (int i = 0; i < 64; i++) { clockall(); reg[0] = reg[0] ^ KeyBits[i]; reg2[0] = reg2[0] ^ KeyBits[i]; reg3[0] = reg3[0] ^ KeyBits[i]; } for (int i = 0; i < 22; i++) { clockall(); reg[0] = reg[0] ^ FrameBits[i]; reg2[0] = reg2[0] ^ FrameBits[i]; reg3[0] = reg3[0] ^ FrameBits[i]; } for (int i = 0; i < 100; i++) { clock(); } } // , public void KeySetup(int[] frame) { BitArray FrameBits = new BitArray(frame); for (int i = 0; i < 22; i++) { clockall(); reg[0] = reg[0] ^ FrameBits[i]; reg2[0] = reg2[0] ^ FrameBits[i]; reg3[0] = reg3[0] ^ FrameBits[i]; } for (int i = 0; i < 100; i++) { clock(); } } private void clock() { bool majority = ((reg[8] & reg2[10]) | (reg[8] & reg3[10]) | (reg2[10] & reg3[10])); if (reg[8] == majority) clockone(reg); if (reg2[10] == majority) clocktwo(reg2); if (reg3[10] == majority) clockthree(reg3); } // private bool[] clockone(bool[] RegOne) { bool temp = false; for (int i = RegOne.Length - 1; i > 0; i--) { if (i == RegOne.Length - 1) temp = RegOne[13] ^ RegOne[16] ^ RegOne[17] ^ RegOne[18]; RegOne[i] = RegOne[i - 1]; if (i == 1) RegOne[0] = temp; } return RegOne; } private bool[] clocktwo(bool[] RegTwo) { bool temp = false; for (int i = RegTwo.Length - 1; i > 0; i--) { if (i == RegTwo.Length - 1) temp = RegTwo[20] ^ RegTwo[21]; RegTwo[i] = RegTwo[i - 1]; if (i == 1) RegTwo[0] = temp; } return RegTwo; } private bool[] clockthree(bool[] RegThree) { bool temp = false; for (int i = RegThree.Length - 1; i > 0; i--) { if (i == RegThree.Length - 1) temp = RegThree[7] ^ RegThree[20] ^ RegThree[21] ^ RegThree[22]; RegThree[i] = RegThree[i - 1]; if (i == 1) RegThree[0] = temp; } return RegThree; } private void clockall() { reg = clockone(reg); reg2 = clocktwo(reg2); reg3 = clockthree(reg3); } // 114 public bool[] A5() { bool[] FirstPart = new bool[114]; for (int i = 0; i < 114; i++) { clock(); FirstPart[i] = (reg[18] ^ reg2[21] ^ reg3[22]); } return FirstPart; } // 228 public bool[] A5(bool AsFrame) { bool[] FirstPart = new bool[228]; for (int i = 0; i < 228; i++) { clock(); FirstPart[i] = (reg[18] ^ reg2[21] ^ reg3[22]); } return FirstPart; } public byte[] FromBoolToByte(bool[] key, bool lsb) { int bytes = key.Length / 8; if ((key.Length % 8) != 0) bytes++; byte[] arr2 = new byte[bytes]; int bitIndex = 0, byteIndex = 0; for (int i = 0; i < key.Length; i++) { if (key[i]) { if(lsb) arr2[byteIndex] |= (byte)(((byte)1) << (7 - bitIndex)); else arr2[byteIndex] |= (byte)(((byte)1) << (bitIndex)); } bitIndex++; if (bitIndex == 8) { bitIndex = 0; byteIndex++; } } return arr2; } } }
private byte[] A5Encyptor(byte[] msg,byte[] key) { A5Enc a5 = new A5Enc(); int[] frame = new int[1]; bool[] resbits = new bool[msg.Count]; int framesCount = msg.Length / 228; if ((msgbits.Length % 228) != 0) framesCount++; for (int i = 0; i < framesCount; i++) { frame[0] = i; a5.KeySetup(key, frame); bool[] KeyStream = a5.A5(true); for (int j = 0; j < 228; j++) { resbits[i * 228 + j] = msgbits[i * 228 + j] ^ KeyStream[j]; } } return a5.FromBoolToByte(resbits, false); }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections; namespace A5project { class A5attack { private double[] factorials = new double[150]; // Pr(cl1,cl2,cl3 v) private double PinVth(int cl1, int cl2, int cl3, int v) { double y=0; double x = 0; double z = 0; double w = 0; if((v - (v - cl1) - (v - cl2) - (v - cl3))>=0) y=factorials[v - (v - cl1) - (v - cl2) - (v - cl3)]; else y=1; if ((v - cl1) >= 0) x = factorials[v - cl1]; else x = 1; if ((v - cl3) >= 0) z = factorials[v - cl3]; else z = 1; if ((v - cl2) >= 0) w = factorials[v - cl2]; else w = 1; double a = factorials[v] / (x * factorials[v - (v - cl1)]); double b = factorials[v - (v - cl1)] / (w * factorials[v - (v - cl1) - (v - cl2)]); double c = factorials[v - (v - cl1) - (v - cl2)] / (z * y); double d = Math.Pow(4, v); return (a * b * c) / d; } private double factorial(int x) { double result=1; for (int i = x; i > 1; i--) result = result * i; return result; } private bool[] reg = new bool[19]; private bool[] reg2 = new bool[22]; private bool[] reg3 = new bool[23]; // , public void KeySetup(int[] frame) { for (int i = 0; i < 19; i++) reg[i] = false; for (int i = 0; i < 22; i++) reg2[i] = false; for (int i = 0; i < 23; i++) reg3[i] = false; BitArray FrameBits = new BitArray(frame); for (int i = 0; i < 22; i++) { clockall(); reg[0] = reg[0] ^ FrameBits[i]; reg2[0] = reg2[0] ^ FrameBits[i]; reg3[0] = reg3[0] ^ FrameBits[i]; } } // private void clock() { bool majority = ((reg[8] & reg2[10]) | (reg[8] & reg3[10]) | (reg2[10] & reg3[10])); if (reg[8] == majority) clockone(reg); if (reg2[10] == majority) clocktwo(reg2); if (reg3[10] == majority) clockthree(reg3); } private bool[] clockone(bool[] RegOne) { bool temp = false; for (int i = RegOne.Length - 1; i > 0; i--) { if (i == RegOne.Length - 1) temp = RegOne[13] ^ RegOne[16] ^ RegOne[17] ^ RegOne[18]; RegOne[i] = RegOne[i - 1]; if (i == 1) RegOne[0] = temp; } return RegOne; } private bool[] clocktwo(bool[] RegTwo) { bool temp = false; for (int i = RegTwo.Length - 1; i > 0; i--) { if (i == RegTwo.Length - 1) temp = RegTwo[20] ^ RegTwo[21]; RegTwo[i] = RegTwo[i - 1]; if (i == 1) RegTwo[0] = temp; } return RegTwo; } private bool[] clockthree(bool[] RegThree) { bool temp = false; for (int i = RegThree.Length - 1; i > 0; i--) { if (i == RegThree.Length - 1) temp = RegThree[7] ^ RegThree[20] ^ RegThree[21] ^ RegThree[22]; RegThree[i] = RegThree[i - 1]; if (i == 1) RegThree[0] = temp; } return RegThree; } private void clockall() { reg = clockone(reg); reg2 = clocktwo(reg2); reg3 = clockthree(reg3); } // , cl1, cl2 cl3 public bool Oj(int cl1,int cl2, int cl3) { for (int i = 0; i < cl1; i++) { clockone(reg); } for (int i = 0; i < cl2; i++) { clocktwo(reg2); } for (int i = 0; i < cl3; i++) { clockthree(reg3); } return (reg[18] ^ reg2[21] ^ reg3[22]); } // , XOR public double Pj(int cl1, int cl2, int cl3, int j, bool[] frame) { double result = 0; double rightPart = 0; int[] framenumb=new int[1]{j}; KeySetup(framenumb); bool[] tempReg = new bool[19]; bool[] tempReg2 = new bool[22]; bool[] tempReg3 = new bool[23]; Array.Copy(reg, tempReg, 19); Array.Copy(reg2, tempReg2, 22); Array.Copy(reg3, tempReg3, 23); bool FramesBit = Oj(cl1, cl2, cl3); for (int i = 100; i < 100 + 50; i++) { Array.Copy(tempReg, reg, 19); Array.Copy(tempReg2, reg2, 22); Array.Copy(tempReg3, reg3, 23); double temp = PinVth(cl1, cl2, cl3, i); rightPart += temp; if((FramesBit^frame[i-100])==false) temp=temp*1; else temp=0; result += temp; } result = result + ((1 - rightPart) / 2); return result; } // , cl1, cl2, cl3 0. >0 0 // , 1 public double LikehoodRatio(int cl1, int cl2, int cl3, bool[] keystream) { double result = 0; for (int i = 0; i < keystream.Length/228; i++) { bool[] temp=new bool[228]; Array.Copy(keystream,i*228,temp,0,228); double x=Pj(cl1, cl2, cl3, i, temp); result = result + Math.Log(( x/ (1 - x))); } return result; } public bool FindKeyBit(int cl1, int cl2, int cl3, bool[] keystream) { for (int i = 0; i < 150; i++) factorials[i] = factorial(i); if (LikehoodRatio(cl1, cl2, cl3, keystream) >= 0) return false; else return true; } // public bool[][] checkSol(byte[] first, byte[] second, byte[] third) { byte[] newFirst = new byte[3]; newFirst[0] = first[0]; newFirst[1] = second[0]; newFirst[2] = third[0]; byte[] newSecond = new byte[3]; newSecond[0] = first[1]; newSecond[1] = second[1]; newSecond[2] = third[1]; byte[] newThird = new byte[3]; newThird[0] = first[2]; newThird[1] = second[2]; newThird[2] = third[2]; bool[] firstArr1 = new BitArray(newFirst).Cast<bool>().ToArray().Reverse().ToArray(); bool[] firstArr = new bool[19]; Array.Copy(firstArr1, 5, firstArr, 0, 19); bool[] secondArr1 = new BitArray(newSecond).Cast<bool>().ToArray().Reverse().ToArray(); bool[] secondArr = new bool[22]; Array.Copy(secondArr1, 2, secondArr, 0, 22); bool[] thirdArr1 = new BitArray(newThird).Cast<bool>().ToArray().Reverse().ToArray(); bool[] thirdArr = new bool[23]; Array.Copy(thirdArr1, 1, thirdArr, 0, 23); for (int i = 0; i < 101; i++) { BackClockone(firstArr); } for (int i = 0; i < 101; i++) { BackClocktwo(secondArr); } for (int i = 0; i < 101; i++) { BackClockthree(thirdArr); } bool[][] result = new bool[3][]; result[0] = firstArr; result[1] = secondArr; result[2] = thirdArr; return result; } private void BackClockone(bool[] RegOne) { bool temp = false; for (int i = 0; i < RegOne.Length-1; i++) { if (i == 0) temp = RegOne[0]; RegOne[i] = RegOne[i+1]; if (i == (RegOne.Length-2)) RegOne[RegOne.Length - 1] = temp ^ RegOne[13] ^ RegOne[16] ^ RegOne[17]; } } private void BackClocktwo(bool[] RegTwo) { bool temp = false; for (int i = 0; i < RegTwo.Length-1; i++) { if (i == 0) temp = RegTwo[0]; RegTwo[i] = RegTwo[i + 1]; if (i == (RegTwo.Length-2)) RegTwo[RegTwo.Length - 1] = temp ^ RegTwo[20]; } } private void BackClockthree(bool[] RegThree) { bool temp = false; for (int i = 0; i < RegThree.Length-1; i++) { if (i == 0) temp = RegThree[0]; RegThree[i] = RegThree[i + 1]; if (i == (RegThree.Length-2)) RegThree[RegThree.Length - 1] = temp ^ RegThree[7] ^ RegThree[20] ^ RegThree[21]; } } } }
private bool[] attack() { bool[] keypart=new bool[512]; int count = 0; A5attack tryattack = new A5attack(); for(int i=79; i<87;i++) for(int j=79; j<87; j++) for (int k = 79; k < 87; k++) { bool temp=tryattack.FindKeyBit(i, j, k, keystream); int time = finish - start; keypart[count] = temp; count++; } return keypart; }
Private void checkSolution() { A5attack LetsAttack = new A5attack(); int[] testframe = new int[1] { 0 }; bool[][] startState = LetsAttack.checkSol(first, second, third); A5Enc a5check = new A5Enc(startState); bool[] TempFrame = new bool[228]; a5check.KeySetup(testframe); TempFrame = a5check.A5(true); for (int l = 0; l < 228; l++) { find = true; if (keystream[l] != TempFrame[l]) { find = false; break; } } }
Source: https://habr.com/ru/post/186838/
All Articles