aws/internal/ecdsa_deterministic
RFC 6979 deterministic ECDSA over NIST P-256 with SHA-256.
The standard ECDSA algorithm picks a fresh random nonce k per
signature; the signature varies between two signings of the
same (key, message). Erlang’s crypto:sign/4 follows that
model — signatures are valid (server-side verify works) but
not byte-reproducible. RFC 6979 derives k deterministically
from (d, h1) via HMAC-DRBG, making signatures byte-for-byte
reproducible against the reference vectors in §A.2.5 and
against the aws-c-auth v4a corpus.
Architecture. The HMAC-DRBG nonce derivation, modular
arithmetic, and DER encoding are pure Gleam. The one expensive
step — the elliptic-curve point multiplication k·G — is
outsourced to Erlang’s crypto:generate_key(ecdh, secp256r1, k)
via the existing aws_ffi:ecdsa_p256_public_key/1 FFI. That
gives us the X coordinate of k·G from which the r half of
the signature is X mod q. Computing s and DER-encoding the
(r, s) pair is then pure integer arithmetic, which BEAM
bignums handle natively.
Values
pub fn sign_p256(
private_key: BitArray,
message_hash: BitArray,
) -> BitArray
Sign a 32-byte SHA-256 hash with a 32-byte P-256 private scalar.
Returns the DER-encoded (r, s) blob — the same shape Erlang’s
crypto:sign/4 returns for ecdsa, so callers can swap the two
without touching downstream code.
pub fn sign_p256_rs_hex(
private_key: BitArray,
message_hash: BitArray,
) -> #(String, String)
Same signature as sign_p256 but returns (r_hex, s_hex) as
64-character lowercase strings. Test-side helper for matching
against the RFC 6979 reference vectors which list r / s as
hex.