Skip to content

feat(core)!: conform hybrid PQ/T key formats to IETF drafts#3563

Open
dmihalcik-virtru wants to merge 12 commits into
mainfrom
DSPX-3396-conformant-hybrid-pqt
Open

feat(core)!: conform hybrid PQ/T key formats to IETF drafts#3563
dmihalcik-virtru wants to merge 12 commits into
mainfrom
DSPX-3396-conformant-hybrid-pqt

Conversation

@dmihalcik-virtru
Copy link
Copy Markdown
Member

@dmihalcik-virtru dmihalcik-virtru commented Jun 3, 2026

Summary

Brings the three hybrid PQ/T KEMs (X-Wing, P-256+ML-KEM-768, P-384+ML-KEM-1024) into interop with draft-ietf-lamps-pq-composite-kem-14 and draft-connolly-cfrg-xwing-kem-10 so we can honestly advertise the registered AlgorithmIdentifier OIDs.

  • PEM envelope: hybrid keys now use standard PUBLIC KEY / PRIVATE KEY blocks wrapped in SPKI / PKCS#8. The OID inside the AlgorithmIdentifier (1.3.6.1.5.5.7.6.59, 1.3.6.1.5.5.7.6.63, 1.3.6.1.4.1.62253.25722) selects the scheme; custom block names (SECP256R1 MLKEM768 PUBLIC KEY, XWING PUBLIC KEY, etc.) are gone.
  • NIST byte order flips to draft-14: mlkemPK || ecPoint for public keys, mlkemSeed || ECPrivateKey(RFC 5915 DER) for private keys, mlkemCT || ephemeralECPoint for hybrid ciphertext.
  • NIST combiner is now SHA3-256(mlkemSS || tradSS || tradCT || tradPK || Label) per draft-14 §4.3 — the old HKDF-with-TDF-salt path is removed and salt/info parameters are dropped from the NIST public API. X-Wing's combiner is unchanged (delegated to circl).
  • Dispatcher: FromPublicPEM / FromPrivatePEM route hybrids by OID and fall through to the stdlib x509 path for RSA/EC. All *PrivateKeyFromPem / *UnwrapDEK per-scheme helpers are removed; call sites in sdk/, service/, and otdfctl/ migrated to the dispatcher.

⚠️ Wire-format break for hybrid keys. No on-disk material in the old format was deployed, so no migration tooling is needed. RSA and EC keys are unaffected.

The HybridNISTWrappedKey / XWingWrappedKey ASN.1 envelopes used for the TDF DEK wrap are unchanged — the IETF drafts cover only the KEM.

Benchmark notes

The current benchmark suite measures end-to-end key generation, wrap, and unwrap
paths. It no longer includes the removed sub-operation benchmark, so percentages
such as "KEM encapsulation is 93-97% of wrap time" should not be reported from
these tables alone. Use pprof or reintroduce a dedicated sub-operation
benchmark if a granular breakdown is needed.

The aggregate results still show the main performance shape clearly: RSA-2048
key generation and unwrap remain dominated by RSA private-key work; EC P-384 is
much slower than EC P-256; and the P384+ML-KEM-1024 hybrid is materially slower
than P256+ML-KEM-768 because it combines the larger curve and larger ML-KEM
parameter set. X-Wing and P256+ML-KEM-768 stay in the same broad latency range
for the end-to-end wrap path, while the NIST composites use the draft-14
SHA3-256 combiner instead of HKDF.

Test Plan

  • go test ./... in lib/ocrypto, sdk, service, otdfctl
  • TestREADMECodeBlocks in sdk
  • golangci-lint run --new-from-rev=main reports 0 new issues across all three modules
  • gofumpt -w applied to all modified Go files
  • New conformance tests pin OIDs, combiner labels, public-key concat order, and cross-scheme dispatch rejection
  • End-to-end TDF round-trip via otdfctl with hpqt:secp256r1-mlkem768 and hpqt:xwing keys
  • Verify openssl/other PQ-aware tooling can parse the new SPKI/PKCS#8 PEMs

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Hybrid PQ/T keys now use standard PUBLIC KEY / PRIVATE KEY envelopes with OID-based dispatch and draft-aligned composite formats and labels.
  • Refactor

    • Unified PEM parsing/Encrypt/Decrypt flow for all hybrid schemes; removed per-scheme PEM helpers and salt/info from public encryptor constructors.
    • Wrap/unwrap uses a SHA3-256 combiner and a new hybrid ciphertext ASN.1 envelope and ordering.
  • Tests

    • Added extensive conformance, serialization, and known-answer tests covering hybrid OIDs, formats, and round-trips.
  • Documentation

    • Spec and docs updated to describe the standardized hybrid formats, labels, and acceptance criteria.

