Verification API

Signature Verification Specification

This specification describes how to verify a signature from a notarization response. The process involves recovering the public key from the signature and message, then checking it against a list of allowlisted public keys.

Prerequisites

  • A programming language of your choice
  • A library that supports EIP-191 signature recovery
  • A library for hex encoding/decoding
  • Access to the allowlisted public keys endpoint

Steps to Verify Signature

  1. Get Required Data
  • The notarization response contains:
    • signature: The EIP-191 signature
    • message: The original message that was signed
  1. Recover Public Key
  • Use EIP-191 signature recovery to get the public key from the signature and message
  • The message should be the JSON string from the response
  1. Check Against Allowlist
  • Fetch the allowlisted public keys from https://verifier.opacity.network/api/public-keys
  • Compare the recovered public key against the allowlist
  • The public key should be in the format of a 20-byte Ethereum address

Example Code (Rust)

use alloy_primitives::Address;
use alloy_signer::Signature;
use hex;

// 1. Get the signature and message from the response
let signature_hex = result.signature.trim_start_matches("0x");
let signature_bytes = hex::decode(signature_hex)?;
let message = serde_json::to_string(&result.message)?;

// 2. Recover the public key
let signature = Signature::try_from(signature_bytes.as_slice())?;
let recovered_address = signature.recover_address_from_msg(message.as_bytes())?;

// 3. Fetch and check against allowlist
let allowlist_response = reqwest::get("https://verifier.opacity.network/api/public-keys").await?;
let allowlist: AllowlistResponse = allowlist_response.json().await?;

let is_valid = allowlist.allowlisted_keys.contains(&recovered_address.to_string());

If using Rust, add these to your Cargo.toml:

[dependencies]
alloy-primitives = "1.2.0"  # Use the latest version
alloy-signer = "1.0.9"      # Use the latest version
hex = "0.4.3"              # Use the latest version
reqwest = { version = "0.12.12", features = ["json"] }

Using the API

You can also verify signatures using the verifier API:

curl -k -X POST https://verifier.opacity.network/api/verify \
  -H "Content-Type: application/json" \
  -d '{
    "signature": "<signature_from_response>",
    "message": "<message_hash_hex>"
  }'

Notes

  • The signature must be a valid EIP-191 signature
  • The recovered public key must match one of the allowlisted keys
  • The allowlist is maintained by the verifier service and can be fetched at any time
  • The verification process ensures that the signature was created by an authorized notary
Previous
Flutter