A3E9 logoA3E9
// AUDIENCE_FILTERShowing content for NIST / standards conformance. De-emphasized: Competitive positioning, the industry-landscape framing, and on-chain market operations — none of it is conformance evidence.
All evidence

// CBOM · NO_LOGIN_REQUIRED

An Inventory of Every Algorithm, Signed and Downloadable.

A cryptographic bill of materials answers a question a reviewer would otherwise have to ask by hand: which primitives does this thing actually contain? A3E9 generates one in CycloneDX 1.6 from a source scan, signs it, and fails the build when the code grows a mechanism the inventory does not account for. All three files are below, with a verify that runs on OpenSSL alone.

How to read this surface

Generated artifacts you can download and check without an account — produced in a laboratory, not by a production deployment. Citing either half without the other misreads the page.

Checkable
The files are generated from real runs, and the ones that carry a signature verify with OpenSSL alone — no A3E9 tooling and no trust in this page.
Not production
What produced them is not a production deployment: Docker Compose on a single VM, driving software PKCS#11 modules with no certified hardware chassis.
Not a certificate
A3E9 holds no FIPS, CAVP or CMVP certificate of its own. No table on this surface is a verdict, and no row should be quoted as one.
Amber is a limit
Wherever a number or a result appears, the boundary on it is written in this colour. Scanning for amber finds every catch without reading each paragraph to the end.

The long version, with the reading map for every artifact page, is on the evidence index.

// DOWNLOAD

Three Files, Served Byte-Identical.

They are useless apart. The inventory without the signature is a file you cannot distinguish from one we edited on the way out; the signature without the key is a check you cannot run.

Envelope, as served

cbom_sha256
f6523a11ba443a4248fa87c874616d792058be17826f21654ffc28a1273b7237
signed_at
2026-08-08T21:47:47Z
public key
1ef4dd7e8b79d94fdc53161f1344a0ea4e2e2bf5c0db84911184469545f8e696

// WHAT_THIS_SIGNATURE_IS_NOT

A Development Key Signed This.

The signature verifies. It is still not an attestation, and the difference decides how much weight the artifact carries.

Read before citing this signature

The signing key is a development Ed25519 key held in a software SoftHSM2 token, not a production HSM key. A signature made with it is cryptographically valid and attests to nothing an auditor should rely on.

The envelope’s key_label field reads A3E9-ATTESTATION-KEY-PROD. That is the label the signing tool was asked to record — it is not evidence of which key signed, and the production key of that name did not exist in the token where this was produced. The field is named here because the .sig file travels independently of this page, and read on its own that line invites precisely the wrong conclusion.

What the signature is good for: change detection. It proves the bytes served here are the bytes that were signed, so a modified inventory fails the check. It does not tie the inventory to a production HSM, and nothing published today does.

// VERIFY_IT

Five Commands, OpenSSL Only.

Every command below was run against the exact files this page links to before it was published. Nothing here needs A3E9 software, a token, or a clone of a private repository — a verification that requires a tool only we ship is not independent verification.
# 1. Fetch all three files
curl -sO https://a3e9.com/evidence/CBOM.json
curl -sO https://a3e9.com/evidence/CBOM.json.sig
curl -sO https://a3e9.com/evidence/cbom_signing_key.pub

# 2. The digest in the envelope must match the file you were served
sha256sum CBOM.json
grep '^cbom_sha256=' CBOM.json.sig

# 3. Rebuild the public key as a DER SubjectPublicKeyInfo, then PEM
HEX=$(grep -v '^#' cbom_signing_key.pub | tr -d '[:space:]')
printf '302a300506032b6570032100%s' "$HEX" | xxd -r -p > pub.der
openssl pkey -pubin -inform DER -in pub.der -out pub.pem

# 4. Extract the base64 signature and the raw digest it covers
sed -n '/^---BEGIN/,/^---END/p' CBOM.json.sig \
  | grep -v '^---\|^cbom_sha256=\|^key_label=\|^signed_at=' \
  | tr -d '\n' | base64 -d > sig.bin
sha256sum CBOM.json | cut -d' ' -f1 | xxd -r -p > digest.bin

# 5. Verify. Ed25519 over the 32 raw digest bytes.
openssl pkeyutl -verify -pubin -inkey pub.pem -rawin -in digest.bin -sigfile sig.bin
# -> Signature Verified Successfully

The signature is Ed25519 over the 32 raw digest bytes rather than over the file, which is why step 4 builds digest.bin instead of passing the JSON directly. If step 2’s two values disagree, stop — the file you were served is not the file that was signed, and step 5 will fail for that reason rather than for a key reason.

// THE_INVENTORY

Every Asset, With Its Parameters.

