A Rust library for creating and verifying sigma protocols (zero-knowledge proofs of knowledge) using symbolic computation over elliptic curves.
This library is experimental and not production-ready. It is intended for research, prototyping, and educational purposes only. Do not use this library in production systems or for securing real assets. The implementation has not undergone security audits and may contain bugs or vulnerabilities.
Add this to your Cargo.toml:
[dependencies]
sigma-proof-compiler = "0.1.0"Here's a complete example implementing a Schnorr identity protocol that proves knowledge of a discrete logarithm:
use sigma_proof_compiler::{
absorb::{SymInstance, SymWitness},
compiler::SigmaProof,
equations::{SymPoint, SymScalar},
};
use curve25519_dalek::{constants::RISTRETTO_BASEPOINT_POINT, Scalar};
// Define the protocol
pub struct SchnorrIdentityProtocol;
// The secret witness (what the prover knows)
#[derive(SymWitness, Clone)]
pub struct SchnorrWitness {
privatekey: SymScalar,
}
// The public instance (what everyone can see)
#[derive(SymInstance, Clone)]
pub struct SchnorrInstance {
pubkey: SymPoint,
}
impl SigmaProof for SchnorrIdentityProtocol {
const LABEL: &'static [u8] = b"schnorr-identity-protocol";
type WITNESS = SchnorrWitness;
type INSTANCE = SchnorrInstance;
// Instance function: public key (= private_key * G)
fn f(instance: &Self::INSTANCE) -> Vec<SymPoint> {
vec![instance.pubkey.clone()]
}
// Witness function: commitment = private_key * G (using symbolic arithmetic)
fn psi(witness: &Self::WITNESS, _instance: &Self::INSTANCE) -> Vec<SymPoint> {
let SchnorrWitness { privatekey } = witness;
vec![privatekey * SymPoint::Const(RISTRETTO_BASEPOINT_POINT)]
}
}A prover and a verifier can then use functions derived by the framework:
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Generate a random private key
let rng = &mut rand::rngs::OsRng;
let sk = Scalar::random(rng);
// Create witness (secret)
let witness = SchnorrWitness {
privatekey: SymScalar::Const(sk),
};
// Create instance (public)
let pk = sk * RISTRETTO_BASEPOINT_POINT;
let instance = SchnorrInstance {
pubkey: SymPoint::Const(pk),
};
// Generate proof
let proof = SchnorrIdentityProtocol::prove(&witness, &instance);
println!("Proof generated: {} bytes", proof.len());
// Verify proof
match SchnorrIdentityProtocol::verify(&instance, &proof) {
Ok(()) => println!("✅ Proof verified successfully!"),
Err(e) => println!("❌ Proof verification failed: {}", e),
}
Ok(())
}The library can automatically generate formal specifications in Markdown+LaTeX format:
// Generate specification for the Schnorr protocol
let spec = SchnorrIdentityProtocol::spec();
println!("{spec}");This outputs the following spec:
Currently, proofs are portable as they do not authenticate their own environement. A future version of the API will include an optional prologue slice that can contain pure data or a hash to contextualize the proof.
