The core and provider split¶
Two modules, divided along a line the format itself draws.
Where the line is¶
Exactly two operations in this path need a private key:
- the ECDH key agreement, when decrypting;
- a signature, when assembling a certificate.
Everything else — the KDF, the AES key unwrap, the checksum, packet assembly, fingerprints — is arithmetic over data anyone can see.
go/encryption holds the arithmetic. go/encryption-aws-kms holds the two
operations, expressed as narrow interfaces the core declares.
Why not one module¶
Testability. The core is driven by fixed vectors with no credentials and no network. A known shared secret goes in, a known session key comes out. That is possible only because the secret arrives as a parameter rather than being fetched.
Dependency weight. A consumer that only reads messages should not inherit an AWS SDK to do it. The core's build graph is standard library only, and a test asserts that rather than trusting it — because it is the sort of guarantee lost accidentally, by one import added for one convenience.
Substitutability. An HSM, a smartcard or Vault implements the same two methods. Nothing in the core knows which it is talking to, which is what makes that true rather than aspirational.
The seam is narrow on purpose¶
The interfaces are one and two methods. That is deliberate: an interface is a promise a caller must keep, and a wide one is expensive to implement and expensive to fake. A one-method interface is one method's worth of mock.
Both modules ship generated mocks so a consumer testing their own wiring does not have to write those fakes at all.
What the provider does not do¶
It does not interpret OpenPGP. It sends a digest, or a point, and returns bytes. All format knowledge — what gets hashed, in what order, with what trailer — stays in the core, where it is tested against an independent implementation rather than against the author's reading of the specification.