@dmihalcik-virtru dmihalcik-virtru requested review from a team as code owners June 3, 2026 18:20
@github-actions github-actions Bot added comp:sdk A software development kit, including library, for client applications and inter-service communicati comp:lib:ocrypto size/xl labels Jun 3, 2026
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request brings the hybrid post-quantum key wrapping schemes (X-Wing and NIST composite KEMs) into full compliance with the latest IETF drafts. By transitioning to standard ASN.1 envelopes and adopting the specified combiners, the implementation ensures interoperability with external PQ-aware tooling. The refactor introduces an OID-based dispatcher for key parsing and simplifies the public API by removing legacy parameters, while maintaining backward compatibility for the TDF-level DEK wrapping container.

Highlights

  • Standardized PEM Envelopes: Migrated hybrid key formats to standard SPKI and PKCS#8 envelopes, replacing custom PEM block headers with OID-based dispatch.
  • IETF Draft Conformance: Updated NIST composite-KEM wire formats and the SHA3-256 combiner to align with draft-ietf-lamps-pq-composite-kem-14.
  • API Simplification: Removed salt and info parameters from the NIST hybrid public API to align with the IETF specification.
  • Conformance Testing: Added comprehensive conformance tests to verify OIDs, combiner labels, and wire-format byte ordering.
New Features

🧠 You can now enable Memory (public preview) to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.


In lattice lands where secrets hide, / The quantum keys now align with pride. / From custom blocks to standard form, / The IETF drafts become the norm.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 3, 2026

Review Change Stack

Warning

Review limit reached

@dmihalcik-virtru, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 34 minutes and 13 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: bbfef90c-c27f-48fa-978a-c95e86295af7

📥 Commits

Reviewing files that changed from the base of the PR and between 2399243 and c9ac7f6.

📒 Files selected for processing (5)
  • lib/ocrypto/BENCHMARK_REPORT.md
  • sdk/tdf_test.go
  • service/internal/security/standard_crypto.go
  • service/internal/security/standard_crypto_test.go
  • test/start-up-with-containers/action.yaml
📝 Walkthrough

Walkthrough

This PR refactors hybrid post-quantum key wrapping formats (NIST EC+ML-KEM composites and X-Wing) to conform to IETF draft specifications. Changes include new ASN.1 serialization helpers, OID-based dispatcher routing, updated hybrid core implementations with SHA3-256 key derivation and byte-ordering adjustments, conformance tests, and cascading integration updates across SDK and service layers.

Changes

Hybrid PQ Key Format Refactor

