AwsEncryptionSdk.Stream.SignatureAccumulator (AWS Encryption SDK v1.2.2)

View Source

Incremental signature accumulation for streaming ECDSA operations.

Purpose

Enables ECDSA signing/verification for large messages without buffering the entire message in memory. Used internally by streaming encryption and decryption for signed algorithm suites.

Memory Efficiency

Instead of buffering the entire message for signing:

  • Accumulates the suite's signature hash state incrementally
  • Hash state size is constant regardless of message size
  • Final signature is computed from hash digest

This allows signing/verifying messages of any size with constant memory usage.

Signed Algorithm Suites

The AWS Encryption SDK includes algorithm suites with ECDSA signatures:

  • AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384 (0x0578, default)
  • AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 (0x0378)
  • AES_192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 (0x0346)
  • AES_128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 (0x0214)

For these suites, the entire message (header + all frames) is signed.

Usage Context

You typically don't use this module directly. It's used internally by:

Low-Level Example

If implementing custom streaming or signature logic:

# During encryption
acc = SignatureAccumulator.init(algorithm_suite)
acc = SignatureAccumulator.update(acc, header_bytes)
acc = SignatureAccumulator.update(acc, frame1_bytes)
acc = SignatureAccumulator.update(acc, frame2_bytes)
signature = SignatureAccumulator.sign(acc, private_key)

# During decryption
acc = SignatureAccumulator.init(algorithm_suite)
acc = SignatureAccumulator.update(acc, header_bytes)
acc = SignatureAccumulator.update(acc, frame1_bytes)
acc = SignatureAccumulator.update(acc, frame2_bytes)
valid? = SignatureAccumulator.verify(acc, signature, public_key)

Hash Algorithm and Curve

init/1 takes both from the algorithm suite: SHA-256 and P-256 for 0x0214, SHA-384 and P-384 for 0x0346, 0x0378 and 0x0578. init/0 uses SHA-384 and P-384.

See Also

Summary

Functions

Returns the current hash digest without finalizing.

Initializes a new signature accumulator with SHA-384 on P-384.

Initializes a new signature accumulator for a signed algorithm suite: SHA-256 on P-256 for 0x0214, SHA-384 on P-384 for 0x0346, 0x0378 and 0x0578.

Finalizes the hash and signs with ECDSA on the accumulator's curve.

Updates the accumulator with additional data.

Finalizes the hash and verifies an ECDSA signature on the accumulator's curve. The public key may be compressed or uncompressed.

Types

t()

@type t() :: %AwsEncryptionSdk.Stream.SignatureAccumulator{
  curve: AwsEncryptionSdk.Crypto.ECDSA.curve(),
  hash_ctx: :crypto.hash_state()
}

Functions

digest(signature_accumulator)

@spec digest(t()) :: binary()

Returns the current hash digest without finalizing.

Useful for debugging or intermediate verification.

init()

@spec init() :: t()

Initializes a new signature accumulator with SHA-384 on P-384.

init(suite)

Initializes a new signature accumulator for a signed algorithm suite: SHA-256 on P-256 for 0x0214, SHA-384 on P-384 for 0x0346, 0x0378 and 0x0578.

sign(signature_accumulator, private_key)

@spec sign(t(), binary()) :: binary()

Finalizes the hash and signs with ECDSA on the accumulator's curve.

Returns DER-encoded signature.

update(acc, data)

@spec update(t(), binary()) :: t()

Updates the accumulator with additional data.

verify(signature_accumulator, signature, public_key)

@spec verify(t(), binary(), binary()) :: boolean()

Finalizes the hash and verifies an ECDSA signature on the accumulator's curve. The public key may be compressed or uncompressed.

Returns true if valid, false otherwise, including for a public key that is not a point on the accumulator's curve.