mnemonicToEntropy method

String mnemonicToEntropy(
  1. String mnemonic
)

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('');
}