Layer / File(s) Summary
ASN.1 and OID foundation
lib/ocrypto/pem_blocks.go, lib/ocrypto/pq_oids.go, lib/ocrypto/pq_asn1.go, lib/ocrypto/pq_asn1_test.go
Adds strict SPKI/PKCS#8 marshal/parse helpers, defines hybrid OIDs and cached DER encodings, domain-separation label constants, and generic PEM block labels for hybrid routing.
PEM dispatcher / tri-state routing
lib/ocrypto/asym_encryption.go, lib/ocrypto/asym_decryption.go
Parses SPKI/PKCS#8 envelopes to detect hybrid OIDs via hybridEncryptorFromSPKI/hybridDecryptorFromPKCS8, returns matched encryptor/decryptor for known hybrids, rejects certificate-wrapped hybrids, and falls back to legacy RSA/EC parsing when not matched.
NIST composite-KEM core
lib/ocrypto/hybrid_nist.go, lib/ocrypto/HYBRID_NIST_KEY_WRAPPING.md, lib/ocrypto/hybrid_nist_test.go
Rewrites hybrid keypair generation and serialization to `mlkemPK
X-Wing & hybrid common wrapper
lib/ocrypto/xwing.go, lib/ocrypto/xwing_test.go, lib/ocrypto/hybrid_common.go
Standardizes X-Wing PEM to SPKI/PKCS#8, adds KeyType to X-Wing decryptor, and changes HybridWrapDEK to dispatch via FromPublicPEM and call encryptor.Encrypt instead of scheme-specific routing.
Conformance & KAT tests
lib/ocrypto/hybrid_conformance_test.go
Adds tests pinning hybrid OIDs, asserting combiner label bytes, verifying SPKI public-key concat order and EC uncompressed SEC1 format, checking certificate rejection and absent AlgorithmIdentifier parameters, and Known Answer Tests for the SHA3-256 combiner.
Benchmark refactoring
lib/ocrypto/benchmark_test.go, lib/ocrypto/BENCHMARK_REPORT.md
Routes benchmarked hybrid wrap/unwrap through unified dispatcher (FromPublicPEM/FromPrivatePEM) and shortens benchmark report text and labels.
SDK & service integration
sdk/experimental/tdf/key_access_test.go, sdk/experimental/tdf/writer_test.go, sdk/tdf_hybrid_test.go, sdk/tdf_test.go, service/internal/security/basic_manager.go, service/internal/security/standard_crypto.go
Replaces per-algorithm unwrap helpers with FromPrivatePEM(...).Decrypt(...), updates mock fixtures and KAS rewrap handler, adds runtime decryptor algorithm alignment checks, and updates tests/formatting accordingly.
Documentation & spec
lib/ocrypto/HYBRID_NIST_KEY_WRAPPING.md, spec/DSPX-3396.md
Updates the NIST hybrid spec to match draft-14 (combiner, ordering, ASN.1 container) and adds a project spec describing the refactor scope and acceptance criteria.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant HybridWrap as HybridNISTWrapDEK
  participant ECDH
  participant MLKEM
  participant Combiner as SHA3-256
  participant AES as AES-256-GCM

  Client->>HybridWrap: DEK + hybrid SPKI public key
  HybridWrap->>HybridWrap: parse SPKI -> split mlkemPK || ecPoint
  HybridWrap->>ECDH: ECDH with ephemeral EC key / tradPK -> tradSS, tradCT
  HybridWrap->>MLKEM: encapsulate mlkemPK -> mlkemSS, mlkemCT
  HybridWrap->>Combiner: derive SHA3-256(mlkemSS||tradSS||tradCT||tradPK||Label)
  Combiner-->>HybridWrap: wrapKey
  HybridWrap->>AES: AES-GCM encrypt DEK with wrapKey
  AES-->>HybridWrap: encryptedDEK (nonce||ciphertext||tag)
  HybridWrap->>Client: HybridNISTWrappedKey ASN.1 (hybridCiphertext = mlkemCT||ephemeralECPub, encryptedDEK)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • opentdf/platform#3276: Implements/adjusts hybrid NIST EC+ML-KEM wrapping support including hybrid key parsing, dispatch, and P-256+ML-KEM-768 / P-384+ML-KEM-1024 wrap/unwrap flows.
  • opentdf/platform#3564: Overlapping changes in BasicManager.unwrap logging/error formatting and related hybrid unwrap handling.

Suggested labels

comp:kas, pqc, docs

Suggested reviewers

  • sujankota
  • elizabethhealy

Poem

🐰 I stitched a key with careful care,
OIDs and SHA3 bound secrets there,
SPKI holds the public part,
PKCS#8 keeps the private heart,
Hop—standards bloom, cryptography fair.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 41.25% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly and specifically describes the main change: conforming hybrid PQ/T key formats to IETF drafts. It directly relates to the core purpose of this large refactoring.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch DSPX-3396-conformant-hybrid-pqt

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request aligns the hybrid post-quantum/traditional (PQ/T) key formats with the IETF drafts, specifically draft-ietf-lamps-pq-composite-kem-14 for NIST composite-KEM (P-256/P-384 + ML-KEM) and draft-connolly-cfrg-xwing-kem-10 for X-Wing. It replaces custom PEM block headers with standard PUBLIC KEY and PRIVATE KEY blocks wrapped in SPKI and PKCS#8 envelopes, routing decryption and encryption via AlgorithmIdentifier OIDs. Additionally, it updates the NIST hybrid combiner to use the draft-specified SHA3-256 scheme with domain-separation labels and identity binding, removing the previous HKDF-SHA256 concatenation. All tests, benchmarks, and external call sites have been updated to support these conformant formats. There are no review comments on this pull request, so no further feedback is provided.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 3, 2026

Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 205.597074ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 158.523287ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 434.24575ms
Throughput 230.28 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 43.505948029s
Average Latency 431.390049ms
Throughput 114.93 requests/second

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
sdk/experimental/tdf/writer_test.go (1)

897-910: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Assert the exact DEK in the hybrid unwrap helper.

assert.NotEmpty(dek) will still pass if the dispatcher returns the wrong bytes, so these new hybrid-path tests no longer prove unwrap correctness. Pass the expected DEK into hybridUnwrapForTest and compare it byte-for-byte.

Suggested tightening
-func hybridUnwrapForTest(t *testing.T, ktype ocrypto.KeyType, privatePEM, wrappedKeyB64 string) {
+func hybridUnwrapForTest(t *testing.T, ktype ocrypto.KeyType, privatePEM, wrappedKeyB64 string, expectedDEK []byte) {
 	t.Helper()
 	wrappedDER, err := ocrypto.Base64Decode([]byte(wrappedKeyB64))
 	require.NoError(t, err, "Base64Decode wrapped key")

 	dec, err := ocrypto.FromPrivatePEM(privatePEM)
 	require.NoError(t, err, "FromPrivatePEM")
 	dek, err := dec.Decrypt(wrappedDER)
 	require.NoError(t, err, "hybrid Decrypt")
-	assert.NotEmpty(t, dek, "%s recovered DEK", ktype)
+	assert.Equal(t, expectedDEK, dek, "%s recovered DEK", ktype)
}

Update the hybrid call sites to pass a copy of the writer DEK they expect to recover.

As per coding guidelines, "Run go test ./... or make test and ensure all existing tests pass; add tests for new functionality".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sdk/experimental/tdf/writer_test.go` around lines 897 - 910,
hybridUnwrapForTest currently only asserts dek is non-empty; change its
signature (hybridUnwrapForTest) to accept an expectedDEK []byte and after
Decrypt compare the recovered dek to expectedDEK byte-for-byte (use the existing
test assertion helpers, e.g., require.Equal/ assert.Equal) with a helpful
message; update all call sites to pass a copy of the writer DEK they expect to
recover (not the original slice if it may be mutated) so the tests validate
exact DEK equality.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@lib/ocrypto/hybrid_common.go`:
- Around line 8-20: HybridWrapDEK must reject non-hybrid key types before using
the dispatcher: in HybridWrapDEK (which calls FromPublicPEM and later
enc.Encrypt), first ensure the requested ktype is a hybrid kind (or explicitly
check that enc.Type() == Hybrid after FromPublicPEM) and return an error if not;
do not rely solely on enc.KeyType() matching ktype because FromPublicPEM may
return RSA/EC encryptors—add a guard that verifies ktype is hybrid (or asserts
enc.Type() == Hybrid) and only then call enc.Encrypt(dek).

In `@lib/ocrypto/hybrid_conformance_test.go`:
- Around line 45-123: Add explicit assertions that the PKCS#8 private-key
payload and the wrapped ciphertext follow the pinned concatenation layouts:
after generating a keypair with NewP256MLKEM768KeyPair (and the P384 analog),
call PrivateKeyInPemFormat/FromPrivatePEM and parse the PKCS#8 payload to assert
it is mlkemSeed || ECPrivateKey(DER) (use the MLKEM seed size constant like
P256MLKEM768MLKEMSeedSize and the EC private-key DER size constant) and likewise
after wrapping with FromPublicPEM/Encrypt, parse the wrapped blob to assert it
is mlkemCT || ephemeralECPub (use the MLKEM ciphertext size constant and the EC
public-key size constant) before calling Decrypt; add equivalent checks for the
P384/MLKEM1024/ephemeral curve symbols to ensure both private and wrapped
layouts are validated.

In `@lib/ocrypto/HYBRID_NIST_KEY_WRAPPING.md`:
- Around line 33-37: The fenced code blocks in this doc (e.g., the block
starting with "SubjectPublicKeyInfo { AlgorithmIdentifier ... }" and the other
fenced sections called out in the review) need explicit language tags to satisfy
markdownlint MD040; update each triple-backtick fence to include an appropriate
identifier (asn1, text, json, etc.) so the blocks render consistently and
lint-clean. Locate each fenced block (examples include the SubjectPublicKeyInfo
block and the other blocks referenced in the review) and add the correct
language token immediately after the opening ``` for that block.

