Esempio n. 1
0
        public static byte[] ComputeWhirlpoolDigest(byte[] data)
        {
            IDigest digest = new WhirlpoolDigest();

            byte[] buffer = new byte[digest.GetDigestSize()];
            digest.BlockUpdate(data, 0, data.Length);
            digest.DoFinal(buffer, 0);
            return(buffer);
        }
Esempio n. 2
0
        public static ExtraHashAlgorithm CreateWhirlpool()
        {
            var ha = new WhirlpoolDigest();

            return(new ExtraHashAlgorithm(
                       ha.AlgorithmName, ha.GetDigestSize(),
                       ha.Reset, ha.BlockUpdate, ha.DoFinal
                       ));
        }
Esempio n. 3
0
        private string createHexOutputFromDigest(byte[] digestBytes)
        {
            IDigest digest = new WhirlpoolDigest();

            byte[] resBuf = new byte[digest.GetDigestSize()];
            digest.BlockUpdate(digestBytes, 0, digestBytes.Length);
            digest.DoFinal(resBuf, 0);
            return(Hex.ToHexString(resBuf));
        }
    public void Reset(IMemoable other)
    {
        WhirlpoolDigest whirlpoolDigest = (WhirlpoolDigest)other;

        Array.Copy(whirlpoolDigest._rc, 0, _rc, 0, _rc.Length);
        Array.Copy(whirlpoolDigest._buffer, 0, _buffer, 0, _buffer.Length);
        _bufferPos = whirlpoolDigest._bufferPos;
        Array.Copy(whirlpoolDigest._bitCount, 0, _bitCount, 0, _bitCount.Length);
        Array.Copy(whirlpoolDigest._hash, 0, _hash, 0, _hash.Length);
        Array.Copy(whirlpoolDigest._K, 0, _K, 0, _K.Length);
        Array.Copy(whirlpoolDigest._L, 0, _L, 0, _L.Length);
        Array.Copy(whirlpoolDigest._block, 0, _block, 0, _block.Length);
        Array.Copy(whirlpoolDigest._state, 0, _state, 0, _state.Length);
    }
Esempio n. 5
0
 public static byte[] Whirlpool(byte[] bytes)
 {
     if (!WhirlpoolHashers.TryPop(out var hasher))
     {
         hasher = new WhirlpoolDigest();
     }
     try {
         var result = new byte[hasher.GetDigestSize()];
         hasher.BlockUpdate(bytes, 0, bytes.Length);
         hasher.DoFinal(result, 0);
         hasher.Reset();
         return(result);
     } finally {
         WhirlpoolHashers.Push(hasher);
     }
 }
Esempio n. 6
0
        public static string CalcCustomAlgorithm1(string password, string salt) // Leet CC
        {
            // SHA-512(pass.salt) XOR whirlpool(salt.pass)
            string toWhirlpool = salt + password;

            byte[] sha512Out = CalcSHA512Raw(password + salt);

            WhirlpoolDigest digest = new WhirlpoolDigest();

            digest.BlockUpdate(Encoding.UTF8.GetBytes(toWhirlpool), 0, toWhirlpool.Length);
            byte[] whirlpoolOut = new byte[digest.GetByteLength()];
            digest.DoFinal(whirlpoolOut, 0);

            // xor together and convert to hex
            byte[] finalOut = exclusiveOR(sha512Out, whirlpoolOut);

            return(ToHexString(finalOut));
        }
        public static string Hash(string message)
        {
            if (string.IsNullOrEmpty(message) || string.IsNullOrWhiteSpace(message))
            {
                return(string.Empty);
            }

            //ASCIIEncoding encoding = new ASCIIEncoding();
            WhirlpoolDigest whirlpool = new WhirlpoolDigest();
            UTF8Encoding    encoding  = new UTF8Encoding();

            byte[] data = encoding.GetBytes(message);
            whirlpool.Reset();
            whirlpool.BlockUpdate(data, 0, data.Length);

            byte[] ret = new byte[whirlpool.GetDigestSize()];
            whirlpool.DoFinal(ret, 0);
            return(ByteToString(ret));
        }
