/// <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)); }