In `@lib/ocrypto/pq_asn1.go`:
- Around line 52-64: The parseHybridSPKI function currently ignores
AlgorithmIdentifier.Parameters; update parseHybridSPKI to reject any SPKI whose
Algorithm.Parameters is present or non-empty (i.e., ensure
spki.Algorithm.Parameters is absent/zero-length) and return an error like "parse
SPKI: unexpected algorithm parameters" when parameters exist; apply the same
check to the corresponding PKCS#8 parser (the private-key parser handling
AlgorithmIdentifier.Parameters around the other block mentioned) so both
subjectPublicKeyInfo/parseHybridSPKI and the PKCS#8 parsing path enforce "OID
with no parameters" by validating Algorithm.Parameters before accepting the key
bytes.

In `@service/internal/security/standard_crypto.go`:
- Around line 523-529: The code decrypts with
ocrypto.FromPrivatePEM(key.hybridPrivateKeyPem) but never verifies that the
parsed private key actually implements the hybrid algorithm declared in
key.Algorithm; add a validation step after dec is obtained that compares the
parsed key's algorithm identifier to key.Algorithm (e.g. use dec.Algorithm /
dec.Scheme or call a provided Algorithm() / Type() accessor on the returned dec
object, or inspect its concrete params) and return an error if they differ, so
misconfigured keys are rejected up front instead of being used for decryption.

---

Outside diff comments:
In `@sdk/experimental/tdf/writer_test.go`:
- Around line 897-910: hybridUnwrapForTest currently only asserts dek is
non-empty; change its signature (hybridUnwrapForTest) to accept an expectedDEK
[]byte and after Decrypt compare the recovered dek to expectedDEK byte-for-byte
(use the existing test assertion helpers, e.g., require.Equal/ assert.Equal)
with a helpful message; update all call sites to pass a copy of the writer DEK
they expect to recover (not the original slice if it may be mutated) so the
tests validate exact DEK equality.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: f4b1c244-8169-4928-8305-1253209a2dbe

📥 Commits

Reviewing files that changed from the base of the PR and between 79ab34f and b760618.

