/// <summary> /// Set the Maze Key and get the Maze Key to apply it to the encryption algorithm /// </summary> /// <returns></returns> public BigInteger SetMazeKey() { Stopwatch SW_Timer = Stopwatch.StartNew(); //Step 5/6 - Walking the Maze int beginPosX = equK(Username, (BigInteger)Username.IntValue(), PrivateSalt.IntValue()).IntValue() % (this.MazeSize.Width / 2) + 3; int beginPosY = equK(Password, (BigInteger)Username.IntValue(), PrivateSalt.IntValue()).IntValue() % (this.MazeSize.Height / 2) + 3; bool Back = false; int WalkSize = 30; this.MazeKey = new BigInteger(); for (int i = 0, j = 1, k = 3, p = 7; i < MazeCount; i++, j++, k += 2, p += 5) { Maze maze = new Maze(); maze.GenerateMaze(MazeSize.Width, MazeSize.Height, (int)((Username.data[j % (Username.dataLength - 1)] + Password.data[k % (Password.dataLength - 1)]) ^ PrivateSalt.data[i % (PrivateSalt.dataLength - 1)]), 0); beginPosX = Math.Abs(beginPosX); beginPosY = Math.Abs(beginPosY); int endPosX = Math.Abs(beginPosX + (Back ? -WalkSize : WalkSize)); int endPosY = Math.Abs(beginPosY + (Back ? -WalkSize : WalkSize)); ArrayList list = maze.Solve(beginPosX, beginPosY, endPosX, endPosY, MazeSteps * 2); if (list.Count < 10) { throw new Exception("The Maze is too small"); } BigInteger tempCalc = new BigInteger(); for (int s = 0; s < MazeSteps; s++) { cCellPosition cell = list[s % list.Count] as cCellPosition; int temp2 = cell.x * cell.y; if (temp2 == 0) { continue; } tempCalc = equK(Username, temp2, s) ^ PrivateSalt.IntValue() ^ tempCalc; this.MazeKey += tempCalc; beginPosX = cell.x; beginPosY = cell.y; } Back = !Back; } PatchKey(ref this._mazeKey); SW_Timer.Stop(); return(this.MazeKey); }
public byte[] GetEncryptedPublicKey() { byte[] key = MazeKey.getBytes(); byte[] salt = PrivateSalt.getBytes(); //also step 7 but here we encrypt it byte[] publicData = new byte[this.PublicKeyData.Length]; Array.Copy(this.PublicKeyData, publicData, publicData.Length); //copy the public key data so the original will be still in memory GetWopEncryption().Encrypt(publicData, 0, publicData.Length); return(publicData); }
public Stream RecalculatePrivateKey(Stream PrivateKeyData) { if (!PrivateKeyData.CanSeek || !PrivateKeyData.CanWrite) { throw new Exception("Unable to write to the stream"); } BigInteger InversedInt = 0; try { InversedInt = PrivateSalt.modInverse(this.Username); } catch (Exception ex) { SysLogger.Log(ex.Message, SysLogType.Error); //no inverse could be found InversedInt = PrivateSalt + this.Username; } PatchKey(ref InversedInt); //patch the key to randomize the 0xFF bytes byte[] inverseData = InversedInt.getBytes(); int temp = InversedInt.IntValue(); for (int j = 0; j <= 1; j++) { for (int i = 4 * j; i < PrivateKeyData.Length; i += 8) { byte[] tempData = new byte[4]; int read = 0; PrivateKeyData.Position = i; if ((read = PrivateKeyData.Read(tempData, 0, tempData.Length)) <= 0) { break; } int TempKey = BitConverter.ToInt32(tempData, 0) ^ temp; PrivateKeyData.Position -= read; PrivateKeyData.Write(BitConverter.GetBytes(TempKey), 0, read); temp = TempKey; } } return(PrivateKeyData); }
/// <summary> /// Patches the key by removing the 255 in the beginning of the key /// </summary> /// <param name="key"></param> private void PatchKey(ref BigInteger key) { byte[] _key = key.getBytes(); int count = 0; for (int i = 0; i < _key.Length; i++, count++) { if (_key[i] != 255) { break; } } if (count > 0) { byte[] tempKey = new byte[count]; new FastRandom(PrivateSalt.IntValue()).NextBytes(tempKey); Array.Copy(tempKey, _key, tempKey.Length); key = new BigInteger(_key); } }
public WopEx GetWopEncryption() { byte[] key = MazeKey.getBytes(); byte[] salt = PrivateSalt.getBytes(); return(GetWopEncryption(key, salt)); }