Overview
TheSimpleAttestationVerifier contract verifies attestations from off-chain verification services using on-chain trust anchors. It implements a simplified model with a single witness that signs standardized attestations after verifying zkTLS proofs.
Key Features:
- Single witness signature verification
- EIP-712 digest validation
- Threshold signature validation (minimum 1 signature required)
- Pluggable architecture through IAttestationVerifier interface
- Governance controls for updating witness
contracts/unifiedVerifier/SimpleAttestationVerifier.sol
Verification Flow
The complete off-chain to on-chain verification flow:1. User Generates zkTLS Proof
The user runs the zkTLS protocol with an attestor to generate a zkTLS proof of their payment transaction.2. Off-Chain Service Verifies and Signs
The off-chain verification service:- Verifies the zkTLS proof
- Extracts and validates payment details
- Generates a standardized attestation
- Signs the attestation with the witness private key
- Includes metadata about the verification
3. On-Chain Verification
TheSimpleAttestationVerifier contract:
- Checks the witness signature on the EIP-712 digest
- Validates trust anchors to ensure off-chain verification integrity
- Returns verification result to the calling payment verifier
Architecture
The contract implements theIAttestationVerifier interface:
contracts/interfaces/IAttestationVerifier.sol:8-21
Attestation Structure
While theSimpleAttestationVerifier only validates signatures on a digest, the digest is typically an EIP-712 formatted hash of a structured attestation. In the zkp2p system, this is the PaymentAttestation:
verify() is:
structHash is the hash of the attestation fields according to EIP-712.
Signature Verification
Theverify function validates that the provided signatures meet the required threshold:
contracts/unifiedVerifier/SimpleAttestationVerifier.sol:56-74
Parameters
_digest: The EIP-712 formatted message digest to verify_sigs: Array of signatures (must contain at least 1 valid signature)_data: Verification data (unused in SimpleAttestationVerifier but part of interface)
Return Value
isValid: True if at least one signature is valid from the configured witness
Threshold Signature Verification
The contract uses theThresholdSigVerifierUtils library to validate signatures:
contracts/lib/ThresholdSigVerifierUtils.sol:29-86
Verification Logic
- Validates that the required threshold is > 0
- Ensures enough signatures and witnesses are provided
- For each signature, checks if any witness created it using
SignatureChecker.isValidSignatureNow - Tracks unique signers to prevent counting the same witness twice
- Returns true once the threshold is met (early exit optimization)
- Reverts if the threshold is not met
Supported Signature Types
The library uses OpenZeppelin’sSignatureChecker, which supports:
- EOA signatures (ECDSA)
- EIP-1271 smart contract signatures
- Both EIP-712 and EIP-191 formatted messages
Trust Model
Single Witness Model
TheSimpleAttestationVerifier uses a single witness trust model:
- Development and testing environments
- Scenarios where the witness is a trusted entity
- Systems where the witness operates secure infrastructure (e.g., TEE)
Security Considerations
Single Point of Failure: The witness private key is a single point of failure. If compromised, attackers could sign fraudulent attestations. Mitigation Strategies:- Use hardware security modules (HSM) to protect witness keys
- Implement witness key rotation procedures
- Monitor witness activity for anomalies
- Consider upgrading to multi-witness threshold model for production
Governance Functions
Setting the Witness
The contract owner can update the witness address:contracts/unifiedVerifier/SimpleAttestationVerifier.sol:82-89
Access Control
The contract inherits from OpenZeppelin’sOwnable, providing:
onlyOwnermodifier for privileged functionstransferOwnershipfor changing contract ownershiprenounceOwnershipfor removing ownership (use with caution)
Events
WitnessUpdated
contracts/unifiedVerifier/SimpleAttestationVerifier.sol:27
Example Usage
From Payment Verifier
contracts/unifiedVerifier/UnifiedPaymentVerifier.sol:183-214
Deploying the Contract
Integration Points
TheSimpleAttestationVerifier is used by:
UnifiedPaymentVerifier
Stored as an immutable reference inBaseUnifiedPaymentVerifier:
contracts/unifiedVerifier/BaseUnifiedPaymentVerifier.sol:38,104-111
Upgrading to Multi-Witness
For production systems requiring higher security, consider implementing a multi-witness attestation verifier:Security Best Practices
Witness Key Management
- Key Generation: Use secure random number generation for witness keys
- Key Storage: Store witness keys in HSM or secure enclaves
- Key Rotation: Implement regular witness key rotation schedules
- Access Control: Limit access to witness signing infrastructure
Monitoring
- Signature Activity: Monitor witness signature frequency and patterns
- Failed Verifications: Alert on unusual numbers of failed verifications
- Witness Updates: Log and audit all witness address changes
Testing
- Signature Validation: Test with valid and invalid signatures
- Edge Cases: Test with zero signatures, multiple signatures, wrong witness
- Replay Protection: Verify attestations cannot be reused (handled by payment verifier)
Related Contracts
- UnifiedPaymentVerifier - Uses attestation verifier for payment validation
- ThresholdSigVerifierUtils - Signature verification library
- IAttestationVerifier - Interface specification