mnemonicToEntropy static method

String mnemonicToEntropy(
  1. String mnemonic
)

Implementation

static String mnemonicToEntropy(String mnemonic) {
  final words = mnemonic.split(' ');

  if (words.length % 3 != 0) {
    throw ArgumentError(
        'The mnemonic must have a number of words that is a multple of 3');
  }

  // convert word indices to 11 bit binary strings
  final bits = words.map((word) {
    final index = bip39_english_wordlist.indexOf(word);

    if (index == -1) {
      throw ArgumentError(
        'The word $word is not contained in the bip39 english dictionary',
      );
    }

    return index.toRadixString(2).padLeft(11, '0');
  }).join('');

  // split the binary string into ENT/CS
  final dividerIndex = (bits.length / 33).floor() * 32;
  final entropyBits = bits.substring(0, dividerIndex);
  final checksumBits = bits.substring(dividerIndex);

  // calculate the checksum and compare
  final regex = RegExp('.{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: the bytes must be at least 16');
  }

  if (entropyBytes.length > 32) {
    throw StateError('Invalid entropy: the bytes must be under 32');
  }

  if (entropyBytes.length % 4 != 0) {
    throw StateError('Invalid entropy: the bytes should be a multiple of 4');
  }

  final newChecksum = _deriveChecksumBits(entropyBytes);

  if (newChecksum != checksumBits) {
    throw StateError('Invalid checksum');
  }

  return entropyBytes.map((byte) {
    return byte.toRadixString(16).padLeft(2, '0');
  }).join('');
}