mnemonicToEntropy method
Converts a BIP-39 mnemonic phrase to entropy bytes.
This method takes a BIP-39 mnemonic phrase as input and converts it into the raw entropy bytes it represents. It performs various checks to ensure the validity of the conversion, including verifying the checksum.
Parameters:
mnemonic
: The BIP-39 mnemonic phrase to convert.
Returns: Raw entropy bytes as a hexadecimal string.
Throws:
- ArgumentError: If an invalid mnemonic word is encountered or the mnemonic phrase is of an incorrect length.
- StateError: If the entropy or checksum is invalid.
Implementation
String mnemonicToEntropy(String mnemonic) {
/// Split the mnemonic into individual words.
List<String> words = mnemonic.split(' ');
if (words.length % 3 != 0) {
throw ArgumentError('Invalid mnemonic');
}
/// Convert word indices to 11-bit binary strings.
final bits = words.map((word) {
final index = language.words.indexOf(word);
if (index == -1) {
throw ArgumentError('Invalid mnemonic');
}
return index.toRadixString(2).padLeft(11, '0');
}).join('');
/// Divide bits into entropy and checksum sections.
final dividerIndex = (bits.length / 33).floor() * 32;
final entropyBits = bits.substring(0, dividerIndex);
final checksumBits = bits.substring(dividerIndex);
/// Convert entropy bits back to bytes and perform validation checks.
final regex = RegExp(r".{1,8}");
final entropyBytes = Uint8List.fromList(regex
.allMatches(entropyBits)
.map((match) => binaryToByte(match.group(0)!))
.toList(growable: false));
if (entropyBytes.length < 16) {
throw StateError("Invalid entropy");
}
if (entropyBytes.length > 32) {
throw StateError("Invalid entropy");
}
if (entropyBytes.length % 4 != 0) {
throw StateError("Invalid entropy");
}
/// Verify the checksum.
final newChecksum = _deriveChecksumBits(entropyBytes);
if (newChecksum != checksumBits) {
throw StateError("Invalid mnemonic checksum");
}
/// Convert valid entropy bytes back to hexadecimal.
return entropyBytes.map((byte) {
return byte.toRadixString(16).padLeft(2, '0');
}).join('');
}