public void TestReadWriteByte() { // Create a new bit stream in memory. BitStream bitStream = new BitStream(); bitStream.WriteByte(0xFF, 3); bitStream.WriteByte(7, 2); // Verify position after write. Assert.Equal(0, bitStream.Position); Assert.Equal(5, bitStream.BitPosition); // Verify position after directly setting it. bitStream.Position = 0; bitStream.BitPosition = 0; Assert.Equal(0, bitStream.Position); Assert.Equal(0, bitStream.BitPosition); // Read 5 bits, all should be set. byte value = bitStream.ReadByte(5); Assert.Equal(31, value); // Verify position after read. Assert.Equal(0, bitStream.Position); Assert.Equal(5, bitStream.BitPosition); // Write split between two bytes (3 bits in first, 2 bits in another). (0xAA == 10101010b) (5 bits = 01010b = 0x0A) bitStream.WriteByte(0xAA, 5); // Verify position after crossing byte boundary writing Assert.Equal(1, bitStream.Position); Assert.Equal(2, bitStream.BitPosition); // Move backwards to the start of our 0xAA value. bitStream.BitPosition -= 5; // Read the value, it should be 0xAA. value = bitStream.ReadByte(5); Assert.Equal(0x0A, value); // Verify position after crossing byte boundary reading. Assert.Equal(1, bitStream.Position); Assert.Equal(2, bitStream.BitPosition); // Move backwards to the start of our stream. bitStream.Position = 0; bitStream.BitPosition = 0; // Read both bytes to verify. value = bitStream.ReadByte(8); Assert.Equal(0xFA, value); value = bitStream.ReadByte(8); Assert.Equal(0x80, value); // Close the bit stream. bitStream.Close(); }
public void TestReadWriteBytes() { // Create a new bit stream in memory. BitStream bitStream = new BitStream(); bitStream.WriteByte(0xFF, 3); bitStream.WriteByte(7, 2); // Verify position after write. Assert.Equal(0, bitStream.Position); Assert.Equal(5, bitStream.BitPosition); // Verify position after directly setting it. bitStream.Position = 0; bitStream.BitPosition = 0; Assert.Equal(0, bitStream.Position); Assert.Equal(0, bitStream.BitPosition); // Read 5 bits, all should be set. byte value = bitStream.ReadByte(5); Assert.Equal(31, value); // --------------------------------- // MULTI BYTE CODE STARTS BELOW // --------------------------------- // Write an array (8 bytes = 64 bit). byte[] allSet = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; bitStream.WriteBytes(allSet, 63); bitStream.WriteByte(5, 5); // Go back to the start of multi byte code bitStream.BitPosition -= 68; // Read 63 bits. byte[] resultAllSet = bitStream.ReadBytes(63, true); // Test all bytes except last (not byte-aligned bits). for (int i = 0; i < allSet.Length - 1; i++) { Assert.Equal(allSet[i], resultAllSet[i]); } // Test the last Assert.Equal(0xFE, resultAllSet[resultAllSet.Length - 1]); // Read our 5 bit integer. value = bitStream.ReadByte(5); // Verify the last integer's value. Assert.Equal(5, value); // Close the bit stream. bitStream.Close(); }
public void TestReadWriteInts() { // Create a new bit stream in memory. BitStream bitStream = new BitStream(); bitStream.Write((ulong)0xFF, 3); bitStream.Write((uint)7, 2); // Verify position after write. Assert.Equal(0, bitStream.Position); Assert.Equal(5, bitStream.BitPosition); // Verify position after directly setting it. bitStream.Position = 0; bitStream.BitPosition = 0; Assert.Equal(0, bitStream.Position); Assert.Equal(0, bitStream.BitPosition); // Read 5 bits, all should be set. byte value = (byte)bitStream.ReadUInt64(5); Assert.Equal(31, value); // Write two values bitStream.Write((ulong)0xAAAAAAAA, 15); bitStream.Write((ulong)0xFFFFFFFF, 29); // Move back. bitStream.BitPosition -= 44; // Verify our two values Assert.Equal((ulong)0x2AAA, bitStream.ReadUInt64(15)); Assert.Equal((ulong)0x1FFFFFFF, bitStream.ReadUInt64(29)); // Move backwards. bitStream.BitPosition -= 44; // Verify our two values as a single one. Assert.Equal((ulong)0x5555FFFFFFF, bitStream.ReadUInt64(44)); // Move backwards. bitStream.BitPosition -= 44; // Rewrite our value as a singular big one. bitStream.Write((ulong)0x5555FFFFFFF, 44); // Move backwards. bitStream.BitPosition -= 44; // Verify our two values Assert.Equal((ulong)0x2AAA, bitStream.ReadUInt64(15)); Assert.Equal((ulong)0x1FFFFFFF, bitStream.ReadUInt64(29)); // Close the bit stream. bitStream.Close(); }
/// <summary> /// Verifies the mnemonic phrase's word sequence checksum is valid. /// </summary> /// <returns>Returns true if the mnemonic word sequence is valid.</returns> public bool Verify() { // Verify our index count/word count is in our bounds. if (Indices.Length < MNEMONIC_WORDS_MINIMUM && Indices.Length > MNEMONIC_WORDS_MAXIMUM) { return(false); } // Determine the size of our entropy and checksum in bits. int bitStreamLength = Indices.Length * MNEMONIC_WORD_INDEX_BITCOUNT; int checksumBitcount = bitStreamLength / (MNEMONIC_ENTROPY_BITS_PER_CHECKSUM_BIT + 1); int entropyBitcount = checksumBitcount * MNEMONIC_ENTROPY_BITS_PER_CHECKSUM_BIT; // Now we'll want to write the indices back to a bitstream to parse our entropy/checksum from it. BitStream bitStream = new BitStream(); for (int i = 0; i < Indices.Length; i++) { // If our index is negative, return false if (Indices[i] < 0) { return(false); } // Write the word index. bitStream.Write((ulong)Indices[i], MNEMONIC_WORD_INDEX_BITCOUNT); } // Move back to the start of the data bitStream.Position = 0; bitStream.BitPosition = 0; // Read our entropy data. byte[] entropy = bitStream.ReadBytes(entropyBitcount, true); // Read our checksum byte[] checksum = bitStream.ReadBytes(checksumBitcount, true); // Recalculate our hash of the entropy and derive our checksum from its bits sequentially. byte[] calculatedChecksum = sha256Provider.ComputeHash(entropy); bitStream.ClearContents(); bitStream.WriteBytes(calculatedChecksum, checksumBitcount); // Move back to the start of the data bitStream.Position = 0; bitStream.BitPosition = 0; // Read our calculated checksum. calculatedChecksum = bitStream.ReadBytes(checksumBitcount, true); // Close the bitstream. bitStream.Close(); // Compare our sequences. return(checksum.SequenceEqual(calculatedChecksum)); }
public long GetSCR() { BitStream bb = new BitStream(); bb.Write(0, 0, 64 - 33); bb.Write(system_clock1, 0, 3); bb.Write(system_clock2, 0, 15); bb.Write(system_clock3, 0, 15); bb.Position = 32; bb.Read(out long scr, 0, 32); bb.Close(); scr /= 90; return(scr); }
/// <summary> /// Initializes a mnemonic phrase for the given language, with the optionally given entropy data (or newly generated data if none is provided). /// </summary> /// <param name="wordListLanguage">The language to create a mnemonic phrase in.</param> /// <param name="entropy">The optionally given entropy data to generate a mnemonic phrase from. If null, generates new entropy data of the maximum size.</param> public MnemonicPhrase(WordListLanguage wordListLanguage, byte[] entropy = null) { // Set our word list WordList = WordList.GetWordList(wordListLanguage); // If our entropy is null, initialize a new set. if (entropy == null) { // Create a buffer of random bytes (entropy) using our RNG. int maximumEntropySize = (MNEMONIC_ENTROPY_BITS_PER_CHECKSUM_BIT * (MNEMONIC_WORDS_MAXIMUM / MNEMONIC_WORDS_PER_CHECKSUM_BIT)) / 8; entropy = new byte[maximumEntropySize]; _random.GetBytes(entropy); } // Verify our entropy size is divisible by the range of a checksum. int entropySizeBits = (entropy.Length * 8); if (entropySizeBits % MNEMONIC_ENTROPY_BITS_PER_CHECKSUM_BIT != 0) { throw new ArgumentException($"Provided entropy data must be divisible by {MNEMONIC_ENTROPY_BITS_PER_CHECKSUM_BIT}"); } // Calculate our component sizes. int checksumBitcount = entropySizeBits / MNEMONIC_ENTROPY_BITS_PER_CHECKSUM_BIT; int wordCount = checksumBitcount * MNEMONIC_WORDS_PER_CHECKSUM_BIT; // Verify our word count is valid if (wordCount < MNEMONIC_WORDS_MINIMUM || wordCount > MNEMONIC_WORDS_MAXIMUM) { throw new ArgumentException($"Provided entropy data of this size would represent {wordCount} words. Should be between {MNEMONIC_WORDS_MINIMUM}-{MNEMONIC_WORDS_MAXIMUM} (inclusive)."); } // Calculate our SHA256 hash of the entropy. byte[] checksum = sha256Provider.ComputeHash(entropy); // Now we write the entropy followed by the checksum bits (which we will use to interpret a mnemonic from later). BitStream bitStream = new BitStream(); bitStream.WriteBytes(entropy); bitStream.WriteBytes(checksum, checksumBitcount); // Move back to the start of the data bitStream.Position = 0; bitStream.BitPosition = 0; // Read every word index, which are represented by 11-bit unsigned integers. At the same time, we resolve our mnemonic words. int wordIndexCount = (int)(bitStream.BitLength / MNEMONIC_WORD_INDEX_BITCOUNT); Indices = new int[wordIndexCount]; MnemonicWords = new string[Indices.Length]; for (int i = 0; i < Indices.Length; i++) { Indices[i] = (int)bitStream.ReadUInt64(MNEMONIC_WORD_INDEX_BITCOUNT); MnemonicWords[i] = WordList.Words[Indices[i]]; } // Close the bitstream. bitStream.Close(); // Join all strings into a mnemonic sentence. MnemonicString = WordList.JoinMnemonic(MnemonicWords); }