Skip to content

Commit 56a70f1

Browse files
authored
Add TD3QueryProofVerifier, PublicSignalsBuilder, RegReplicator (#78)
Added TD3QueryProofVerifier, PublicSignalsBuilder, RegistrationSMTReplicator
1 parent d7f46dd commit 56a70f1

File tree

1 file changed

+110
-0
lines changed

1 file changed

+110
-0
lines changed

docs/zk-passport/contracts.mdx

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,3 +398,113 @@ contract PRSASHAAuthenticator is Initializable {
398398
- `authenticate(...)` — checks active authentication of a passport (RSA signature);
399399

400400
For the full implementation, see <OutLink href="https://github.com/rarimo/passport-contracts/blob/master/contracts/passport/authenticators/PRSASHAAuthenticator.sol">PRSASHAAuthenticator.sol</OutLink> at the GitHub.
401+
402+
## `TD3QueryProofVerifier`
403+
404+
### Interface
405+
406+
```solidity
407+
contract TD3QueryProofVerifier {
408+
function verifyProof(
409+
uint256[2] calldata _pA,
410+
uint256[2][2] calldata _pB,
411+
uint256[2] calldata _pC,
412+
uint256[] calldata _pubSignals
413+
) external view returns (bool) {
414+
/* ... */
415+
}
416+
}
417+
```
418+
419+
- Verifies TD3-query zero-knowledge proofs produced by the Query circuit (e.g., age, uniqueness, country masks) without revealing raw passport data.
420+
- Accepts Groth16 proof points and the public signals array (23 items for Query circuit) and returns `true` if valid.
421+
- Intended for SDK-level integrations where on-chain verification of query proofs is needed.
422+
423+
For the full implementation, see <OutLink href="https://github.com/rarimo/passport-contracts/blob/master/contracts/sdk/verifier/TD3QueryProofVerifier.sol">TD3QueryProofVerifier.sol</OutLink> at the GitHub.
424+
425+
## `PublicSignalsBuilder`
426+
427+
### Interface
428+
429+
```solidity
430+
library PublicSignalsBuilder {
431+
uint256 public constant PROOF_SIGNALS_COUNT = 23;
432+
433+
function newPublicSignalsBuilder(
434+
uint256 selector_,
435+
uint256 nullifier_
436+
) internal pure returns (uint256 dataPointer_);
437+
438+
function withName(uint256 dataPointer_, uint256 name_) internal pure;
439+
function withNameResidual(uint256 dataPointer_, uint256 nameResidual_) internal pure;
440+
function withNationality(uint256 dataPointer_, uint256 nationality_) internal pure;
441+
function withCitizenship(uint256 dataPointer_, uint256 citizenship_) internal pure;
442+
function withSex(uint256 dataPointer_, uint256 sex_) internal pure;
443+
function withEventIdAndData(uint256 dataPointer_, uint256 eventId_, uint256 eventData_) internal pure;
444+
function withIdStateRoot(uint256 dataPointer_, bytes32 idStateRoot_) internal view;
445+
function withSelector(uint256 dataPointer_, uint256 selector_) internal pure;
446+
function withCurrentDate(uint256 dataPointer_, uint256 currentDate_, uint256 timeBound_) internal view;
447+
function withTimestampLowerboundAndUpperbound(uint256 dataPointer_, uint256 lb_, uint256 ub_) internal pure;
448+
function withIdentityCounterLowerbound(uint256 dataPointer_, uint256 lb_, uint256 ub_) internal pure;
449+
function withBirthDateLowerboundAndUpperbound(uint256 dataPointer_, uint256 lb_, uint256 ub_) internal pure;
450+
function withExpirationDateLowerboundAndUpperbound(uint256 dataPointer_, uint256 lb_, uint256 ub_) internal pure;
451+
function withCitizenshipMask(uint256 dataPointer_, uint256 citizenshipMask_) internal pure;
452+
453+
function buildAsUintArray(uint256 dataPointer_) internal pure returns (uint256[] memory);
454+
function buildAsBytesArray(uint256 dataPointer_) internal pure returns (bytes32[] memory);
455+
}
456+
```
457+
458+
- Helper library to construct the Query circuit public signals in the exact index layout expected by verifiers (see <OutLink href="https://github.com/rarimo/passport-zk-circuits/?tab=readme-ov-file#query-circuit-public-signals">Query circuit public signals spec</OutLink>).
459+
- Validates constraints via `AQueryProofExecutor` storage; `withIdStateRoot(...)` checks `IPoseidonSMT(registrationSMT).isRootValid(...)` before writing the root at index 11.
460+
- Date handling: `withCurrentDate(...)` parses `yyMMdd` to a timestamp and enforces a ±timeBound window using `Date2Time` utilities.
461+
- Produces either `uint256[]` or `bytes32[]` views of the same in-memory array for downstream verifier calls.
462+
463+
For the full implementation, see <OutLink href="https://github.com/rarimo/passport-contracts/blob/master/contracts/sdk/lib/PublicSignalsBuilder.sol">PublicSignalsBuilder.sol</OutLink> at the GitHub.
464+
465+
## `RegistrationSMTReplicator`
466+
467+
### Interface
468+
469+
```solidity
470+
contract RegistrationSMTReplicator is IPoseidonSMT {
471+
uint256 public constant ROOT_VALIDITY = 1 hours;
472+
string public constant REGISTRATION_ROOT_PREFIX = "Rarimo root";
473+
474+
address public sourceSMT;
475+
bytes32 public latestRoot;
476+
uint256 public latestTimestamp;
477+
478+
event RootTransitioned(bytes32 newRoot, uint256 transitionTimestamp);
479+
480+
function __RegistrationSMTReplicator_init(
481+
address[] memory oracles_,
482+
address sourceSMT_
483+
) external;
484+
485+
function addOracles(address[] memory oracles_) external;
486+
function removeOracles(address[] memory oracles_) external;
487+
function setSourceSMT(address newSourceSMT_) external;
488+
489+
function transitionRoot(bytes32 newRoot_, uint256 transitionTimestamp_) external;
490+
function transitionRootWithSignature(
491+
bytes32 newRoot_,
492+
uint256 transitionTimestamp_,
493+
bytes memory signature_
494+
) external;
495+
496+
function isRootValid(bytes32 root_) external view returns (bool);
497+
function isRootLatest(bytes32 root_) public view returns (bool);
498+
function isOracle(address oracle_) public view returns (bool);
499+
function getOracles() external view returns (address[] memory);
500+
}
501+
```
502+
503+
- Deployed on target chains to replicate the Registration SMT root when the canonical `StateKeeper` is not directly available.
504+
- Root updates can be pushed by:
505+
- Authorized oracles via `transitionRoot(...)`.
506+
- Anyone with an oracle-signed message via `transitionRootWithSignature(...)` using `keccak256(abi.encodePacked(REGISTRATION_ROOT_PREFIX, sourceSMT, address(this), newRoot, timestamp))` recovered with ECDSA.
507+
- `isRootValid(root)` returns true if the root is the latest or if it was observed within `ROOT_VALIDITY` (1 hour), enabling lightweight freshness checks by verifiers depending on `IPoseidonSMT`.
508+
- Owners manage the oracle set and can update `sourceSMT`; contract follows UUPS upgradeability and multi-owner controls.
509+
510+
For the full implementation, see <OutLink href="https://github.com/rarimo/passport-contracts/blob/master/contracts/sdk/RegistrationSMTReplicator.sol">RegistrationSMTReplicator.sol</OutLink> at the GitHub.

0 commit comments

Comments
 (0)