deriveKeys
Derives shielded public keys from a 32-byte seed using Midnight's algorithm.
Algorithm:
Coin secret key:
Blake2b("midnight:csk" || seed)Coin public key:
Blake2b("midnight:zswap-pk[v1]" || coin_secret_key)Encryption keys: JubJub elliptic curve operations (twisted Edwards on BLS12-381)
Input: The seed should be derived from BIP-32 at path m/44'/2400'/account'/3/index:
Derive using HDWallet with role
MidnightKeyRole.ZSWAPExtract the 32-byte private key
Pass it to this function
Output: Two 32-byte public keys encoded as 64-character hex strings:
Coin public key (CPK) - Used in zero-knowledge circuits
Encryption public key (EPK) - Used for encrypting transaction data
Security:
This function does NOT clear the seed - caller must wipe it
Public keys are safe to share/store - they're public information
The seed MUST be kept secret - it's equivalent to a private key
Performance:
FFI overhead: < 1ms
Rust crypto: < 1ms (Blake2b + JubJub)
Total: < 2ms per derivation
Compatibility: The output matches Midnight SDK (key derivation version-abstract via Rust FFI):
const zswapKeys = ZswapSecretKeys.fromSeed(seed);
const coinPk = zswapKeys.coinPublicKey; // Matches our coinPublicKey
const encPk = zswapKeys.encPublicKey; // Matches our encryptionPublicKeyError Handling: Returns null if:
Native library not loaded
Native function returns null (internal error)
Returned keys fail validation (invalid hex format)
Throws IllegalArgumentException if seed is not exactly 32 bytes.
Check stderr/Logcat for detailed error messages from the native library.
Return
ShieldedKeys containing both public keys, or null on error
Parameters
32-byte seed derived from BIP-32 at m/44'/2400'/account'/3/index
Throws
if seed is not 32 bytes