Bourse.Signing.Crypto (bourse v0.1.0)

Copy Markdown View Source

Shared low-level crypto primitives for the custom DEX signing modules (Bourse.Signing.Hyperliquid, Bourse.Signing.Derive).

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).

Keccak-256 digest of data (32 raw bytes).

Signs a 32-byte digest with the secp256k1 private_key.

Strips a leading 0x/0X prefix if present.

Types

signature()

@type signature() :: %{r: String.t(), s: String.t(), v: non_neg_integer()}

Functions

decode_hex(hex)

@spec decode_hex(String.t()) :: binary()

Decodes a (0x-prefixed) hex string into a binary.

decode_private_key(private_key)

@spec decode_private_key(String.t()) :: binary()

Decodes a (0x-prefixed) hex private key into the 32-byte binary ExSecp256k1 expects. Accepts the last 64 hex characters.

encode_hex(binary)

@spec encode_hex(binary()) :: String.t()

Lowercase hex-encodes a binary (no 0x prefix).

keccak256(data)

@spec keccak256(iodata()) :: binary()

Keccak-256 digest of data (32 raw bytes).

sign_hash(digest, private_key)

@spec sign_hash(binary(), binary()) :: signature()

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.

strip_0x(hex)

@spec strip_0x(String.t()) :: String.t()

Strips a leading 0x/0X prefix if present.