test: pin cross-module nonce scoping for create-and-bind - #917
Open
kilianglas wants to merge 1 commit into
Open
Conversation
A create-and-bind request drives two OPRF queries under a single RP nonce: the uniqueness nullifier and the session seed. Both modules share one node-local NonceHistory, so acceptance depends entirely on the two queries consuming the nonce in different scopes. That was only covered at the cache level (nonce_history unit test) and by the full-stack e2e. This adds the assertion at the layer that derives the scope, so collapsing or dropping a NonceScope variant fails here instead of in the heavyweight e2e. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
kilianglas
requested review from
0xThemis,
dkales,
fabian1409 and
philsippl
as code owners
August 12, 2026 13:58
dkales
approved these changes
Aug 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A create-and-bind request (
ProofType::Uniqueness×SessionRef::Create) drives two OPRF queries under a single RP nonce: the uniqueness nullifier (OprfModule::Nullifier) and the session seed (OprfModule::Session). Both modules are handed the sameNonceHistoryat startup (services/oprf-node/src/lib.rs:130-152), so acceptance rests entirely on the two queries consuming the nonce in differentNonceScopes — derived inauthenticate_inner(services/oprf-node/src/auth/rp_module.rs:389-426).That invariant was only covered at the cache level (
nonce_history::test_nonce_history_allows_distinct_scopes, which asserts nothing about how the modules pick a scope) and indirectly by the full-stack e2e incrates/core/tests/generate_proof.rs. This adds the assertion at the layer that derives the scope.The test also replays both queries and expects
DUPLICATE_NONCE, so it cannot pass vacuously if replay protection were disabled outright.Test plan
cargo test -p world-id-oprf-node --all-features— 76 passed.authenticate_innerto returnNonceScope::Uniquenessmakes the new test fail with4503 signature nonce already used.