📒 Files selected for processing (21)
  • lib/ocrypto/HYBRID_NIST_KEY_WRAPPING.md
  • lib/ocrypto/asym_decryption.go
  • lib/ocrypto/asym_encryption.go
  • lib/ocrypto/benchmark_test.go
  • lib/ocrypto/hybrid_common.go
  • lib/ocrypto/hybrid_conformance_test.go
  • lib/ocrypto/hybrid_nist.go
  • lib/ocrypto/hybrid_nist_test.go
  • lib/ocrypto/pem_blocks.go
  • lib/ocrypto/pq_asn1.go
  • lib/ocrypto/pq_asn1_test.go
  • lib/ocrypto/pq_oids.go
  • lib/ocrypto/xwing.go
  • lib/ocrypto/xwing_test.go
  • sdk/experimental/tdf/key_access_test.go
  • sdk/experimental/tdf/writer_test.go
  • sdk/tdf_hybrid_test.go
  • sdk/tdf_test.go
  • service/internal/security/basic_manager.go
  • service/internal/security/standard_crypto.go
  • spec/DSPX-3396.md

Comment thread lib/ocrypto/hybrid_common.go
Comment thread lib/ocrypto/hybrid_conformance_test.go
Comment thread lib/ocrypto/HYBRID_NIST_KEY_WRAPPING.md Outdated
Comment thread lib/ocrypto/pq_asn1.go
Comment thread service/internal/security/standard_crypto.go
@dmihalcik-virtru dmihalcik-virtru marked this pull request as draft June 3, 2026 19:52
dmihalcik-virtru added a commit that referenced this pull request Jun 4, 2026
PR #3563 review surfaced gaps at the edges of the IETF-draft conformance
work. Tightens dispatch, adds spec-anchored KATs, and corrects citations
that had drifted between draft revisions.

- Dispatcher: distinguish unknown-hybrid-OID from non-envelope so
  unrecognised hybrid OIDs no longer silently retry as RSA/EC; reject
  CERTIFICATE PEM blocks carrying a hybrid SPKI.
- KAS decrypt sites cross-check the OID-routed decryptor's KeyType
  against keyDetails.Algorithm before trusting it.
- Combiner asserts input lengths and is anchored byte-for-byte to the
  lamps-wg/draft-composite-kem reference KATs for both NIST hybrids.
- HybridNISTDecryptor parses and validates the EC DER tail at
  construction, mirroring the encryptor's strictness.
- Six-way cross-scheme dispatch rejection test (table-driven).
- pq_asn1: reject non-absent AlgorithmIdentifier.Parameters per
  draft-14 §6 / draft-10 §5.8.
- X-Wing: inline TODO(DSPX-TBD) noting the draft-05 primitive vs.
  draft-10 wire-format split until cloudflare/circl ships draft-10.
- Doc/spec citation sweep across hybrid_nist.go, pq_oids.go,
  hybrid_common.go, HYBRID_NIST_KEY_WRAPPING.md; trim stale
  BenchmarkHybridSubOps references from BENCHMARK_REPORT.md.

Signed-off-by: Dave Mihalcik <dmihalcik@virtru.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 4, 2026

Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 145.532439ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 80.035564ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 395.88183ms
Throughput 252.60 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 41.08489646s
Average Latency 409.250317ms
Throughput 121.70 requests/second

dmihalcik-virtru and others added 5 commits June 4, 2026 17:40
conformant hybrid pqt
Rewrite the spec body from the Jira ticket as the source of truth so
tables, headings, and bullet lists render correctly. The original import
had collapsed all table rows into single lines and dropped the section
headings.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: Dave Mihalcik <dmihalcik@virtru.com>
Brings the three hybrid PQ/T KEMs (X-Wing, P-256+ML-KEM-768,
P-384+ML-KEM-1024) into interop with draft-ietf-lamps-pq-composite-kem-14
and draft-connolly-cfrg-xwing-kem-10 so we can honestly advertise the
registered AlgorithmIdentifier OIDs.

- Public/private keys now use standard `PUBLIC KEY` / `PRIVATE KEY` PEM
  blocks wrapped in SPKI / PKCS#8; the OID inside the AlgorithmIdentifier
  selects the scheme (no more custom block names).
- NIST hybrids flip to draft-14 byte order: `mlkemPK || ecPoint` for
  public keys, `mlkemSeed || ECPrivateKey(RFC 5915 DER)` for private
  keys, `mlkemCT || ephemeralECPoint` for hybrid ciphertext.
- NIST combiner is now `SHA3-256(mlkemSS || tradSS || tradCT || tradPK
  || Label)` per draft-14 §4.3 — the old HKDF-with-TDF-salt path is
  removed and `salt`/`info` parameters are dropped from the NIST public
  API. X-Wing's combiner is unchanged (delegated to circl).
- `FromPublicPEM` / `FromPrivatePEM` dispatch hybrids by OID and fall
  through to the stdlib x509 path for RSA/EC.

This is a wire-format break for hybrid keys. No on-disk material in the
old format was deployed, so no migration tooling is needed.

Signed-off-by: Dave Mihalcik <dmihalcik@virtru.com>
PR #3563 review surfaced gaps at the edges of the IETF-draft conformance
work. Tightens dispatch, adds spec-anchored KATs, and corrects citations
that had drifted between draft revisions.

