Skip to content

perf: hash arena identities without SipHash in content tables - #370

Merged
polaz merged 4 commits into
mainfrom
perf/#368-seeded-identity-hash
Nov 2, 2026
Merged

polaz merged 4 commits into
mainfrom
perf/#368-seeded-identity-hash

Conversation

@polaz

@polaz polaz commented Nov 2, 2026 •

Copy link
Copy Markdown
Member

Summary

  • Content-keyed hash tables hash arena identities with a seeded integer mix instead of SipHash, using the shared structured_asn1::hash::RandomState; strings keep the randomly keyed SipHash, and a document still cannot predict bucket positions.
  • XPath node-set deduplication, which hashes a document identity and a slot for every selected node, costs a fraction of what it did.
  • Signing dependency analysis keeps every value a value-reading XPath can reach as a dependency, even when Enveloped later removes it, so a Reference whose selection reads its own DigestValue is refused instead of signed with a digest that does not verify.

Changes

  • The Map/Set aliases for content-keyed tables use structured_asn1::hash::RandomState (each table independently seeded; strings and every word after one go through the keyed byte hasher in order). This crate keeps only the aliases; tables are built with Default.
  • structured-asn1 0.20.2 is a required dependency, since content tables exist without signature support; the shared structured-* crates resolve to 0.20.2 together.
  • Without std the tables remain ordered trees.
  • The dependency-analysis early stop applies only before an octet-consuming step.
  • A value-reading XPath step records the tracked values it can read as dependencies whether or not they stay in its output.
  • The competitor benchmark lockfile follows the structured-asn1 bump.

Testing

Workspace tests with all features (including the xmlsec1 and libxslt oracles), the PKCS#11 suite, Clippy, feature-profile lints, the no-std targets, the fuzz build, the shared-crate graph check and the compatibility ledgers pass on macOS; Linux and Windows run in CI.

Closes #368

@coderabbitai

coderabbitai Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 13 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
Commits

Reviewing files that changed from the base of the PR and between b8b2cd8 and 3c8b4f7.

Files selected for processing: 2
  • src/xmldsig/sign/single_execution_tests.rs
  • src/xmldsig/transforms.rs
Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between dc989d4 and 437f493.

Files selected for processing: 5
  • Cargo.toml
  • src/collections.rs
  • src/xmldsig/sign.rs
  • src/xmldsig/sign/single_execution_tests.rs
  • src/xmldsig/transforms.rs

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

Walkthrough

The PR adds per-table seeded hashing to standard map and set aliases, updates collection initialization sites, and changes XML signature transform dependency handling. A new test checks signing and digest values for a reference with XPath, Enveloped Signature, and exclusive canonicalization transforms.

Changes: Seeded hashing and XML signature transforms

Layer / File(s) Summary
Seeded collection aliases
Cargo.toml, src/collections.rs, src/collections/tests.rs
The standard Map and Set aliases use SeededState. structured-asn1 is updated and enabled through the std feature. Tests check hash consistency, distribution, and variation between default states.
Collection initialization updates
src/key_manager.rs, src/operation.rs, src/parser_xmloxide/validation/dtd.rs, src/sxd_document/lazy_hash_map.rs, src/sxd_xpath/..., src/xml.rs, src/xml/dom/..., src/xmldsig/verify.rs, src/xmldsig/verify/tests.rs, src/xmldsig/xpath/storage.rs, scripts/patches/xmloxide-0.5.0.patch
Map and set initialization sites use Default or the project’s Map and Set aliases. The corresponding DTD validation patch changes its local set initialization to Default.
Transform dependency handling
src/xmldsig/transforms.rs, src/xmldsig/sign.rs, src/xmldsig/sign/single_execution_tests.rs
Node-set transforms can run while dependencies are tracked, allowing later transforms to remove tracked nodes before dependency status is settled. Signing dependency sets use the shared Set type. A test checks signing and recomputed digest values.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Merge Risk: Low · previous review 437f4

The change moves content-keyed tables to seeded hashing and fixes the false dependency-cycle error when signing with XPath, Enveloped and canonicalization transforms. One existing gap remains in this area. An XPath that reads a DigestValue and is followed by an Enveloped transform can still sign with a mismatched digest. It is not made worse by this PR, so it is worth fixing soon but is a bounded concern.

Pre-merge checks: Passed 3 · Failed 2

Failed Failed checks: 2 warnings

Check name Status Explanation Resolution
Out of Scope Changes check Warning The hashing aliases, their constructors, and related call-site updates support #368. However, src/xmldsig/transforms.rs also changes signing dependency analysis so node-set transforms continue after… Remove the signing dependency-analysis change and its dedicated test from this PR, or link the change to an active issue with its own coding requirements. Then reassess the PR scope.
Docstring Coverage Warning Docstring coverage is 38.46% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documenta… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 3 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main performance change: using a non-SipHash strategy for hash-based content tables.
Linked Issues check Passed #368 is the only active directly linked issue. The std aliases in src/collections.rs now use structured_asn1::hash::RandomState, with a new seed for each table. The non-std aliases remain `BTr…
Full details: Linked Issues check

