Signed Circuits (Optional)
This repo includes optional circuits that verify issuer signatures inside the proof. These circuits use BabyJub EdDSA (circomlib) signatures, which are different from the Ed25519 signatures used in the default issuer flow. Use these when you want the proof to be selfâcontained (issuer trust bound inâcircuit), at the cost of larger public inputs and slower proving.
Whatâs Included
age-verify-signed.circomnationality-verify-signed.circom
These circuits verify:
- Claim constraint (age or nationality)
- Credential commitment (Poseidon hash)
- Nonce and request timestamp
- Issuer signature over the credential commitment
How It Works (High Level)
- Issuer signs the credential commitment using a circuitâcompatible EdDSA signature.
- Prover supplies signature bits + issuer public key bits as circuit inputs.
- Circuit verifies signature and proof claims.
Usage (High Level)
- Issue a circuitâsigned credential using
CircuitCredentialIssuer. - Build the
CircuitSignatureInputs(issuer pubkey + signature bits). - Generate a signed proof using the
generate*Signedfunctions. - Verify using
verify*Signedand the signed verification keys.
If you use the server SDK, call verifySignedProof and configure:
signedVerificationKeyPath/signedNationalityVerificationKeyPathissuerPublicKeyBits(trusted BabyJub public key bits per issuer)
Code Sketch
import { generateAgeProofSigned, verifyAgeProofSigned } from '@zk-id/core';
import { CircuitCredentialIssuer } from '@zk-id/issuer';
const issuer = await CircuitCredentialIssuer.createTestIssuer('Demo Issuer');
const signed = await issuer.issueCredential(1990, 840);
const signatureInputs = issuer.getSignatureInputs(signed);
const nonce = '...';
const requestTimestampMs = Date.now();
const proof = await generateAgeProofSigned(
signed.credential,
18,
nonce,
requestTimestampMs,
signatureInputs,
'path/to/age-verify-signed.wasm',
'path/to/age-verify-signed.zkey',
);
// verifyAgeProofSigned(proof, verificationKey)
Notes
- The signed circuits are optional. The default circuits are still supported.
- The signed circuits are significantly heavier; proving time will be higher.
- Only use these if you need issuer trust enforced inside the proof.