private DataReader DecodeFile(DataReader reader, FileType containerType, int fileNumber) { var header = reader.Size < 4 ? 0 : reader.PeekDword(); var fileType = ((header & 0xffff0000) == (uint)FileType.JH) ? FileType.JH : (FileType)header; if (fileType == FileType.JH) { reader.Position += 4; // skip header reader = new DataReader(JH.Crypt(reader, (ushort)(((header & 0xffff0000u) >> 16) ^ (header & 0x0000ffffu)))); } else if (containerType == FileType.AMNC) // AMNC archives are always encoded { reader = new DataReader(JH.Crypt(reader, (ushort)fileNumber)); } header = reader.Size < 4 ? 0 : reader.PeekDword(); // Note: The header might have changed above. fileType = (FileType)header; // Note: No need to check for JH here as this can not happen. // See if it is a LOB file if (fileType == FileType.LOB || fileType == FileType.VOL1) { reader.Position += 4; // skip header uint decodedSize = reader.PeekDword() & 0x00ffffff; // the first byte would contain the offset for the size entry (= 6) // AMNP archives are always encoded if (containerType == FileType.AMNP) { reader.Position += 4; // skip decoded size reader = new DataReader(JH.Crypt(reader, (ushort)fileNumber)); reader.Position += 4; // skip encoded size } else { reader.Position += 8; // skip decoded and encoded size } return(Lob.Decompress(reader, decodedSize)); } else { // AMNP archives are always encoded if (containerType == FileType.AMNP) { // ensure and skip the header (should be FileType.None here) if (reader.ReadDword() != (uint)FileType.None) { throw new AmbermoonException(ExceptionScope.Data, "Invalid AMNP file data."); } reader = new DataReader(JH.Crypt(reader, (ushort)fileNumber)); } return(reader); } }
// Test encryption static void TestCryptography() { IHashProvider p; // Generate a random set of bytes byte[] Bytes = SecureRandom.Bytes(32); // Write bytes to console Console.WriteLine($"Randomly generated bytes: {Encoding.ByteArrayToHexString(Bytes)}"); // Keccak the generated bytes byte[] KeccakBytes = Keccak.keccak(Bytes); // Write keccak bytes to console Console.WriteLine($"Keccak: {Encoding.ByteArrayToHexString(KeccakBytes)}"); // Blake256 the generated bytes p = new Blake(); byte[] BlakeBytes = p.Hash(Bytes); // Write blake256 bytes to console Console.WriteLine($"Blake: {Encoding.ByteArrayToHexString(BlakeBytes)}"); // Skein the generated bytes p = new Skein(); byte[] SkeinBytes = p.Hash(Bytes); // Write skein bytes to console Console.WriteLine($"Skein: {Encoding.ByteArrayToHexString(SkeinBytes)}"); // Groestl the generated bytes p = new Groestl(); byte[] GroestlBytes = p.Hash(Bytes); // Write groestl bytes to console Console.WriteLine($"Groestl: {Encoding.ByteArrayToHexString(GroestlBytes)}"); // JH the generated bytes p = new JH(); byte[] JHBytes = p.Hash(Bytes); // Write JH bytes to console Console.WriteLine($"JH: {Encoding.ByteArrayToHexString(JHBytes)}"); // Base58 the generated bytes string Base58String = Base58.Encode(Bytes); // Write base58 bytes to console Console.WriteLine($"Base58: {Base58String}"); Console.WriteLine(); }
/* CryptoNight Step 5: Apply Keccak to the state again, and then * use the resulting data to select which of four finalizer * hash functions to apply to the data (Blake, Groestl, JH, * or Skein). Use this hash to squeeze the state array down * to the final 32 byte hash output. */ public static byte[] HashFinalState(CNState cnState) { /* Get the state buffer as an array of ulongs rather than bytes */ ulong[] hashState = cnState.GetHashState(); Keccak.Keccakf(hashState, 24); /* Set the state buffer from the coerced hash state */ cnState.SetHashState(hashState); /* Get the actual state buffer finally */ byte[] state = cnState.GetState(); /* Choose the final hashing function to use based on the value of * state[0] */ switch (state[0] % 4) { case 0: { return(Blake.Hash(state)); } case 1: { return(Groestl.Hash(state)); } case 2: { return(JH.Hash(state)); } default: { return(Skein.Hash(state)); } } }