tomdodd4598

Untitled

Jun 2nd, 2021
767
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using System;
  2. using System.Numerics;
  3. using System.Security.Cryptography;
  4. using System.Text;
  5.  
  6. namespace CipherTest
  7. {
  8.     public class Cipher
  9.     {
  10.         const long KeySize = 64;
  11.         const long NonceSize = 8;
  12.         const long BlockSize = 8;
  13.         const long RoundCount = 16;
  14.  
  15.         // <Hermione, Don't You Think On It For One Minute>
  16.         static readonly ulong[] Hagrid = { 0x3C4865726D696F6E, 0x652C20446F6E2774, 0x20596F7520546869, 0x6E6B204F6E204974, 0x20466F72204F6E65, 0x204D696E7574653E };
  17.  
  18.         static readonly Encoding UTF = Encoding.UTF8;
  19.  
  20.         private readonly RNGCryptoServiceProvider provider;
  21.         private readonly ulong[] key;
  22.  
  23.         public Cipher(RNGCryptoServiceProvider provider, BigInteger key)
  24.         {
  25.             this.provider = provider;
  26.             byte[] keyBytes = new byte[KeySize], inBytes = key.ToByteArray(true);
  27.             Array.Copy(inBytes, keyBytes, Math.Min(inBytes.Length, KeySize));
  28.             this.key = Array.ConvertAll(keyBytes, Convert.ToUInt64);
  29.         }
  30.  
  31.         public void QR(ref ulong a, ref ulong b, ref ulong c, ref ulong d)
  32.         {
  33.             b ^= (a + d).RL(25);
  34.             c ^= (b + a).RL(23);
  35.             d ^= (c + b).RL(19);
  36.             a ^= (d + c).RL(46);
  37.         }
  38.  
  39.         public void Round(ulong[] table)
  40.         {
  41.             QR(ref table[0], ref table[4], ref table[8], ref table[12]);
  42.             QR(ref table[5], ref table[9], ref table[13], ref table[1]);
  43.             QR(ref table[10], ref table[14], ref table[2], ref table[6]);
  44.             QR(ref table[15], ref table[3], ref table[7], ref table[11]);
  45.  
  46.             QR(ref table[0], ref table[1], ref table[2], ref table[3]);
  47.             QR(ref table[5], ref table[6], ref table[7], ref table[4]);
  48.             QR(ref table[10], ref table[11], ref table[8], ref table[9]);
  49.             QR(ref table[15], ref table[12], ref table[13], ref table[14]);
  50.         }
  51.  
  52.         public ulong KeyBlock(ulong block, ulong nonce)
  53.         {
  54.             ulong[] table = {
  55.                 Hagrid[0],  Hagrid[1],  Hagrid[2],  Hagrid[3],
  56.                 key[0],     key[1],     key[2],     key[3],
  57.                 key[4],     key[5],     key[6],     key[7],
  58.                 block,      nonce,      Hagrid[4],  Hagrid[5]
  59.             };
  60.             ulong original = table[block & 15];
  61.  
  62.             for (int i = 0; i < RoundCount; i += 2)
  63.             {
  64.                 Round(table);
  65.             }
  66.  
  67.             return original + table[block & 15];
  68.         }
  69.  
  70.         public byte[] TransformBlock(byte[] bytes, long i, ulong block, long size, ulong nonce)
  71.         {
  72.             byte[] inputBytes = new byte[BlockSize];
  73.             Array.Copy(bytes, i, inputBytes, 0, Math.Min(BlockSize, size - i));
  74.             return BitConverter.GetBytes(KeyBlock(block, nonce) ^ BitConverter.ToUInt64(inputBytes));
  75.         }
  76.  
  77.         public string Encrypt(string input)
  78.         {
  79.             byte[] plain = UTF.GetBytes(input);
  80.             byte[] nonceBytes = new byte[NonceSize];
  81.             provider.GetBytes(nonceBytes);
  82.             ulong nonce = BitConverter.ToUInt64(nonceBytes);
  83.  
  84.             long length = plain.Length;
  85.             long size = length + NonceSize;
  86.             byte[] cipher = new byte[size];
  87.             Array.Copy(nonceBytes, cipher, NonceSize);
  88.  
  89.             ulong j = 0;
  90.             for (long i = 0; i < length; i += BlockSize, ++j)
  91.             {
  92.                 Array.Copy(TransformBlock(plain, i, j, length, nonce), 0, cipher, i + NonceSize, Math.Min(BlockSize, length - i));
  93.             }
  94.  
  95.             return Helpers.BytesToHex(cipher);
  96.         }
  97.  
  98.         public string Decrypt(string input)
  99.         {
  100.             byte[] bytes = Helpers.HexToBytes(input);
  101.             if (bytes == null || bytes.Length < NonceSize)
  102.             {
  103.                 return null;
  104.             }
  105.  
  106.             byte[] nonceBytes = new byte[NonceSize];
  107.             Array.Copy(bytes, nonceBytes, NonceSize);
  108.             ulong nonce = BitConverter.ToUInt64(nonceBytes);
  109.  
  110.             long size = bytes.Length - NonceSize;
  111.             byte[] cipher = new byte[size];
  112.             Array.Copy(bytes, NonceSize, cipher, 0, size);
  113.  
  114.             byte[] plain = new byte[size];
  115.  
  116.             ulong j = 0;
  117.             for (long i = 0; i < size; i += BlockSize, ++j)
  118.             {
  119.                 Array.Copy(TransformBlock(cipher, i, j, size, nonce), 0, plain, i, Math.Min(BlockSize, size - i));
  120.             }
  121.  
  122.             return UTF.GetString(plain);
  123.         }
  124.     }
  125. }
  126.  
RAW Paste Data