TransactionSigner
Transaction signer using Schnorr BIP-340 signatures via JNI to Rust midnight-ledger.
This class bridges Kotlin → JNI → Rust FFI → midnight-ledger for cryptographic signing.
Architecture:
Kotlin: TransactionSigner.signData(privateKey, data)
↓
JNI (C): kuira_crypto_jni.c - Extract bytes, call Rust
↓
Rust FFI: transaction_ffi.rs - create_signing_key, sign_data
↓
midnight-ledger: Schnorr BIP-340 signing over secp256k1Security Notes:
Private keys are copied to native memory and zeroized immediately after use
Transaction data is zeroized after signing (prevents memory dump recovery)
SigningKey pointers must be freed to prevent memory leaks
Uses OS-level RNG for signature nonces (secure by default)
Thread Safety:
Each signing operation creates an independent SigningKey
SigningKey pointers are NOT shared across threads
Safe to call signData() from multiple threads concurrently with different keys
DO NOT manually share SigningKey pointers between threads (use-after-free risk)
The useSigningKey() helper ensures automatic cleanup and prevents pointer misuse
Memory Management:
Native library loads once on first use
Each signData() call creates a new SigningKey, uses it, and frees it automatically
Manual management with nativeCreateSigningKey() requires calling nativeFreeSigningKey()
Use
useSigningKey()for automatic cleanup (recommended pattern)
See also
::signatures::SigningKey (Rust implementation)
(provides private keys)