> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/zkp2p/zkp2p-contracts/llms.txt
> Use this file to discover all available pages before exploring further.

# SimpleAttestationVerifier

> Verifies attestations from off-chain verification services with on-chain trust anchors

## Overview

The `SimpleAttestationVerifier` 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

**Contract Location:** `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

The `SimpleAttestationVerifier` 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 the `IAttestationVerifier` interface:

```solidity theme={null}
interface IAttestationVerifier {
    function verify(
        bytes32 _digest,
        bytes[] calldata _sigs,
        bytes calldata _data
    ) external view returns (bool isValid);
}
```

**Source:** `contracts/interfaces/IAttestationVerifier.sol:8-21`

## Attestation Structure

While the `SimpleAttestationVerifier` 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:

```solidity theme={null}
struct PaymentAttestation {
    bytes32 intentHash;       // Binds the payment to the intent
    uint256 releaseAmount;    // Final token amount to release
    bytes32 dataHash;         // Hash of the payment details
    bytes[] signatures;       // Witness signatures
    bytes data;               // Encoded payment details
    bytes metadata;           // Additional metadata (not signed)
}
```

The digest passed to `verify()` is:

```solidity theme={null}
bytes32 digest = keccak256(
    abi.encodePacked(
        "\x19\x01",
        DOMAIN_SEPARATOR,
        structHash
    )
);
```

Where `structHash` is the hash of the attestation fields according to EIP-712.

## Signature Verification

The `verify` function validates that the provided signatures meet the required threshold:

```solidity theme={null}
function verify(
    bytes32 _digest,
    bytes[] calldata _sigs,
    bytes calldata
) external view override returns (bool isValid) {
    address[] memory witnesses = new address[](1);
    witnesses[0] = witness;
    
    // Verify signatures meet threshold
    isValid = ThresholdSigVerifierUtils.verifyWitnessSignatures(
        _digest,
        _sigs,
        witnesses,
        MIN_WITNESS_SIGNATURES // = 1
    );

    return isValid;
}
```

**Source:** `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 the `ThresholdSigVerifierUtils` library to validate signatures:

```solidity theme={null}
function verifyWitnessSignatures(
    bytes32 _digest,
    bytes[] memory _signatures,
    address[] memory _witnesses,
    uint256 _reqThreshold
)
    internal
    view
    returns (bool success)
```

**Source:** `contracts/lib/ThresholdSigVerifierUtils.sol:29-86`

### Verification Logic

1. Validates that the required threshold is > 0
2. Ensures enough signatures and witnesses are provided
3. For each signature, checks if any witness created it using `SignatureChecker.isValidSignatureNow`
4. Tracks unique signers to prevent counting the same witness twice
5. Returns true once the threshold is met (early exit optimization)
6. Reverts if the threshold is not met

### Supported Signature Types

The library uses OpenZeppelin's `SignatureChecker`, which supports:

* EOA signatures (ECDSA)
* EIP-1271 smart contract signatures
* Both EIP-712 and EIP-191 formatted messages

## Trust Model

### Single Witness Model

The `SimpleAttestationVerifier` uses a single witness trust model:

```solidity theme={null}
uint256 public constant MIN_WITNESS_SIGNATURES = 1;
address public witness;
```

This model is suitable for:

* 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:

```solidity theme={null}
function setWitness(address _newWitness) external onlyOwner {
    require(_newWitness != address(0), "SimpleAttestationVerifier: Zero address");
    
    address oldWitness = witness;
    witness = _newWitness;
    
    emit WitnessUpdated(oldWitness, _newWitness);
}
```

**Source:** `contracts/unifiedVerifier/SimpleAttestationVerifier.sol:82-89`

### Access Control

The contract inherits from OpenZeppelin's `Ownable`, providing:

* `onlyOwner` modifier for privileged functions
* `transferOwnership` for changing contract ownership
* `renounceOwnership` for removing ownership (use with caution)

## Events

### WitnessUpdated

```solidity theme={null}
event WitnessUpdated(address indexed oldWitness, address indexed newWitness);
```

Emitted when the witness address is updated.

**Source:** `contracts/unifiedVerifier/SimpleAttestationVerifier.sol:27`

## Example Usage

### From Payment Verifier

```solidity theme={null}
// Inside UnifiedPaymentVerifier._verifyAttestation()

bytes32 structHash = keccak256(
    abi.encode(
        PAYMENT_ATTESTATION_TYPEHASH,
        attestation.intentHash,
        attestation.releaseAmount,
        attestation.dataHash
    )
);

bytes32 digest = keccak256(
    abi.encodePacked(
        "\x19\x01",
        DOMAIN_SEPARATOR,
        structHash
    )
);

// Verify data integrity
require(
    keccak256(attestation.data) == attestation.dataHash,
    "UPV: Data hash mismatch"
);

// Verify witness signature
bool isValid = attestationVerifier.verify(
    digest, 
    attestation.signatures,
    attestation.data
);
```

**Source:** `contracts/unifiedVerifier/UnifiedPaymentVerifier.sol:183-214`

### Deploying the Contract

```solidity theme={null}
// Deploy with initial witness
SimpleAttestationVerifier verifier = new SimpleAttestationVerifier(witnessAddress);

// Or deploy and set witness later
SimpleAttestationVerifier verifier = new SimpleAttestationVerifier(address(0));
verifier.setWitness(witnessAddress);
```

## Integration Points

The `SimpleAttestationVerifier` is used by:

### UnifiedPaymentVerifier

Stored as an immutable reference in `BaseUnifiedPaymentVerifier`:

```solidity theme={null}
IAttestationVerifier public attestationVerifier;
```

Can be updated via governance:

```solidity theme={null}
function setAttestationVerifier(address _newVerifier) external onlyOwner
```

**Source:** `contracts/unifiedVerifier/BaseUnifiedPaymentVerifier.sol:38,104-111`

## Upgrading to Multi-Witness

For production systems requiring higher security, consider implementing a multi-witness attestation verifier:

```solidity theme={null}
contract MultiWitnessAttestationVerifier is IAttestationVerifier {
    uint256 public constant MIN_WITNESS_SIGNATURES = 2; // Require 2 of 3
    address[] public witnesses; // Multiple witnesses
    
    function verify(
        bytes32 _digest,
        bytes[] calldata _sigs,
        bytes calldata
    ) external view override returns (bool isValid) {
        return ThresholdSigVerifierUtils.verifyWitnessSignatures(
            _digest,
            _sigs,
            witnesses,
            MIN_WITNESS_SIGNATURES
        );
    }
}
```

This provides Byzantine fault tolerance where the system remains secure as long as less than the threshold of witnesses are compromised.

## Security Best Practices

### Witness Key Management

1. **Key Generation**: Use secure random number generation for witness keys
2. **Key Storage**: Store witness keys in HSM or secure enclaves
3. **Key Rotation**: Implement regular witness key rotation schedules
4. **Access Control**: Limit access to witness signing infrastructure

### Monitoring

1. **Signature Activity**: Monitor witness signature frequency and patterns
2. **Failed Verifications**: Alert on unusual numbers of failed verifications
3. **Witness Updates**: Log and audit all witness address changes

### Testing

1. **Signature Validation**: Test with valid and invalid signatures
2. **Edge Cases**: Test with zero signatures, multiple signatures, wrong witness
3. **Replay Protection**: Verify attestations cannot be reused (handled by payment verifier)

## Related Contracts

* [UnifiedPaymentVerifier](/contracts/unified-payment-verifier) - Uses attestation verifier for payment validation
* ThresholdSigVerifierUtils - Signature verification library
* IAttestationVerifier - Interface specification