All 19 cryptographic assets in the inventory, read from the same file the download serves. Nothing in this table is typed by hand — regenerating the CBOM upstream changes these rows.
AssetTypePrimitiveParametersFunctionsClassicalNIST PQEvidence
Ed25519 (EdDSA)algorithmsignatureed25519sign, verify128013 locations
ECDSA (NIST P-256)algorithmsignaturesecp256r1sign, verify128016 locations
ECDSA (secp256k1)algorithmsignaturesecp256k1sign, verify128013 locations
RSA (2048/4096) with PSS-SHA256algorithmsignature2048/4096sign, verify112016 locations
RSA PKCS#1 v1.5 / OAEP (key transport)algorithmpke2048/4096encrypt, decrypt112012 locations
AES-256-GCMalgorithmae256encrypt, decrypt256115 locations
AES Key Wrap (RFC 3394 / RFC 5649)algorithmkey-wrap256wrapkey, unwrapkey256118 locations
AES-CBC / AES-ECB (unauthenticated modes)algorithmblock-cipher256encrypt, decrypt25611 location
AES-CMACalgorithmmactag, verify12817 locations
SHA-256algorithmhash256digest128118 locations
HMAC-SHA256algorithmmac256tag, verify12818 locations
PBKDF2-HMAC-SHA256algorithmkdf100000 iterations, 32-byte outputkeyderive12811 location
Keccak-256algorithmhash256digest128111 locations
RIPEMD-160 (via Hash160 = RIPEMD-160(SHA-256(x)))algorithmhash160digest8008 locations
2-key Triple DES (TDEA, EDE mode)algorithmblock-cipherecbencrypt, decrypt, keyderive11208 locations
ML-DSA-65 (FIPS 204)algorithmsignatureML-DSA-65keygen, sign, verify0315 locations
ML-KEM-768 (FIPS 203)algorithmkemML-KEM-768keygen, encapsulate, decapsulate032 locations
OpenSSL default DRBG (RAND_bytes)algorithmdrbggenerate12817 locations
TLS (gRPC mutual TLS)protocolprotocol: tls1.2/1.3 (negotiated by gRPC's TLS stack; not version-pinned here)4 locations

What the NIST PQ column is, and is not

The post-quantum security level the inventory records for each asset: 7 at level 0, 9 at level 1, 2 at level 3, 1 at level unstated. A 0 means no post-quantum level is claimed for that asset — it is not an assertion that the algorithm is broken, and this page does not convert it into one. The two ML-* entries are the only assets claiming a NIST category, and liboqs, which implements them, is not a FIPS-certified module.

Why the evidence column counts rather than lists

Each asset is evidenced by the source locations where its mechanisms and symbols actually appear — that is what the over-claim gate checks. The count is shown; the paths are not, because internal component paths are not published to a page. They remain in the downloadable CBOM for a reviewer who goes looking, which is a deliberate act rather than an incidental disclosure.

// WHAT_IT_INVENTORIES

Cryptographic Assets, Not Just Packages.

A dependency SBOM lists libraries. A CBOM lists the cryptography those libraries are used for — which is the part that matters when the question is post-quantum readiness or algorithm deprecation.

What is in this file

23 components: 18 algorithm assets, 1 protocol asset, and 4 libraries — OpenSSL 3.0.13, SoftHSM2 2.6.1, liboqs (Open Quantum Safe) unpinned, Craton HSM (in-tree software PKCS#11 module) in-tree @ a0252b7.

The blocking CI gate

Adding a PKCS#11 mechanism to the code fails the build until the inventory accounts for it, either by mapping it to an asset or by recording a reasoned exemption. The inventory cannot silently fall behind the code, because the code will not compile past it.

How it reconciles with the vector coverage

The conformance report is derived against this inventory: of 18 algorithm assets, 4 have known-answer vectors wired and 14 do not. Those 14 are listed by name in the report rather than summarised as a gap, and the derivation is automatic — wiring a test removes a primitive from the uncovered list with no manual edit.

Two scan gaps, recorded upstream

The under-claim gate keys on PKCS#11 mechanism tokens, so a primitive added purely in software through OpenSSL EVP would not trip it. And the private attestation submodule sits outside the scan roots, so a novel primitive added inside it would not appear here. Both are recorded in the conformance record's own automation-limits list rather than left to be discovered.

Limit

This file inventories cryptography, not packages. The dependency graphs are a separate artifact, published at /evidence/sbom. Note that the signature on this page covers this file only — it does not extend to those SBOMs, which are unsigned today, and holding both artifacts is not the same as holding a reconciliation between them, which does not exist yet. No row here is a certification of any algorithm it names, and the post-quantum entries carry the same fence as everywhere else on this site — liboqs is not a FIPS-certified module.

// WHAT_A_TOKEN_ADDS

The CBOM describes a build. A token confirms the image actually running is that build, which no downloadable file can establish about itself.

Everything above is checkable without contacting anyone, and is meant to be read first. The token exists because the remainder needs a provisioned environment — not because the evidence is being held back.