- Dispatcher: distinguish unknown-hybrid-OID from non-envelope so
  unrecognised hybrid OIDs no longer silently retry as RSA/EC; reject
  CERTIFICATE PEM blocks carrying a hybrid SPKI.
- KAS decrypt sites cross-check the OID-routed decryptor's KeyType
  against keyDetails.Algorithm before trusting it.
- Combiner asserts input lengths and is anchored byte-for-byte to the
  lamps-wg/draft-composite-kem reference KATs for both NIST hybrids.
- HybridNISTDecryptor parses and validates the EC DER tail at
  construction, mirroring the encryptor's strictness.
- Six-way cross-scheme dispatch rejection test (table-driven).
- pq_asn1: reject non-absent AlgorithmIdentifier.Parameters per
  draft-14 §6 / draft-10 §5.8.
- X-Wing: inline TODO(DSPX-TBD) noting the draft-05 primitive vs.
  draft-10 wire-format split until cloudflare/circl ships draft-10.
- Doc/spec citation sweep across hybrid_nist.go, pq_oids.go,
  hybrid_common.go, HYBRID_NIST_KEY_WRAPPING.md; trim stale
  BenchmarkHybridSubOps references from BENCHMARK_REPORT.md.

Signed-off-by: Dave Mihalcik <dmihalcik@virtru.com>
@dmihalcik-virtru dmihalcik-virtru force-pushed the DSPX-3396-conformant-hybrid-pqt branch from b0e0034 to 6058b41 Compare June 4, 2026 21:45
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 4, 2026

Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 172.686569ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 87.52129ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 442.367026ms
Throughput 226.06 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 43.696344224s
Average Latency 434.638033ms
Throughput 114.43 requests/second

@dmihalcik-virtru dmihalcik-virtru marked this pull request as ready for review June 4, 2026 22:13
@dmihalcik-virtru dmihalcik-virtru changed the title feat(ocrypto)!: conform hybrid PQ/T key formats to IETF drafts (DSPX-3396) feat(core)!: conform hybrid PQ/T key formats to IETF drafts Jun 4, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
sdk/experimental/tdf/writer_test.go (1)

897-910: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Strengthen hybridUnwrapForTest to assert DEK equality (not just non-empty).

The helper only checks assert.NotEmpty(t, dek, ...) after dec.Decrypt(...). A regression that decrypts to the wrong (but non-empty) DEK would still pass; the hybrid wrap/unwrapped key material should be byte-for-byte compared (callers can pass the writer’s DEK).

