Cryptography Reference
Grizzly encrypts asset data with AES-256-GCM and wraps the resulting symmetric keys using RSA-4096 before storing them. Asset metadata integrity and provenance are protected by crypto-agile asymmetric signatures, using a hybrid classical and post-quantum suite by default, issued through a delegated signing service so that the signing root never leaves the customer's custody. This document covers the specific algorithms, key material, IV construction, the signing hierarchy, and binary formats in enough detail to evaluate them, audit them, or present them to a security reviewer.
Algorithms at a Glance
| Purpose | Algorithm | Key Size | Notes |
|---|---|---|---|
| Data encryption | AES-256-GCM | 256-bit | 128-bit auth tag |
| Key wrapping | RSA-4096 | 4096-bit | PKCS1 public, PKCS8 private |
| Asset signing | hybrid:ed25519+ml-dsa-65 (default) |
— | Ed25519 and ML-DSA-65; both must verify |
| Content hashing | SHA-256 | — | Binds the signed asset's content and envelope |
The asset-signing suite is crypto-agile. The default binds a classical Ed25519 signature and a post-quantum ML-DSA-65 signature (FIPS 204), both of which must verify for a signature to be accepted, and the suite label travels with the data so the scheme can evolve without breaking assets that were already signed. Rings can also be provisioned with other suites, such as ML-DSA-87.
AES-256-GCM
All asset data is encrypted using AES-256-GCM with a 32-byte key and a 128-bit authentication tag. GCM provides authenticated encryption, which means the ciphertext carries an integrity check that the decryption process must verify before returning any plaintext. If the authentication tag does not match, decryption fails rather than silently producing corrupted output. The authentication tag (16 bytes) is appended to the end of the ciphertext and stripped during decryption.
IV Construction
Each encryption operation uses a 96-bit (12-byte) nonce composed of two parts: a 72-bit (9-byte) cryptographically random prefix and a 24-bit (3-byte) incrementing counter. The random prefix is generated when a Key is first created. The counter starts at zero and increments with each encrypt call on that Key.
This construction follows NIST SP 800-38D guidance for deterministic IV generation. The 24-bit counter supports up to 16,777,216 unique nonces per prefix before exhaustion, but Key rotation limits the number of operations per Key to a configurable ceiling that sits well below that number in practice.
Key Rotation
Each Key on a KeyRing has a maxEncryptCount setting that controls how many encrypt operations it will serve before the KeyRing automatically rotates to a new Key. The platform default is 50,000 operations. NIST recommends rotating AES-256-GCM keys before 64 GB of data has been encrypted under a single key, so organizations encrypting large payloads should tune maxEncryptCount downward to stay within that boundary.
After a Key rotates, it is never used for new encryption but remains in the system so that previously encrypted data can still be decrypted. The platform tracks which Key was used for each encrypt operation, so decryption always resolves to the correct Key regardless of how many rotations have occurred on the KeyRing.
Key Wrapping: RSA-4096
Every AES-256 key generated by the platform is immediately encrypted using the RSA-4096 public key associated with its KeyRing before it is stored. Grizzly never persists a raw symmetric key. To decrypt any asset, the caller presents the private key, which the platform uses to unwrap the symmetric key and complete the decryption.
Public keys are stored in PEM PKCS1 format. Private keys default to PEM PKCS8 format and can optionally be encrypted at rest using a symmetric cipher and passphrase, which adds a second layer of protection if the key file is exposed. Organizations generating their own key pairs outside of Grizzly's tooling can produce compatible keys with OpenSSL:
openssl genrsa -out private.pem 4096
openssl rsa -in private.pem -pubout -out public.pem
Organizations that manage their own RSA key pairs can destroy the private key to render all data encrypted under a given KeyRing permanently unrecoverable, which is useful for time-limited datasets, expired partner contracts, or regulatory data destruction requirements.
Asset Signing
Asset metadata is signed with asymmetric signatures rather than a shared secret, so verifying a signature never requires access to any signing key. When an asset is signed, the platform computes a SHA-256 hash over the serialized asset metadata together with the encryption envelope, meaning the key data and IV, and signs that hash with the ring's current intermediate signing key. The default suite signs the hash twice, once with Ed25519 and once with ML-DSA-65, and a signature is accepted only when both components verify. Binding the envelope into the hash means a signature covers not just the metadata but the specific encrypted output it was produced for, so a signature cannot be lifted from one asset and attached to different ciphertext.
Signing Hierarchy
Signing is delegated through a two-level key hierarchy so that the long-lived root never has to be online for routine operations. Each KeyRing has a Root Signing Key whose private material is generated and held by the signing service and never leaves it. The root does not sign assets directly. Instead it certifies short-lived Intermediate Signing Keys, each valid for a bounded window that defaults to 24 hours, and the platform uses an intermediate key to sign assets during that window. Every signed asset therefore chains upward: the asset signature verifies under the intermediate key, and the intermediate key's certificate verifies under the ring's published root. A verifier that trusts the ring root can validate any asset the ring produced without ever contacting the signer.
Signing Modes
A signed asset can be produced in one of two modes. In compact mode, which is the default, the asset carries a reference to the intermediate key that certified it, and a verifier resolves the corresponding certificate from the signing service when it needs it. In offline mode, the full certificate is embedded alongside the signature, so the asset is entirely self-contained and can be verified with no network access at all, given only the ring's root public key. Compact mode keeps signed assets small for high-volume workflows, while offline mode suits archival or air-gapped verification.
Verification and Revocation
Verification recomputes the SHA-256 hash from the current metadata and envelope, checks every component of the asset signature against the intermediate key, and checks the intermediate key's certificate against the ring root and its validity window. If the metadata or the envelope has changed, the hash will not match. If any signature component fails, or the certificate is expired or does not chain to the ring root, verification fails. Because a forgery would require defeating every component at once, the signature stays secure as long as any one component's algorithm remains unbroken, which is what allows the classical and post-quantum guarantees to hold at the same time.
Signing authority can be paused or revoked per KeyRing. Pausing stops the signing service from issuing new intermediate keys, so no new assets can be signed on that ring, while assets already signed continue to verify. Revocation invalidates the outstanding intermediate certificates, so signatures that depended on them stop verifying. These controls let an operator freeze or withdraw signing authority for a single ring without affecting any other ring or any previously encrypted data.
Encrypted Output: The Header
When the platform encrypts data, it prepends a binary header to the ciphertext. The header carries the information needed to look up the correct Key for decryption and can embed the IV, a signed asset, or an asset ID as typed blocks.
Header layout (Version 1):
| Field | Size | Description |
|---|---|---|
| Version | 1 byte | Header version (currently 1) |
| Length | 4 bytes | Total header length, big-endian |
| Hash | 14 bytes | 6 bytes KeyRing ID + 8 bytes Key ID |
| Blocks | variable | Zero or more typed data blocks |
Each block contains a 1-byte type identifier, a 4-byte big-endian length field, and the block payload. Three block types are defined:
| Type | Value | Contents |
|---|---|---|
| IV | 1 | The packed nonce (random prefix + counter) used during encryption |
| Asset | 2 | The signed asset: its signature, plus a reference to the certifying intermediate key or, in offline mode, the embedded certificate |
| AssetId | 3 | The asset identifier string |
The 14-byte hash is returned as a standalone value in encrypt responses. Either the full header or the hash can be passed to the decrypt endpoint; the platform uses whichever is provided to resolve the KeyRing and Key, then decrypts accordingly.
Platform Capacity
The hash field in the header allocates 6 bytes to the KeyRing ID and 8 bytes to the Key ID. Those sizes set the theoretical upper bounds on scale:
- KeyRings: up to 281,474,976,710,656 (2^48), which is roughly 892,551 new KeyRings per minute sustained over 10 years.
- Keys per KeyRing: up to approximately 1.89 × 10^19 (2^64), which is roughly 974,904,028 new Keys per second sustained over 10 years.
These limits are inherent to the binary format and are not configurable.
Security Properties
AES-256-GCM with a 32-byte key provides 256-bit symmetric security against brute force. The GCM authentication tag detects any modification to ciphertext before decryption produces output, so a successful decryption is proof the data has not been altered in transit or at rest. RSA-4096 key wrapping means raw symmetric keys are never stored in plaintext and can only be recovered by whoever holds the corresponding private key. Each KeyRing uses a separate RSA key pair, so a key pair compromise is bounded to that KeyRing's data and does not affect others. Key rotation limits the volume of data exposed under any single symmetric key, and rotated keys are retained for decryption of existing data but are never reused for new encryption.
Asset signing adds integrity and provenance guarantees on top of encryption. Because signing uses asymmetric keys, anyone can verify an asset while only the signing service can produce a signature, and the signing root's private material never leaves the customer's custody. The default hybrid suite pairs a classical algorithm with a post-quantum one and requires both to verify, so signed assets stay resistant to forgery even against an adversary with a quantum computer, for as long as either algorithm holds. Short-lived intermediate keys bound the exposure of any single signing key to its validity window, and per-ring pause and revocation controls let an organization withdraw signing authority for one boundary without touching data or signatures in any other.