Aere Network public source. Everything here can be checked against the live chain (chain id 2800, https://rpc.aere.network). Scope note, stated up front rather than buried: consensus on chain 2800 is classical secp256k1 ECDSA QBFT. The post-quantum work in this repository is at the signature, precompile, account and transport layers. Nothing here makes the consensus post-quantum, and no document in it should be read as claiming so.
68 lines
2.3 KiB
Solidity
68 lines
2.3 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity ^0.8.20;
|
|
|
|
import {ISP1Verifier, ISP1VerifierWithHash} from "./ISP1Verifier.sol";
|
|
import {ISP1VerifierGateway, VerifierRoute} from "./ISP1VerifierGateway.sol";
|
|
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
|
|
|
|
/// @title SP1 Verifier Gateway
|
|
/// @author Succinct Labs
|
|
/// @notice This contract verifies proofs by routing to the correct verifier based on the verifier
|
|
/// selector contained in the first 4 bytes of the proof. It additionally checks that to see that
|
|
/// the verifier route is not frozen.
|
|
contract SP1VerifierGateway is ISP1VerifierGateway, Ownable {
|
|
/// @inheritdoc ISP1VerifierGateway
|
|
mapping(bytes4 => VerifierRoute) public routes;
|
|
|
|
constructor(address initialOwner) Ownable() { transferOwnership(initialOwner); }
|
|
|
|
/// @inheritdoc ISP1Verifier
|
|
function verifyProof(
|
|
bytes32 programVKey,
|
|
bytes calldata publicValues,
|
|
bytes calldata proofBytes
|
|
) external view {
|
|
bytes4 selector = bytes4(proofBytes[:4]);
|
|
VerifierRoute memory route = routes[selector];
|
|
if (route.verifier == address(0)) {
|
|
revert RouteNotFound(selector);
|
|
} else if (route.frozen) {
|
|
revert RouteIsFrozen(selector);
|
|
}
|
|
|
|
ISP1Verifier(route.verifier).verifyProof(programVKey, publicValues, proofBytes);
|
|
}
|
|
|
|
/// @inheritdoc ISP1VerifierGateway
|
|
function addRoute(address verifier) external onlyOwner {
|
|
bytes4 selector = bytes4(ISP1VerifierWithHash(verifier).VERIFIER_HASH());
|
|
if (selector == bytes4(0)) {
|
|
revert SelectorCannotBeZero();
|
|
}
|
|
|
|
VerifierRoute storage route = routes[selector];
|
|
if (route.verifier != address(0)) {
|
|
revert RouteAlreadyExists(route.verifier);
|
|
}
|
|
|
|
route.verifier = verifier;
|
|
|
|
emit RouteAdded(selector, verifier);
|
|
}
|
|
|
|
/// @inheritdoc ISP1VerifierGateway
|
|
function freezeRoute(bytes4 selector) external onlyOwner {
|
|
VerifierRoute storage route = routes[selector];
|
|
if (route.verifier == address(0)) {
|
|
revert RouteNotFound(selector);
|
|
}
|
|
if (route.frozen) {
|
|
revert RouteIsFrozen(selector);
|
|
}
|
|
|
|
route.frozen = true;
|
|
|
|
emit RouteFrozen(selector, route.verifier);
|
|
}
|
|
}
|