Shared low-level crypto primitives for the custom DEX signing modules
(Bourse.Signing.Hyperliquid, Bourse.Signing.Derive) and Lighter L1
ChangePubKey personal-message signatures.
Wraps the Keccak-256 (ex_keccak) and secp256k1 (ex_secp256k1) NIFs.
Signatures use RFC-6979 deterministic nonces, low-s normalization, and
Ethereum recovery value v = 27 + recovery_id.
Summary
Functions
Decodes a (0x-prefixed) hex string into a binary.
Decodes a (0x-prefixed) hex private key into the 32-byte binary
ExSecp256k1 expects. Accepts the last 64 hex characters.
Lowercase hex-encodes a binary (no 0x prefix).
Computes the EIP-191 personal-message hash (hashMessage) for message.
Keccak-256 digest of data (32 raw bytes).
Recovers the EIP-191 signer address from message and a packed 0x ‖ r ‖ s ‖ v
signature. v may be 27/28 or the raw recovery id 0/1.
Signs a 32-byte digest with the secp256k1 private_key.
Signs message with EIP-191 personal signing, returning the packed
0x ‖ r ‖ s ‖ v signature string. Options: :private_key (required).
Strips a leading 0x/0X prefix if present.
Types
@type signature() :: %{r: String.t(), s: String.t(), v: non_neg_integer()}
Functions
Decodes a (0x-prefixed) hex string into a binary.
Decodes a (0x-prefixed) hex private key into the 32-byte binary
ExSecp256k1 expects. Accepts the last 64 hex characters.
Lowercase hex-encodes a binary (no 0x prefix).
Computes the EIP-191 personal-message hash (hashMessage) for message.
Keccak-256 digest of data (32 raw bytes).
@spec recover_signer_address(String.t(), String.t()) :: {:ok, String.t()} | {:error, :invalid_signature}
Recovers the EIP-191 signer address from message and a packed 0x ‖ r ‖ s ‖ v
signature. v may be 27/28 or the raw recovery id 0/1.
Signs a 32-byte digest with the secp256k1 private_key.
Returns %{r, s, v} where r/s are lowercase
64-char hex strings (no 0x) and v = 27 + recovery_id. Signatures use
RFC-6979 deterministic nonces and canonical low-s values.
Signs message with EIP-191 personal signing, returning the packed
0x ‖ r ‖ s ‖ v signature string. Options: :private_key (required).
Strips a leading 0x/0X prefix if present.