generateSpendKey method
Derive the 32-byte private spend seed for Monero.
The returned bytes are the raw PBKDF2-HMAC-SHA256 output (10 000 iterations, coin-domain-separated salt). Pass them to MoneroKeys.fromSeed, which performs the required Ed25519 scalar reduction (mod l) before use as a private spend key.
Throws StateError if isEncrypted is true - decrypt the seed with the correct passphrase before calling this method.
Implementation
Uint8List generateSpendKey() {
if (isEncrypted) {
throw StateError(
'Cannot derive a spend key from an encrypted polyseed. '
'Decrypt the seed with the correct passphrase first.',
);
}
// Salt layout (32 bytes, all fields little-endian):
// [0..11] "POLYSEED key" (UTF-8, 12 bytes)
// [12] 0x00 (separator, never written)
// [13..15] 0xff 0xff 0xff
// [16..19] coin index (uint32 LE) - Monero = 0
// [20..23] encoded birthday (uint32 LE)
// [24..27] features (uint32 LE)
// [28..31] 0x00 0x00 0x00 0x00
final salt = Uint8List(32); // zero-initialised
const label = 'POLYSEED key'; // 12 chars -> bytes 0-11
salt.setRange(0, label.length, utf8.encode(label));
// byte 12 stays 0x00
salt[13] = 0xff;
salt[14] = 0xff;
salt[15] = 0xff;
_store32(salt, 16, _moneroIndex);
_store32(salt, 20, _data.birthday);
_store32(salt, 24, _data.features);
// bytes 28-31 stay 0x00
return _pbkdf2HmacSha256(
password: _data.secret,
salt: salt,
iterations: 10000,
keyLength: 32,
);
}