Esempio n. 8
0
        /// <summary>
        /// Whirlpool computation
        /// </summary>
        /// <param name="data">the data to hash</param>
        /// <param name="key">optional hmac key</param>
        /// <returns>the hash value</returns>
        private static byte[] ComputeWhirlpool(byte[] data, byte[] key)
        {
            byte[] outData = new byte[64];

            if (key != null)
            {
                var poolHmac = new HMac(new WhirlpoolDigest());
                poolHmac.Init(new KeyParameter(key));
                poolHmac.BlockUpdate(data, 0, data.Length);
                poolHmac.DoFinal(outData, 0);
            }
            else
            {
                var digest = new WhirlpoolDigest();
                digest.BlockUpdate(data, 0, data.Length);
                digest.DoFinal(outData, 0);
            }

            return(outData);
        }
Esempio n. 9
0
        public override void Decode(byte[] data)
        {
            if (this.Info == null)
            {
                throw new DecodeException("File info must be set before decoding binary file.");
            }

            var dataReader = new BinaryReader(new MemoryStream(data));

            this.Info.CompressionType = (CompressionType)dataReader.ReadByte();
            var dataLength = dataReader.ReadInt32BigEndian();

            // Total length includes already read bytes and the extra bytes read because of compression
            var totalLength = (this.Info.CompressionType == CompressionType.None ? 5 : 9) + dataLength;

            // Decrypt the data if a key is given
            if (this.Info.EncryptionKey != null)
            {
                var xtea = new XteaEngine();
                xtea.Init(false, new KeyParameter(this.Info.EncryptionKey));
                var decrypted = new byte[totalLength];
                xtea.ProcessBlock(dataReader.ReadBytes(totalLength), 5, decrypted, 0);

                dataReader = new BinaryReader(new MemoryStream(decrypted));
            }

            // Check if we should decompress the data or not
            if (this.Info.CompressionType == CompressionType.None)
            {
                this.Info.UncompressedSize = dataLength;
                this.Data = dataReader.ReadBytes(dataLength);
            }
            else
            {
                // Decompress the data
                this.Info.CompressedSize   = dataLength;
                this.Info.UncompressedSize = dataReader.ReadInt32BigEndian();
                var compressedBytes   = dataReader.ReadBytes(dataLength);
                var uncompressedBytes = new byte[this.Info.UncompressedSize.Value];

                switch (this.Info.CompressionType)
                {
                case CompressionType.Bzip2:
                    // Add the bzip2 header as it is missing from the cache for whatever reason
                    var bzipCompressedBytes = new byte[compressedBytes.Length + 4];
                    bzipCompressedBytes[0] = (byte)'B';
                    bzipCompressedBytes[1] = (byte)'Z';
                    bzipCompressedBytes[2] = (byte)'h';
                    bzipCompressedBytes[3] = (byte)'1';
                    Array.Copy(compressedBytes, 0, bzipCompressedBytes, 4, compressedBytes.Length);

                    using (var bzip2Stream = new BZip2InputStream(new MemoryStream(bzipCompressedBytes)))
                    {
                        var readBzipBytes = bzip2Stream.Read(uncompressedBytes, 0, this.Info.UncompressedSize.Value);

                        if (readBzipBytes != this.Info.UncompressedSize)
                        {
                            throw new DecodeException("Uncompressed container data length does not match obtained length.");
                        }
                    }
                    break;

                case CompressionType.Gzip:
                    using (var gzipStream = new GZipInputStream(new MemoryStream(compressedBytes)))
                    {
                        var readGzipBytes = gzipStream.Read(uncompressedBytes, 0, this.Info.UncompressedSize.Value);

                        if (readGzipBytes != this.Info.UncompressedSize)
                        {
                            throw new DecodeException("Uncompressed container data length does not match obtained length.");
                        }
                    }
                    break;

                case CompressionType.Lzma:
                    using (var compressedStream = new MemoryStream(compressedBytes))
                        using (var uncompressedStream = new MemoryStream(uncompressedBytes))
                        {
                            var lzmaDecoder = new SevenZip.Compression.LZMA.Decoder();
                            lzmaDecoder.Code(compressedStream, uncompressedStream, compressedStream.Length, -1, null);

                            if (uncompressedStream.Length != this.Info.UncompressedSize)
                            {
                                throw new DecodeException("Uncompressed container data length does not match obtained length.");
                            }

                            uncompressedBytes = uncompressedStream.ToArray();
                        }
                    break;

                default:
                    throw new DecodeException("Invalid compression type given.");
                }

                this.Data = uncompressedBytes;
            }

            // Update and verify obtained info
            // Read and verify the version of the file
            var versionRead = false;

            if (dataReader.BaseStream.Length - dataReader.BaseStream.Position >= 2)
            {
                var version = dataReader.ReadUInt16BigEndian();

                if (this.Info.Version != null)
                {
                    // The version is truncated to 2 bytes, so only the least significant 2 bytes are compared
                    var truncatedInfoVersion = (int)(ushort)this.Info.Version;
                    if (version != truncatedInfoVersion)
                    {
                        throw new DecodeException($"Obtained version part ({version}) did not match expected ({truncatedInfoVersion}).");
                    }
                }
                else
                {
                    // Set obtained version if previously unset
                    this.Info.Version = version;
                }

                versionRead = true;
            }

            // Calculate and verify CRC
            // CRC excludes the version of the file added to the end
            // There is no way to know if the CRC is zero or unset
            var crcHasher = new Crc32();

            crcHasher.Update(data.Take(data.Length - (versionRead ? 2 : 0)).ToArray());
            var crc = (int)crcHasher.Value;

            if (this.Info.Crc != null && crc != this.Info.Crc)
            {
                throw new DecodeException($"Calculated checksum (0x{crc:X}) did not match expected (0x{this.Info.Crc:X}).");
            }

            this.Info.Crc = crc;

            // Calculate and verify the whirlpool digest
            var whirlpoolHasher = new WhirlpoolDigest();

            whirlpoolHasher.BlockUpdate(data, 0, data.Length - (versionRead ? 2 : 0));

            var whirlpoolDigest = new byte[whirlpoolHasher.GetDigestSize()];

            whirlpoolHasher.DoFinal(whirlpoolDigest, 0);

            if (this.Info.WhirlpoolDigest != null && !whirlpoolDigest.SequenceEqual(this.Info.WhirlpoolDigest))
            {
                throw new DecodeException("Calculated whirlpool digest did not match expected.");
            }

            this.Info.WhirlpoolDigest = whirlpoolDigest;

            if (dataReader.BaseStream.Position < dataReader.BaseStream.Length)
            {
                throw new DecodeException($"Input data not fully consumed while decoding binary file. {dataReader.BaseStream.Length - dataReader.BaseStream.Position} bytes remain.");
            }
        }
