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 secp256k1

Security 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

midnight_base_crypto

::signatures::SigningKey (Rust implementation)

(provides private keys)

Functions

Link copied to clipboard
fun getPublicKey(privateKey: ByteArray): ByteArray?

Derives the verifying key (public key) from a private key.

Link copied to clipboard
fun signData(privateKey: ByteArray, data: ByteArray): ByteArray?

Signs data with Schnorr BIP-340 signature.

Link copied to clipboard
fun verifySignature(publicKey: ByteArray, message: ByteArray, signature: ByteArray): Boolean

Verifies a Schnorr BIP-340 signature.