Esempio n. 1
0
        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();
        }
Esempio n. 2
0
        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();
        }
Esempio n. 3
0
        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();
        }
Esempio n. 4
0
        /// <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));
        }
Esempio n. 5
0
            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);
            }
Esempio n. 6
0
        /// <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);
        }