AwsEncryptionSdk.Crypto.ECDSA (AWS Encryption SDK v1.2.1)
View SourceECDSA operations for AWS Encryption SDK.
Provides key generation, signing, verification and key encoding for the
curves of the signed algorithm suites: P-256 (secp256r1, with SHA-256)
for 0x0214, and P-384 (secp384r1, with SHA-384) for 0x0346, 0x0378 and
0x0578. curve_for_suite/1 maps a suite to its curve and
hash_for_curve/1 a curve to its hash.
Spec Reference
Summary
Functions
Returns the curve a signed algorithm suite signs on.
Decodes a base64-encoded public key from encryption context.
Encodes a public key to base64 for storage in encryption context.
Generates an ECDSA key pair for the given curve (:secp256r1 or
:secp384r1).
Returns the hash a curve signs with: SHA-256 on P-256, SHA-384 on P-384.
Normalizes a public key to uncompressed format.
Generates an ECDSA signature over the given message, with the curve's hash (SHA-256 on P-256, SHA-384 on P-384).
Signs a pre-computed digest using ECDSA.
Verifies an ECDSA signature over the given message, with the curve's hash (SHA-256 on P-256, SHA-384 on P-384).
Verifies an ECDSA signature against a pre-computed digest.
Types
Functions
@spec curve_for_suite(AwsEncryptionSdk.AlgorithmSuite.t()) :: curve()
Returns the curve a signed algorithm suite signs on.
:ecdsa_p256 (suite 0x0214) signs on :secp256r1; :ecdsa_p384 (suites
0x0346, 0x0378 and 0x0578) on :secp384r1.
Examples
iex> suite = AwsEncryptionSdk.AlgorithmSuite.aes_128_gcm_iv12_tag16_hkdf_sha256_ecdsa_p256()
iex> AwsEncryptionSdk.Crypto.ECDSA.curve_for_suite(suite)
:secp256r1
iex> suite = AwsEncryptionSdk.AlgorithmSuite.aes_256_gcm_hkdf_sha512_commit_key_ecdsa_p384()
iex> AwsEncryptionSdk.Crypto.ECDSA.curve_for_suite(suite)
:secp384r1
Decodes a base64-encoded public key from encryption context.
Examples
iex> {_private_key, public_key} = AwsEncryptionSdk.Crypto.ECDSA.generate_key_pair(:secp384r1)
iex> encoded = AwsEncryptionSdk.Crypto.ECDSA.encode_public_key(public_key)
iex> {:ok, decoded} = AwsEncryptionSdk.Crypto.ECDSA.decode_public_key(encoded)
iex> AwsEncryptionSdk.Crypto.ECDSA.normalize_public_key(decoded, :secp384r1) == public_key
true
Encodes a public key to base64 for storage in encryption context.
An uncompressed point (0x04 prefix) is written as the point compressed
according to SEC 1 v2.0 section 2.3.3 (a 0x02 or 0x03 prefix by the
parity of y, followed by x), as the specification's
framework/transitive-requirements.md requires for a serialized
verification key, then base64 encoded. Any other binary (a point already
compressed) is base64 encoded as it is. Versions before 1.1.0 wrote the
uncompressed point; decode_public_key/1 and normalize_public_key/2
still read both forms.
Examples
iex> {_private_key, public_key} = AwsEncryptionSdk.Crypto.ECDSA.generate_key_pair(:secp384r1)
iex> encoded = AwsEncryptionSdk.Crypto.ECDSA.encode_public_key(public_key)
iex> byte_size(Base.decode64!(encoded))
49
Generates an ECDSA key pair for the given curve (:secp256r1 or
:secp384r1).
Returns {private_key, public_key} where:
private_keyis the raw private key bytespublic_keyis the uncompressed public key point
Examples
iex> {private_key, public_key} = AwsEncryptionSdk.Crypto.ECDSA.generate_key_pair(:secp384r1)
iex> byte_size(private_key)
48
iex> byte_size(public_key)
97
iex> {_private_key, public_key} = AwsEncryptionSdk.Crypto.ECDSA.generate_key_pair(:secp256r1)
iex> byte_size(public_key)
65
@spec hash_for_curve(curve()) :: :sha256 | :sha384
Returns the hash a curve signs with: SHA-256 on P-256, SHA-384 on P-384.
Examples
iex> AwsEncryptionSdk.Crypto.ECDSA.hash_for_curve(:secp256r1)
:sha256
iex> AwsEncryptionSdk.Crypto.ECDSA.hash_for_curve(:secp384r1)
:sha384
Normalizes a public key to uncompressed format.
Handles both compressed (0x02/0x03 prefix, 49 bytes for P-384 or 33 bytes for P-256) and uncompressed (0x04 prefix, 97 bytes for P-384 or 65 bytes for P-256) formats.
The curve is auto-detected from the key size when possible:
- 33 bytes compressed or 65 bytes uncompressed → secp256r1
- 49 bytes compressed or 97 bytes uncompressed → secp384r1
Generates an ECDSA signature over the given message, with the curve's hash (SHA-256 on P-256, SHA-384 on P-384).
Parameters
message- Binary data to signprivate_key- Raw private key bytes (32 bytes for P-256, 48 for P-384)curve- Elliptic curve to use (:secp256r1or:secp384r1)
Returns
- DER-encoded ECDSA signature
Examples
iex> {private_key, _public_key} = AwsEncryptionSdk.Crypto.ECDSA.generate_key_pair(:secp384r1)
iex> message = "test message"
iex> signature = AwsEncryptionSdk.Crypto.ECDSA.sign(message, private_key, :secp384r1)
iex> is_binary(signature)
true
Signs a pre-computed digest using ECDSA.
This is useful for streaming where the hash is accumulated incrementally. The digest's size picks the curve: a 32-byte SHA-256 digest signs on P-256, a 48-byte SHA-384 digest on P-384.
Parameters
digest- SHA-256 digest (32 bytes) or SHA-384 digest (48 bytes)private_key- Raw private key bytes
Returns
- DER-encoded ECDSA signature
Examples
iex> {private_key, _public_key} = AwsEncryptionSdk.Crypto.ECDSA.generate_key_pair(:secp384r1)
iex> digest = :crypto.hash(:sha384, "test message")
iex> signature = AwsEncryptionSdk.Crypto.ECDSA.sign_digest(digest, private_key)
iex> is_binary(signature)
true
Verifies an ECDSA signature over the given message, with the curve's hash (SHA-256 on P-256, SHA-384 on P-384).
Parameters
message- Binary data that was signedsignature- DER-encoded ECDSA signaturepublic_key- Raw public key bytes, compressed or uncompressedcurve- Elliptic curve to use (:secp256r1or:secp384r1)
Returns
trueif signature is validfalseif signature is invalid
Examples
iex> {private_key, public_key} = AwsEncryptionSdk.Crypto.ECDSA.generate_key_pair(:secp384r1)
iex> message = "test message"
iex> signature = AwsEncryptionSdk.Crypto.ECDSA.sign(message, private_key, :secp384r1)
iex> AwsEncryptionSdk.Crypto.ECDSA.verify(message, signature, public_key, :secp384r1)
true
Verifies an ECDSA signature against a pre-computed digest.
The digest's size picks the curve, as for sign_digest/2.
Parameters
digest- SHA-256 digest (32 bytes) or SHA-384 digest (48 bytes)signature- DER-encoded ECDSA signaturepublic_key- Raw public key bytes
Returns
trueif valid,falseotherwise
Examples
iex> {private_key, public_key} = AwsEncryptionSdk.Crypto.ECDSA.generate_key_pair(:secp384r1)
iex> digest = :crypto.hash(:sha384, "test message")
iex> signature = AwsEncryptionSdk.Crypto.ECDSA.sign_digest(digest, private_key)
iex> AwsEncryptionSdk.Crypto.ECDSA.verify_digest(digest, signature, public_key)
true