Suggested tightening
-func hybridUnwrapForTest(t *testing.T, ktype ocrypto.KeyType, privatePEM, wrappedKeyB64 string) {
+func hybridUnwrapForTest(t *testing.T, ktype ocrypto.KeyType, privatePEM, wrappedKeyB64 string, expectedDEK []byte) {
 	t.Helper()
 	wrappedDER, err := ocrypto.Base64Decode([]byte(wrappedKeyB64))
 	require.NoError(t, err, "Base64Decode wrapped key")

 	dec, err := ocrypto.FromPrivatePEM(privatePEM)
 	require.NoError(t, err, "FromPrivatePEM")
 	dek, err := dec.Decrypt(wrappedDER)
 	require.NoError(t, err, "hybrid Decrypt")
-	assert.NotEmpty(t, dek, "%s recovered DEK", ktype)
+	assert.Equal(t, expectedDEK, dek, "%s recovered DEK", ktype)
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sdk/experimental/tdf/writer_test.go` around lines 897 - 910,
hybridUnwrapForTest currently only asserts the decrypted DEK is non-empty;
change it to accept an expected DEK parameter and assert byte-for-byte equality
against the decrypted value. Specifically, update the function signature
hybridUnwrapForTest(t *testing.T, ktype ocrypto.KeyType, privatePEM,
wrappedKeyB64 string, expectedDEK []byte), keep Base64Decode and
FromPrivatePEM/dec.Decrypt as-is, replace assert.NotEmpty(t, dek, ...) with
assert.Equal(t, expectedDEK, dek, "%s recovered DEK matches expected", ktype),
and update all callers to pass the writer’s original DEK into the new
expectedDEK parameter.
♻️ Duplicate comments (1)
service/internal/security/standard_crypto.go (1)

509-553: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Reject mislabeled hybrid/X-Wing keys during load, not on first decrypt.

assertDecryptorAlgorithm closes the hole at decrypt time, but loadKey still buckets these PEMs under keysByAlg[k.Algorithm] without validating the routed KeyType() up front. A misconfigured key can still be advertised under the wrong algorithm and only fail once traffic reaches Decrypt(). Parse and compare the private PEM in loadKey so bad config is rejected at startup instead of surfacing as an interoperability break later.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@service/internal/security/standard_crypto.go` around lines 509 - 553, loadKey
currently buckets PEMs into keysByAlg without validating the routed decryptor
type, so mislabelled hybrid/X-Wing keys only fail at first Decrypt; fix by
parsing the private PEM in loadKey with ocrypto.FromPrivatePEM, cast to the
interface{ KeyType() ocrypto.KeyType } (or simply call
assertDecryptorAlgorithm(dec, key.Algorithm, kid)) and compare kt.KeyType() to
key.Algorithm, and if mismatched return an error and refuse to load the key
(ensuring keysByAlg only stores validated keys); apply this check for the
hybrid/X-Wing branches before inserting into keysByAlg.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@lib/ocrypto/BENCHMARK_REPORT.md`:
- Around line 95-100: The benchmark text incorrectly claims "HKDF, AES-GCM, and
ASN.1 marshaling are all sub-microsecond" for "all hybrid schemes" even though
the NIST composite KEMs now follow the new combiner path (no
HKDF-with-TDF-salt), conflating X-Wing and NIST composites; update the paragraph
in BENCHMARK_REPORT.md to either (a) use scheme-neutral wording that refers to
"combine/hash operations" or "post-encapsulation hashing/combining" instead of
naming HKDF for all schemes, and call out that X-Wing uses HKDF-related work
while NIST composites follow the new combiner path, or (b) split the note into
two sentences that separately report X-Wing behavior (mention HKDF cost) and
NIST composite behavior (mention combiner/hash cost), preserving the per-scheme
latency comparisons (P-256 vs P-384 and ML-KEM-768/1024) and advising
re-introduction of per-op pprof breakdown if needed.

In `@sdk/tdf_test.go`:
- Around line 3103-3106: In the "hybrid-wrapped" fake KAS path in
sdk/tdf_test.go, after creating the decryptor with
ocrypto.FromPrivatePEM(kasPrivateKey) and before calling
dec.Decrypt(wrappedKey), assert the decryptor's KeyType() is present and equals
f.Algorithm (use f.s.Require().NotNil/Require().NotEmpty on dec.KeyType() and
f.s.Require().Equal to compare to f.Algorithm), and fail the test if the types
mismatch, mirroring the production checks in
basic_manager.go/standard_crypto.go.

In `@test/start-up-with-containers/action.yaml`:
- Around line 174-177: The if condition currently uses the raw input expression
"if: ${{ inputs.pqc-enabled }}" which treats any non-empty string (including
"false") as truthy; change the gate to explicitly compare the input string to
'true' (for example using "if: ${{ inputs.pqc-enabled == 'true' }}" or the
equals() expression) so the PQC step only runs when inputs.pqc-enabled is
exactly the string 'true'.

---

Outside diff comments:
In `@sdk/experimental/tdf/writer_test.go`:
- Around line 897-910: hybridUnwrapForTest currently only asserts the decrypted
DEK is non-empty; change it to accept an expected DEK parameter and assert
byte-for-byte equality against the decrypted value. Specifically, update the
function signature hybridUnwrapForTest(t *testing.T, ktype ocrypto.KeyType,
privatePEM, wrappedKeyB64 string, expectedDEK []byte), keep Base64Decode and
FromPrivatePEM/dec.Decrypt as-is, replace assert.NotEmpty(t, dek, ...) with
assert.Equal(t, expectedDEK, dek, "%s recovered DEK matches expected", ktype),
and update all callers to pass the writer’s original DEK into the new
expectedDEK parameter.

---

Duplicate comments:
In `@service/internal/security/standard_crypto.go`:
- Around line 509-553: loadKey currently buckets PEMs into keysByAlg without
validating the routed decryptor type, so mislabelled hybrid/X-Wing keys only
fail at first Decrypt; fix by parsing the private PEM in loadKey with
ocrypto.FromPrivatePEM, cast to the interface{ KeyType() ocrypto.KeyType } (or
simply call assertDecryptorAlgorithm(dec, key.Algorithm, kid)) and compare
kt.KeyType() to key.Algorithm, and if mismatched return an error and refuse to
load the key (ensuring keysByAlg only stores validated keys); apply this check
for the hybrid/X-Wing branches before inserting into keysByAlg.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 71c8b994-4efb-4b9f-bfc8-46912561e136

📥 Commits

Reviewing files that changed from the base of the PR and between b760618 and 6058b41.

📒 Files selected for processing (24)
  • lib/ocrypto/BENCHMARK_REPORT.md
  • lib/ocrypto/HYBRID_NIST_KEY_WRAPPING.md
  • lib/ocrypto/asym_decryption.go
  • lib/ocrypto/asym_encryption.go
  • lib/ocrypto/benchmark_test.go
  • lib/ocrypto/hybrid_common.go
  • lib/ocrypto/hybrid_conformance_test.go
  • lib/ocrypto/hybrid_nist.go
  • lib/ocrypto/hybrid_nist_test.go
  • lib/ocrypto/pem_blocks.go
  • lib/ocrypto/pq_asn1.go
  • lib/ocrypto/pq_asn1_test.go
  • lib/ocrypto/pq_oids.go
  • lib/ocrypto/xwing.go
  • lib/ocrypto/xwing_test.go
  • sdk/experimental/tdf/key_access_test.go
  • sdk/experimental/tdf/writer_test.go
  • sdk/tdf_hybrid_test.go
  • sdk/tdf_test.go
  • service/internal/security/basic_manager.go
  • service/internal/security/standard_crypto.go
  • spec/DSPX-3396.md
  • test/start-additional-kas/action.yaml
  • test/start-up-with-containers/action.yaml

Comment thread lib/ocrypto/BENCHMARK_REPORT.md Outdated
Comment thread sdk/tdf_test.go
Comment thread test/start-up-with-containers/action.yaml Outdated
@dmihalcik-virtru
Copy link
Copy Markdown
Member Author

Addressed the outside-diff writer test note in 2399243: hybridUnwrapForTest now compares the recovered DEK byte-for-byte against a copied writer DEK for X-Wing, P-256+ML-KEM-768, and P-384+ML-KEM-1024.

Validation run locally:

  • ~/go/bin/gofumpt -w ... on touched Go files
  • go test -count=1 ./lib/ocrypto/... ./sdk/experimental/tdf/...
  • golangci-lint run ./lib/ocrypto/...
  • cd sdk && golangci-lint run ./experimental/tdf
  • cd sdk && go test -run TestREADMECodeBlocks
  • git diff --check

make test was also attempted. It passes lib/ocrypto but stops in lib/fixtures because the local Keycloak token lifetime is 60s while those tests expect the default/custom token buffer values (120s/60s); this appears unrelated to the PR feedback changes.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 5, 2026

Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 178.974846ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 92.647424ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 430.120356ms
Throughput 232.49 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 44.839579029s
Average Latency 445.544074ms
Throughput 111.51 requests/second

Signed-off-by: Dave Mihalcik <dmihalcik@virtru.com>
@dmihalcik-virtru
Copy link
Copy Markdown
Member Author

dmihalcik-virtru commented Jun 5, 2026

Addressed the latest CodeRabbit review-summary items in 492a55d:

  • Updated BENCHMARK_REPORT.md to avoid applying HKDF wording to all hybrid schemes; it now distinguishes X-Wing’s HKDF-based TDF wrap path from the NIST draft-14 SHA3-256 combiner.
  • Added fake-KAS test-side validation in sdk/tdf_test.go that the OID-routed hybrid decryptor exposes a KeyType() matching the fake KAS algorithm. The dependent cast uses Require, and the algorithm comparison uses the suite assert shorthand (f.s.Equal).
  • Changed the container action PQC gate to inputs.pqc-enabled == 'true' so the string false is not treated as truthy.
  • Added load-time validation for X-Wing and NIST hybrid private PEMs in standard_crypto.go, plus a regression test proving mislabeled hybrid keys are rejected at startup.
  • The outside-diff hybridUnwrapForTest DEK equality item was already addressed in 2399243.

Validation:

  • go test -count=1 ./lib/ocrypto/... ./service/internal/security/... ./sdk/experimental/tdf/...
  • cd sdk && go test -count=1 . (with localhost listener access for httptest)
  • cd sdk && go test -run TestREADMECodeBlocks
  • golangci-lint run --new-from-rev 2399243697d53408b2f84b78c8095c8ab8caaa9f ./lib/ocrypto/... ./sdk/... ./service/internal/security/...
  • git diff --check

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 5, 2026

Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 177.642834ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 95.611458ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 420.122459ms
Throughput 238.03 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 45.467170899s
Average Latency 452.660857ms
Throughput 109.97 requests/second

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 5, 2026

X-Test Failure Report

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 5, 2026

Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 174.624784ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 91.856069ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 688.241668ms
Throughput 145.30 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 43.963146538s
Average Latency 437.612222ms
Throughput 113.73 requests/second

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 5, 2026

Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 184.170236ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 97.030673ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 416.031882ms
Throughput 240.37 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 43.562284797s
Average Latency 433.517375ms
Throughput 114.78 requests/second

sujankota
sujankota previously approved these changes Jun 5, 2026
dmihalcik-virtru and others added 2 commits June 5, 2026 13:47
The watch-sh-fix tag predates PQC support in init-temp-keys.sh, so
kas-xwing-private.pem and related files were never generated. The
pqc-enabled tag points to main HEAD which already runs
`go run ./service/cmd/keygen` to produce the PQC key pairs needed by
start-additional-kas when pqc-enabled is true.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Dave Mihalcik <dmihalcik@virtru.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 5, 2026

Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 150.154927ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 81.12083ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 413.938575ms
Throughput 241.58 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 42.073531341s
Average Latency 419.002033ms
Throughput 118.84 requests/second

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 5, 2026

⚠️ Govulncheck found vulnerabilities ⚠️

The following modules have known vulnerabilities:

  • examples
  • otdfctl
  • sdk
  • service
  • lib/fixtures
  • tests-bdd

See the workflow run for details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp:lib:ocrypto comp:sdk A software development kit, including library, for client applications and inter-service communicati size/xl

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants