Example #1
0
        private static double GetSolveAttemptsPerSecond(byte[] payload, EstimationAccuracy accuracy)
        {
            CashPack pack = Packer.Pack(payload, (ushort)(payload.Length * 8));

            Stopwatch watch = new Stopwatch();

            int decrypts = 0;

            watch.Start();

            byte[] currentKey = new byte[pack.Key.Length];
            Array.Copy(pack.Key, 0, currentKey, 0, pack.Key.Length);

            byte[] solveWorkspace = new byte[pack.Payload.Length];

            while (watch.ElapsedMilliseconds < ((uint)accuracy * 1000))
            {
                for (int i = 0; i < pack.Payload.Length; i++)
                {
                    solveWorkspace[i] = (byte)(pack.Payload[i] ^ currentKey[i]);
                }

                // IMPORTANT: Use HMAC instead of Checksum
                // This prevents you to do attacks where you can correlate known payloads
                // And a CashPack without ever solving it.
                using (HMACSHA512 sha = new HMACSHA512(currentKey))
                {
                    byte[] hash = sha.ComputeHash(solveWorkspace);

                    for (int i = 0; i < pack.Hash.Length; i++)
                    {
                        if (pack.Hash[i] != hash[i])
                        {
                            break;
                        }
                    }
                }

                // Increment key
                ulong keyAsNumber = BitHelper.KeyToNumber(currentKey, pack.BitDifficulty);
                BitHelper.SetLastBitNumberBytes(currentKey, keyAsNumber + 1, pack.BitDifficulty);

                decrypts++;
            }

            watch.Stop();

            return(decrypts / (watch.ElapsedMilliseconds / 1000d));
        }
Example #2
0
        /// <summary>
        /// Solves a CashPack in a single go. Only recommended to be used for very easy CashPacks that takes no more than a few minutes.
        /// </summary>
        /// <param name="pack">The CashPack to solve.</param>
        /// <returns>The solved plaintext payload.</returns>
        public static byte[] Solve(CashPack pack)
        {
            byte[] currentKey = new byte[pack.Key.Length];
            Array.Copy(pack.Key, 0, currentKey, 0, pack.Key.Length);

            byte[] solveWorkspace = new byte[pack.Payload.Length];


            while (true)
            {
                for (int i = 0; i < pack.Payload.Length; i++)
                {
                    solveWorkspace[i] = (byte)(pack.Payload[i] ^ currentKey[i]);
                }

                // IMPORTANT: Use HMAC instead of Checksum
                // This prevents you to do attacks where you can correlate known payloads
                // And a CashPack without ever solving it.
                using (HMACSHA512 sha = new HMACSHA512(currentKey))
                {
                    byte[] hash = sha.ComputeHash(solveWorkspace);

                    bool failed = false;

                    for (int i = 0; i < pack.Hash.Length; i++)
                    {
                        if (pack.Hash[i] != hash[i])
                        {
                            failed = true;
                            break;
                        }
                    }

                    if (!failed)
                    {
                        return(solveWorkspace);
                    }
                }

                // Increment key
                ulong keyAsNumber = BitHelper.KeyToNumber(currentKey, pack.BitDifficulty);
                BitHelper.SetLastBitNumberBytes(currentKey, keyAsNumber + 1, pack.BitDifficulty);
            }
        }
Example #3
0
        /// <summary>
        /// Packs a payload into a CashPack.
        /// </summary>
        /// <param name="payload">The plaintext payload to CashPack.</param>
        /// <param name="bitDifficulty">The amount of bits to omit from the packed key. Calculator class can calculate this.</param>
        /// <returns>The packed CashPack ready to distribute. It only contains the encrypted payload and reduced key.</returns>
        public static CashPack Pack(byte[] payload, ushort bitDifficulty)
        {
            CashPack pack = new CashPack()
            {
                BitDifficulty = bitDifficulty,
            };

            // Alloc key
            byte[] fullKey = new byte[payload.Length];

            // Create key
            using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
            {
                rng.GetBytes(fullKey);
            }

            // HMAC Key
            using (HMACSHA512 sha = new HMACSHA512(fullKey))
            {
                pack.Hash = sha.ComputeHash(payload);
            }

            // Alloc payload
            pack.Payload = new byte[payload.Length];

            // Encrypt payload
            for (int i = 0; i < pack.Payload.Length; i++)
            {
                pack.Payload[i] = (byte)(payload[i] ^ fullKey[i]);
            }

            // Reduce key
            byte[] reducedKey = fullKey;
            BitHelper.ReduceKey(reducedKey, bitDifficulty);

            pack.Key = reducedKey;

            return(pack);
        }