private SerializationType GetType(byte[] Value) { // Get serialization type byte Type = Encoding.ByteArrayToInteger <byte>(Value, 0); return((SerializationType)Type); }
public static string PrivateKeyToMnemonic(PrivateKey privateKey) { /* Where we'll put the output words into */ List <string> words = new List <string>(); /* For less typing */ byte[] data = privateKey.data; /* Take chunks 4 at a time */ for (int i = 0; i < privateKey.data.Length - 1; i += 4) { /* Read 4 bytes from the byte[] as an integer */ uint val = Encoding.ByteArrayToInteger <uint>(data, i, 4); uint wlLen = (uint)(WordList.English.Length); uint w1 = val % wlLen; uint w2 = ((val / wlLen) + w1) % wlLen; uint w3 = (((val / wlLen) / wlLen) + w2) % wlLen; words.Add(WordList.English[w1]); words.Add(WordList.English[w2]); words.Add(WordList.English[w3]); } /* Add the checksum */ words.Add(GetChecksumWord(words.ToArray())); /* Convert into combined string */ return(string.Join(" ", words.ToArray())); }
// Deserializes the header information from a byte array internal static BucketHead2 Deserialize(byte[] Data) { try { // Create a header object BucketHead2 Head = new BucketHead2(); // Create a working byte array byte[] CurrentBytes = new byte[0]; // Decode signature CurrentBytes = new byte[8]; Buffer.BlockCopy(Data, 0, CurrentBytes, 0, CurrentBytes.Length); Head.Signature = Encoding.ByteArrayToInteger <ulong>(CurrentBytes); // Decode payload size CurrentBytes = new byte[8]; Buffer.BlockCopy(Data, 8, CurrentBytes, 0, CurrentBytes.Length); Head.PayloadSize = Encoding.ByteArrayToInteger <ulong>(CurrentBytes); // Decode response required CurrentBytes = new byte[1]; Buffer.BlockCopy(Data, 16, CurrentBytes, 0, CurrentBytes.Length); Head.ResponseRequired = Convert.ToBoolean(CurrentBytes[0]); // Decode command code CurrentBytes = new byte[4]; Buffer.BlockCopy(Data, 17, CurrentBytes, 0, CurrentBytes.Length); Head.CommandCode = Encoding.ByteArrayToInteger <uint>(CurrentBytes); // Decode return code CurrentBytes = new byte[4]; Buffer.BlockCopy(Data, 21, CurrentBytes, 0, CurrentBytes.Length); Head.ReturnCode = Encoding.ByteArrayToInteger <int>(CurrentBytes); // Decode flags CurrentBytes = new byte[4]; Buffer.BlockCopy(Data, 25, CurrentBytes, 0, CurrentBytes.Length); Head.Flags = Encoding.ByteArrayToInteger <uint>(CurrentBytes); // Decode protocol version CurrentBytes = new byte[4]; Buffer.BlockCopy(Data, 29, CurrentBytes, 0, CurrentBytes.Length); Head.ProtocolVersion = Encoding.ByteArrayToInteger <uint>(CurrentBytes); // Return header object return(Head); } catch { return(default(BucketHead2)); } }
// Decodes a string public static Extra FromString(string Hex) { // Create an extra object Extra Extra = new Extra { Children = new List <object>() }; // Crop hex string to only the included data if (Hex.StartsWith("01")) { Hex = Hex.Substring(66); } // Check if there is data to be read while (Hex.StartsWith("02")) { // Crop to data position Hex = Hex.Substring(2); // Read size byte[] DataSizeBytes = Encoding.HexStringToByteArray(Hex.Substring(0, 8)); int DataSize = Encoding.ByteArrayToInteger <int>(DataSizeBytes); // Get data string string DataString = Hex.Substring(8, DataSize * 2); // Decompress data byte[] DataBytes = Encoding.HexStringToByteArray(DataString); try { DataBytes = Encoding.DecompressByteArray(DataBytes); } catch { } // Decode hex string to dictionary try { Extra.Children.Add(Encoding.DecodeObject <object>(DataBytes)); } catch { Extra.Children.Add(DataString); } // Crop to end of data position Hex = Hex.Substring(8 + DataSize * 2); } // Return extra object return(Extra); }
// Generate a random number of a given type public static T Integer <T>() where T : IConvertible { // Get size of output type int Size = Encoding.GetSizeOfObject(default(T)); // Create a byte buffer of the given size byte[] Bytes = new byte[Size]; // Generate random bytes usin the cryptography provider Provider.GetBytes(Bytes, 0, Size); // Convert the output value into a 64 bit integer ulong Output = Encoding.ByteArrayToInteger <ulong>(Bytes); // Convert 64 bit integer into the given integer type return((T)Convert.ChangeType(Output, typeof(T))); }
// Deserializes a byte array to a storage object public byte[] Deserialize(byte[] Data, bool IncludeHeader = true) { // Verify header int Offset = 0; if (IncludeHeader) { if (Encoding.ByteArrayToInteger <uint>(Data, 0) != GlobalsConfig.STORAGE_SIGNATUREA || Encoding.ByteArrayToInteger <uint>(Data, 4) != GlobalsConfig.STORAGE_SIGNATUREB) { throw new Exception(string.Format("Signature mismatch, expected {0}{1}, got {2}{3}", GlobalsConfig.STORAGE_SIGNATUREA, GlobalsConfig.STORAGE_SIGNATUREB, Encoding.ByteArrayToInteger <uint>(Data, 0), Encoding.ByteArrayToInteger <uint>(Data, 4))); } else if (Data[8] != GlobalsConfig.STORAGE_FORMAT_VERSION) { throw new Exception(string.Format("Version mismatch, expected {0}, got {1}", GlobalsConfig.STORAGE_FORMAT_VERSION, Data[8])); } Offset = 9; } // Get entry count int Count = DeserializeVarInt <int>(Data, Offset, out Offset); // Create a buffer containing just the storage contents byte[] Buffer = Encoding.SplitByteArray(Data, Offset, Data.Length - Offset); // Loop through data until it's empty for (int i = 0; i < Count; i++) { // Deserialize entry Buffer = DeserializeEntry(Buffer); } // Return successful return(Buffer); }
/* This can throw if the input size or outputSize is not of a valid * value. Suggestes output size values are 32 and 200, and suggested * input values are 1 - 136 */ private static byte[] _keccak(byte[] input, int outputSize) { ulong[] state = new ulong[25]; int rsiz; /* sizeof (state) == outputSize */ if ((state.Length * 8) == outputSize) { rsiz = Constants.HASH_DATA_AREA; } else { rsiz = 200 - 2 * outputSize; } int inputLength = input.Length; int offset = 0; /* We index the array 8 bytes at a time, and treat each set of * bytes as a long */ for (; inputLength >= rsiz; inputLength -= rsiz, offset += rsiz * 8) { for (int i = 0; i < rsiz; i += 8) { /* Read 8 bytes as a ulong */ state[i / 8] ^= Encoding.ByteArrayToInteger <ulong>(input, offset + i, 8); } Keccakf(state, Constants.KECCAK_ROUNDS); } byte[] temp = new byte[144]; for (int i = 0; i < inputLength; i++) { temp[i] = input[i + offset]; } temp[inputLength++] = 1; for (int i = inputLength; i < rsiz - inputLength; i++) { temp[i] = 0; } temp[rsiz - 1] |= 0x80; /* We proceed in chunks of 8 bytes as once */ for (int i = 0; i < rsiz; i += 8) { /* Read 8 bytes as a ulong */ state[i / 8] ^= Encoding.ByteArrayToInteger <ulong>(temp, i, 8); } Keccakf(state, Constants.KECCAK_ROUNDS); byte[] output = new byte[outputSize]; /* Copy the ulong state into the output array as bytes */ Buffer.BlockCopy(state, 0, output, 0, output.Length); return(output); }
// Deserializes an entry from a byte array and adds it to storage private byte[] DeserializeEntry(byte[] Buffer) { // Get entry name length int NameLength = Encoding.ByteArrayToInteger <byte>(Buffer, 0, 1);//DeserializeVarInt<int>(Buffer, 0, out int Offset); int Offset = 1; if (NameLength < 1 || NameLength > MAX_STRING_LENGTH) { throw new Exception("Name size exceeds allowed string bounds"); } // Get entry name string Name = Encoding.ByteArrayToString(Buffer, Offset, NameLength); Offset += NameLength; Buffer = Encoding.SplitByteArray(Buffer, Offset, Buffer.Length - Offset); // Get object type SerializationType Type = GetType(Buffer); if ((int)Type < 1 || (int)Type > 14) { throw new Exception("Invalid serialization type caught: " + Encoding.ByteArrayToHexString(Encoding.SplitByteArray(Buffer, 1, Buffer.Length - 1))); } Buffer = Encoding.SplitByteArray(Buffer, 1, Buffer.Length - 1); // Create an entry object var Output = new object(); // Object is a string if (Type == SerializationType.STRING) { // Deserialize string length int Length = DeserializeVarInt <int>(Buffer, 0, out Offset); // Deserialize string Output = Encoding.ByteArrayToString(Encoding.SplitByteArray(Buffer, Offset, Length)); // Resize buffer Offset += (Output as string).Length; if (Buffer.Length - Offset > 0) { Buffer = Encoding.SplitByteArray(Buffer, Offset, Buffer.Length - Offset); } } // Object is an integer else if ((int)Type >= 1 && (int)Type <= 9) { // Create a generic method wrapper to access deserialization MethodInfo MethodInfo = typeof(Encoding).GetMethod("ByteArrayToInteger", new[] { typeof(byte[]), typeof(int) }); Type[] Args = new Type[] { ConvertSerializationType(Type) }; MethodInfo Method = MethodInfo.MakeGenericMethod(Args); // Deserialize integer Output = Method.Invoke(null, new object[] { Buffer, 0 }); // Resize buffer Offset = Encoding.GetSizeOfObject(Output); if (Buffer.Length - Offset > 0) { Buffer = Encoding.SplitByteArray(Buffer, Offset, Buffer.Length - Offset); } } // Object is an object else if (Type == SerializationType.OBJECT) { // Create a new storage object PortableStorage Storage = new PortableStorage(); // Deserialize entry Buffer = Storage.Deserialize(Buffer, false); Output = Storage; } // Add to entries Entries.Add(Name, Output); // Return buffer output return(Buffer); }
/* Compute a hash of length outputSize from input */ private static byte[] _keccak(byte[] input, int outputSize) { ulong[] state = new ulong[25]; int rsiz = Constants.HashDataArea; if (outputSize != 200) { rsiz = 200 - 2 * outputSize; } int rsizw = rsiz / 8; int inputLength = input.Length; /* Offset of input array */ int offset = 0; for (; inputLength >= rsiz; inputLength -= rsiz, offset += rsiz) { for (int i = 0; i < rsizw; i++) { /* Read 8 bytes as a ulong, need to multiply i by 8 * because we're reading chunks of 8 at once */ state[i] ^= Encoding.ByteArrayToInteger <ulong>( input, offset + (i * 8), 8 ); } keccakf(state); } byte[] tmp = new byte[144]; /* Copy inputLength bytes from input to tmp at an offset of * offset from input */ Buffer.BlockCopy(input, offset, tmp, 0, inputLength); tmp[inputLength++] = 1; /* Zero (rsiz - inputLength) bytes in tmp, at an offset of * inputLength */ Array.Clear(tmp, inputLength, rsiz - inputLength); tmp[rsiz - 1] |= 0x80; for (int i = 0; i < rsizw; i++) { /* Read 8 bytes as a ulong - need to read at (i * 8) because * we're reading chunks of 8 at once, rather than overlapping * chunks of 8 */ state[i] ^= Encoding.ByteArrayToInteger <ulong>(tmp, i * 8, 8); } keccakf(state, Constants.KeccakRounds); byte[] output = new byte[outputSize]; Buffer.BlockCopy(state, 0, output, 0, outputSize); return(output); }