ECDSA signing with deterministic k (RFC 6979) and Low-S normalization
Public key recovery from signatures
All operations use BouncyCastle's secp256k1 implementation with performance optimizations including thread-local digest pooling and optional coordinate caching.
This is the JVM-specific implementation. Cross-platform code should use CryptoOpsLike interface.
Example
// Generate a key pair
val keyPair = CryptoOps.generate()
// Hash and sign
val message = "hello".getBytes
val hash = CryptoOps.keccak256(message)
val sig = CryptoOps.sign(keyPair, hash).toOption.get
// Recover public key
val recovered = CryptoOps.recover(sig, hash)
assert(recovered.contains(keyPair.publicKey))
Performs privateKey mod n then scalar multiplication on the secp256k1 generator point to compute the corresponding public key. The caller is expected to supply a value in [1, n-1]; out-of-range inputs are reduced rather than rejected.
Value parameters
privateKey
private key as BigInt; should be in range [1, n-1] (prevalidated)
Attributes
Returns
KeyPair containing the private key and its derived public key
Recovers the public key from a (v, r, s) signature and message hash.
Recovers the public key from a (v, r, s) signature and message hash.
Accepts signatures with either High-S or Low-S; internally normalizes s to Low-S before recovery. The recovery parameter v determines which candidate public key to return.
Value parameters
hashArray
32-byte message hash that was signed
signature
ECDSA signature with recovery parameter v (27-30)
Attributes
Returns
Right(PublicKey) on success, Left(failure) if recovery fails