generatePrivateKey static method
Generate a BIP38-encrypted private key from an intermediate passphrase.
This method creates a BIP38-encrypted private key from an intermediate passphrase and the specified public key mode. It follows BIP38 standards for encryption.
intPassphrase
: The intermediate passphrase.pubKeyMode
: The public key mode specifying the address type.- Returns: A BIP38-encrypted private key.
Implementation
static String generatePrivateKey(
String intPassphrase, PubKeyModes pubKeyMode) {
/// Decode the intermediate passphrase into bytes.
final intPassphraseBytes = Base58Decoder.checkDecode(intPassphrase);
/// Ensure the length of the intermediate code is valid.
if (intPassphraseBytes.length != Bip38EcConst.intPassEncByteLen) {
throw ArgumentException(
'Invalid intermediate code length (${intPassphraseBytes.length})');
}
/// Extract magic, owner entropy, and passpoint from the intermediate code.
final magic = intPassphraseBytes.sublist(0, 8);
final ownerEntropy = intPassphraseBytes.sublist(8, 16);
final passpoint =
Secp256k1PublicKeyEcdsa.fromBytes(intPassphraseBytes.sublist(16));
/// Check if the magic number is valid.
if (!BytesUtils.bytesEqual(magic, Bip38EcConst.intPassMagicNoLotSeq) &&
!BytesUtils.bytesEqual(magic, Bip38EcConst.intPassMagicWithLotSeq)) {
throw ArgumentException(
'Invalid magic (${BytesUtils.toHexString(magic)})');
}
/// Generate a random seed for seedb and derive a new point.
final seedb = QuickCrypto.generateRandom(Bip38EcConst.seedBByteLen);
final factorb = QuickCrypto.sha256DoubleHash(seedb);
final newPoint = passpoint.point * BigintUtils.fromBytes(factorb);
/// Calculate the address hash.
final addressHash = Bip38Addr.addressHash(newPoint.toBytes(), pubKeyMode);
/// Derive key halves using Scrypt.
final derivedHalves = Bip38EcUtils.deriveKeyHalves(
passpoint.compressed, addressHash, ownerEntropy);
/// Encrypt seedb and create the BIP38-encrypted private key.
final encryptedParts =
_encryptSeedb(seedb, derivedHalves.item1, derivedHalves.item2);
final flagbyte = _setFlagbyteBits(magic, pubKeyMode);
final encKeyBytes = List<int>.from([
...Bip38EcConst.encKeyPrefix,
...flagbyte,
...addressHash,
...ownerEntropy,
...encryptedParts.item1.sublist(0, 8),
...encryptedParts.item2
]);
return Base58Encoder.checkEncode(encKeyBytes);
}