Explanation

#368 is the only active directly linked issue. The std aliases in src/collections.rs now use structured_asn1::hash::RandomState, with a new seed for each table. The non-std aliases remain BTreeMap and BTreeSet. The collection tests cover equal hashes, strided integer-key spread, control-byte coverage, and independent table seeds. The changed constructors preserve the existing table behavior. The reported workspace and compatibility tests provide no contrary evidence for document acceptance, outputs, or typed errors. The requested before/after CPU measurement is a non-coding task and does not affect this coding assessment.

Full details: Out of Scope Changes check

Explanation

The hashing aliases, their constructors, and related call-site updates support #368. However, src/xmldsig/transforms.rs also changes signing dependency analysis so node-set transforms continue after dependency detection. The added signing test covers this behavior. This is a substantive signing behavior change, not a hashing implementation, supporting test, or required refactor for #368. The current description reports the change, but it does not link an active issue that requires it.

Resolution

Remove the signing dependency-analysis change and its dedicated test from this PR, or link the change to an active issue with its own coding requirements. Then reassess the PR scope.

Full details: Docstring Coverage

Explanation

Docstring coverage is 38.46% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 13 functions across 18 files. (1 skipped: 1 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches
Generate docstrings
  • Commit to this branch
  • Create a new PR
Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-02T14:31:57.179044Z 3c8b4f7 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3b00592acb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/collections.rs Resolved
@polaz
polaz force-pushed the perf/#367-single-transform-run branch from aef391a to 714f52d Compare November 2, 2026 10:47
@polaz
polaz force-pushed the perf/#368-seeded-identity-hash branch from 3b00592 to 4ec184d Compare November 2, 2026 10:47
@polaz
polaz force-pushed the perf/#367-single-transform-run branch from 714f52d to 50f52d6 Compare November 2, 2026 11:27
@polaz
polaz force-pushed the perf/#368-seeded-identity-hash branch from 4ec184d to dc989d4 Compare November 2, 2026 11:28
Base automatically changed from perf/#367-single-transform-run to main November 2, 2026 11:59

@coderabbitai coderabbitai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

  • Fix comments: Fix CodeRabbit comments on this PR

Comment thread src/xmldsig/transforms.rs Resolved
polaz added 2 commits November 2, 2026 14:40
Content-keyed tables hashed every key with the randomly keyed SipHash,
including the arena identities (document identity and slot) that XPath
node-set deduplication stores for every selected node.

- The table alias now uses a seeded hasher: integer words are mixed by
  a folded multiply under a random odd seed per table, byte strings
  and every word after them go through the randomly keyed SipHash in
  order, so neither form lets a document predict bucket positions
- Tables are built with Default instead of the RandomState-only new
- Without std the tables remain ordered trees

Closes #368
- Content-keyed tables use `structured_asn1::hash::RandomState`, the
  shared seeded hasher (integer mix under a per-table seed, keyed
  SipHash for strings and every word after one); this crate keeps only
  the table aliases. structured-asn1 0.20.2 becomes a required
  dependency, since tables exist without signature support too
- Dependency analysis stops a chain early only before a step that reads
  content: a node-set step such as Enveloped still runs, so it can drop
  the Signature's own values instead of a known dependency turning them
  into a false cycle (regression test with a value-reading XPath, then
  Enveloped and canonicalization)
@polaz
polaz force-pushed the perf/#368-seeded-identity-hash branch from dc989d4 to 437f493 Compare November 2, 2026 13:43
The product now requires structured-asn1 0.20.2, so the competitor
harness lockfile moves with it.

@coderabbitai coderabbitai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

  • Fix comments: Fix CodeRabbit comments on this PR

Comment thread src/xmldsig/transforms.rs Resolved
A value-reading XPath recorded as dependencies only the tracked values
it excluded; a value it read and kept stayed a plain visible node, so a
later Enveloped step removed it and the dependency with it. The XPath
had selected nodes by the empty placeholder, a verifier selects them by
the filled value, and the signed digest did not verify. Every tracked
value such an XPath can read now stays a dependency, visible or not, so
a Reference whose selection reads its own DigestValue is refused as a
cycle.

The regression test covers a predicate on the DigestValue length and a
string(.) test, which reads it through every ancestor's string value;
it replaces a test that expected the latter to sign.
@polaz
polaz enabled auto-merge (squash) November 2, 2026 14:49
@polaz
polaz merged commit 3f4fea2 into main Nov 2, 2026
29 checks passed
@polaz
polaz deleted the perf/#368-seeded-identity-hash branch November 2, 2026 14:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

perf: hash arena identities without SipHash in content tables

1 participant