Esempio n. 10
0
        public override byte[] Encode()
        {
            if (this.Info == null)
            {
                throw new DecodeException("File info must be set before encoding binary file.");
            }

            // Encrypt data
            if (this.Info.EncryptionKey != null)
            {
                throw new NotImplementedException("RuneTek5 file encryption is not yet supported. Nag me about it if you encounter this error.");
            }

            // Compression
            var uncompressedSize = this.Data.Length;

            byte[] compressedData;
            switch (this.Info.CompressionType)
            {
            case CompressionType.Bzip2:
                using (var bzip2CompressionStream = new MemoryStream())
                {
                    using (var bzip2Stream = new BZip2OutputStream(bzip2CompressionStream, 1))
                    {
                        bzip2Stream.Write(this.Data, 0, this.Data.Length);
                    }

                    // Remove BZh1
                    compressedData = bzip2CompressionStream.ToArray().Skip(4).ToArray();
                }
                break;

            case CompressionType.Gzip:
                using (var gzipCompressionStream = new MemoryStream())
                {
                    using (var gzipStream = new GZipOutputStream(gzipCompressionStream))
                    {
                        gzipStream.Write(this.Data, 0, this.Data.Length);
                    }

                    compressedData = gzipCompressionStream.ToArray();
                }
                break;

            case CompressionType.Lzma:
                using (var lzmaCompressionStream = new MemoryStream())
                    using (var dataStream = new MemoryStream(this.Data))
                    {
                        var lzmaEncoder = new SevenZip.Compression.LZMA.Encoder();
                        lzmaEncoder.Code(dataStream, lzmaCompressionStream, this.Data.Length, -1, null);

                        compressedData = lzmaCompressionStream.ToArray();
                    }
                break;

            case CompressionType.None:
                compressedData = this.Data;
                break;

            default:
                throw new ArgumentException("Invalid compression type.");
            }

            var memoryStream = new MemoryStream();
            var writer       = new BinaryWriter(memoryStream);

            writer.Write((byte)this.Info.CompressionType);

            // Compressed/total size
            writer.WriteInt32BigEndian(compressedData.Length);

            // Add uncompressed size when compressing
            if (this.Info.CompressionType != CompressionType.None)
            {
                writer.WriteInt32BigEndian(uncompressedSize);
            }

            writer.Write(compressedData);

            // Suffix with version truncated to two bytes (not part of data for whatever reason)
            if (this.Info.Version != null)
            {
                writer.WriteUInt16BigEndian((ushort)this.Info.Version);
            }

            var result = memoryStream.ToArray();

            // Update file info with sizes
            this.Info.CompressedSize   = compressedData.Length;
            this.Info.UncompressedSize = uncompressedSize;

            // Update file info with CRC
            var crc = new Crc32();

            crc.Update(result.Take(result.Length - 2).ToArray());
            this.Info.Crc = (int)crc.Value;

            // Update file info with whirlpool digest
            var whirlpool = new WhirlpoolDigest();

            whirlpool.BlockUpdate(result, 0, result.Length - 2);

            this.Info.WhirlpoolDigest = new byte[whirlpool.GetDigestSize()];
            whirlpool.DoFinal(this.Info.WhirlpoolDigest, 0);

            return(result);
        }
Esempio n. 11
0
        protected byte[] DecodeData(byte[] encodedData, CacheFileInfo info)
        {
            using var dataStream = new MemoryStream(encodedData);
            using var dataReader = new BinaryReader(dataStream);

            // Decrypt the data if a key is given
            if (info.EncryptionKey != null)
            {
                throw new DecodeException(
                          "XTEA encryption not supported. If you encounter this please inform me about the index and file that triggered this message."
                          );

                // var totalLength = dataStream.Position + dataLength;
                //
                // var xtea = new XteaEngine();
                // xtea.Init(false, new KeyParameter(info.EncryptionKey));
                // var decrypted = new byte[totalLength];
                // xtea.ProcessBlock(dataReader.ReadBytes(totalLength), 5, decrypted, 0);
                //
                // dataReader = new BinaryReader(new MemoryStream(decrypted));
            }

            var compressionType  = (CompressionType)dataReader.ReadByte();
            var compressedSize   = dataReader.ReadInt32BigEndian();
            var uncompressedSize = compressedSize;

            if (compressionType != CompressionType.None)
            {
                uncompressedSize = dataReader.ReadInt32BigEndian();
            }

            var data = this.Decompress(
                compressionType,
                dataReader.ReadBytesExactly(compressedSize),
                uncompressedSize
                );

            // Compressed size includes meta bytes for info.
            compressedSize = (int)dataStream.Position;

            // Verify compressed size. Info's compressed size includes meta bytes.
            if (info.CompressedSize != null && compressedSize != info.CompressedSize)
            {
                throw new DecodeException(
                          $"Compressed size ({compressedSize}) does not equal expected ({info.CompressedSize})."
                          );
            }

            // Verify uncompressed size.
            if (info.UncompressedSize != null && uncompressedSize != info.UncompressedSize)
            {
                // Some uncompressed files _do_ seem to include meta bytes into the uncompressed size. Allow for now.
                // TODO: Figure out when uncompressed size includes the meta bytes. Is this only true for audio files?
                var message = $"Uncompressed size ({uncompressedSize}) does not equal expected ({info.UncompressedSize}).";
                if (compressionType == CompressionType.None && uncompressedSize + 5 == info.UncompressedSize)
                {
                    Log.Debug(message + " (allowed)");
                }
                else
                {
                    throw new DecodeException(message);
                }
            }

            // Calculate and verify CRC.
            var crcHasher = new Crc32();

            crcHasher.Update(encodedData);
            // Note that there is no way to distinguish between an unset CRC and one that is zero.
            var crc = (int)crcHasher.Value;

            if (info.Crc != null && crc != info.Crc)
            {
                throw new DecodeException($"Calculated checksum ({crc}) did not match expected ({info.Crc}).");
            }

            // Calculate and verify whirlpool digest.
            var whirlpoolHasher = new WhirlpoolDigest();

            whirlpoolHasher.BlockUpdate(encodedData, 0, compressedSize);
            var whirlpoolDigest = new byte[whirlpoolHasher.GetDigestSize()];

            whirlpoolHasher.DoFinal(whirlpoolDigest, 0);

            if (info.WhirlpoolDigest != null && !whirlpoolDigest.SequenceEqual(info.WhirlpoolDigest))
            {
                throw new DecodeException("Calculated whirlpool digest did not match expected.");
            }

            if (dataStream.Position < dataStream.Length)
            {
                throw new DecodeException(
                          $"Input data not fully consumed while decoding RuneTek5CacheFile. {dataStream.Length - dataStream.Position} bytes remain."
                          );
            }

            // Update info with obtained details.
            info.CompressionType  = compressionType;
            info.CompressedSize   = compressedSize;
            info.UncompressedSize = uncompressedSize;
            info.Crc             = crc;
            info.WhirlpoolDigest = whirlpoolDigest;

            return(data);
        }
Esempio n. 12
0
        protected byte[] EncodeData(byte[] data, CacheFileInfo?info)
        {
            // Encrypt data.
            if (info?.EncryptionKey != null)
            {
                throw new EncodeException(
                          "XTEA encryption not supported. If you encounter this please inform me about the index and file that triggered this message."
                          );
            }

            // Compression.
            var compressionType  = info?.CompressionType ?? CompressionType.Bzip2;
            var uncompressedSize = data.Length;
            var compressedData   = this.CompressData(compressionType, data);

            using var dataStream = new MemoryStream();
            using var dataWriter = new BinaryWriter(dataStream);

            dataWriter.Write((byte)compressionType);
            dataWriter.WriteInt32BigEndian(compressedData.Length);

            // Add uncompressed size if compression is used.
            if (compressionType != CompressionType.None)
            {
                dataWriter.WriteInt32BigEndian(uncompressedSize);
            }

            dataWriter.Write(compressedData);

            if (compressionType == CompressionType.None)
            {
                // Uncompressed size includes meta bytes for info when not using compression.
                uncompressedSize = (int)dataStream.Position;
            }

            // Compressed size includes meta bytes for info.
            var compressedSize = (int)dataStream.Position;

            var result = dataStream.ToArray();

            // Calculate new CRC.
            var crcHasher = new Crc32();

            crcHasher.Update(result);
            var crc = (int)crcHasher.Value;

            // Calculate new whirlpool digest.
            var whirlpoolHasher = new WhirlpoolDigest();

            whirlpoolHasher.BlockUpdate(result, 0, compressedSize);
            var whirlpoolDigest = new byte[whirlpoolHasher.GetDigestSize()];

            whirlpoolHasher.DoFinal(whirlpoolDigest, 0);

            // Update file info.
            if (info != null)
            {
                info.CompressionType  = compressionType;
                info.CompressedSize   = compressedSize;
                info.UncompressedSize = uncompressedSize;
                info.Crc             = crc;
                info.WhirlpoolDigest = whirlpoolDigest;
            }

            return(result);
        }
Esempio n. 13
0
        public static IDigest GetDigest(string algorithm)
        {
            string text  = Platform.ToUpperInvariant(algorithm);
            string text2 = (string)DigestUtilities.algorithms[text];

            if (text2 == null)
            {
                text2 = text;
            }
            try
            {
                switch ((DigestUtilities.DigestAlgorithm)Enums.GetEnumValue(typeof(DigestUtilities.DigestAlgorithm), text2))
                {
                case DigestUtilities.DigestAlgorithm.GOST3411:
                {
                    IDigest result = new Gost3411Digest();
                    return(result);
                }

                case DigestUtilities.DigestAlgorithm.MD2:
                {
                    IDigest result = new MD2Digest();
                    return(result);
                }

                case DigestUtilities.DigestAlgorithm.MD4:
                {
                    IDigest result = new MD4Digest();
                    return(result);
                }

                case DigestUtilities.DigestAlgorithm.MD5:
                {
                    IDigest result = new MD5Digest();
                    return(result);
                }

                case DigestUtilities.DigestAlgorithm.RIPEMD128:
                {
                    IDigest result = new RipeMD128Digest();
                    return(result);
                }

                case DigestUtilities.DigestAlgorithm.RIPEMD160:
                {
                    IDigest result = new RipeMD160Digest();
                    return(result);
                }

                case DigestUtilities.DigestAlgorithm.RIPEMD256:
                {
                    IDigest result = new RipeMD256Digest();
                    return(result);
                }

                case DigestUtilities.DigestAlgorithm.RIPEMD320:
                {
                    IDigest result = new RipeMD320Digest();
                    return(result);
                }

                case DigestUtilities.DigestAlgorithm.SHA_1:
                {
                    IDigest result = new Sha1Digest();
                    return(result);
                }

                case DigestUtilities.DigestAlgorithm.SHA_224:
                {
                    IDigest result = new Sha224Digest();
                    return(result);
                }

                case DigestUtilities.DigestAlgorithm.SHA_256:
                {
                    IDigest result = new Sha256Digest();
                    return(result);
                }

                case DigestUtilities.DigestAlgorithm.SHA_384:
                {
                    IDigest result = new Sha384Digest();
                    return(result);
                }

                case DigestUtilities.DigestAlgorithm.SHA_512:
                {
                    IDigest result = new Sha512Digest();
                    return(result);
                }

                case DigestUtilities.DigestAlgorithm.SHA_512_224:
                {
                    IDigest result = new Sha512tDigest(224);
                    return(result);
                }

                case DigestUtilities.DigestAlgorithm.SHA_512_256:
                {
                    IDigest result = new Sha512tDigest(256);
                    return(result);
                }

                case DigestUtilities.DigestAlgorithm.SHA3_224:
                {
                    IDigest result = new Sha3Digest(224);
                    return(result);
                }

                case DigestUtilities.DigestAlgorithm.SHA3_256:
                {
                    IDigest result = new Sha3Digest(256);
                    return(result);
                }

                case DigestUtilities.DigestAlgorithm.SHA3_384:
                {
                    IDigest result = new Sha3Digest(384);
                    return(result);
                }

                case DigestUtilities.DigestAlgorithm.SHA3_512:
                {
                    IDigest result = new Sha3Digest(512);
                    return(result);
                }

                case DigestUtilities.DigestAlgorithm.TIGER:
                {
                    IDigest result = new TigerDigest();
                    return(result);
                }

                case DigestUtilities.DigestAlgorithm.WHIRLPOOL:
                {
                    IDigest result = new WhirlpoolDigest();
                    return(result);
                }
                }
            }
            catch (ArgumentException)
            {
            }
            throw new SecurityUtilityException("Digest " + text2 + " not recognised.");
        }
 public WhirlpoolDigest(WhirlpoolDigest originalDigest)
 {
     Reset(originalDigest);
 }