Path: blob/main/frontier/10-snarks-starks/rust/src/lib.rs
483 views
unlisted
//! # Module 10: SNARKs and STARKs — Exercises1//!2//! ## Progression3//! 1. `evaluate_circuit` — signature + doc4//! 2. `circuit_to_r1cs` — signature + doc5//! 3. `check_r1cs_witness` — signature + doc6//! 4. `fri_fold` — signature only78/// A gate in an arithmetic circuit.9#[derive(Debug, Clone)]10pub enum Gate {11/// Addition gate: output = left + right12Add(usize, usize),13/// Multiplication gate: output = left * right14Mul(usize, usize),15/// Constant gate: output = value16Const(i64),17}1819/// Evaluate an arithmetic circuit on given inputs.20///21/// `gates` defines the circuit. The first `num_inputs` wires are input wires.22/// Each subsequent gate takes wire indices as inputs and produces one output wire.23///24/// Returns the value of all wires (inputs + intermediate + output).25pub fn evaluate_circuit(gates: &[Gate], inputs: &[i64], modulus: i64) -> Vec<i64> {26todo!("Evaluate each gate, building up wire values")27}2829/// Convert a circuit to R1CS form: A * witness . B * witness = C * witness.30///31/// Returns matrices (A, B, C) where each row corresponds to a constraint32/// and the witness vector is [1, inputs..., intermediates..., output].33///34/// Each matrix is Vec<Vec<i64>> (rows × witness_size).35#[allow(clippy::type_complexity)]36pub fn circuit_to_r1cs(37gates: &[Gate],38num_inputs: usize,39) -> (Vec<Vec<i64>>, Vec<Vec<i64>>, Vec<Vec<i64>>) {40todo!("Flatten circuit into R1CS matrices")41}4243/// Check whether a witness satisfies an R1CS instance.44///45/// For each row i: (A[i] · w) * (B[i] · w) == C[i] · w (mod modulus)46pub fn check_r1cs_witness(47a: &[Vec<i64>],48b: &[Vec<i64>],49c: &[Vec<i64>],50witness: &[i64],51modulus: i64,52) -> bool {53todo!("Verify (A·w) * (B·w) = (C·w) for each constraint")54}5556/// One round of FRI folding: reduce polynomial degree by half.57///58/// Given evaluations of a polynomial p(x) at points {ω^i},59/// fold using challenge α:60/// p_new(x²) = (p(x) + p(-x))/2 + α * (p(x) - p(-x))/(2x)61///62/// Returns the folded evaluations (half the length).63pub fn fri_fold(evaluations: &[i64], challenge: i64, modulus: i64) -> Vec<i64> {64todo!("FRI folding step: halve the polynomial degree")65}6667#[cfg(test)]68mod tests {69use super::*;7071#[test]72#[ignore]73fn test_evaluate_circuit() {74// Circuit: c = a * b + a75// Wire 0: a (input), Wire 1: b (input)76// Wire 2: a * b, Wire 3: (a*b) + a77let gates = vec![Gate::Mul(0, 1), Gate::Add(2, 0)];78let wires = evaluate_circuit(&gates, &[3, 5], 97);79assert_eq!(wires[2], 15); // 3 * 580assert_eq!(wires[3], 18); // 15 + 381}8283#[test]84#[ignore]85fn test_check_r1cs_witness() {86// Simple constraint: a * b = c87let a = vec![vec![0, 1, 0, 0]]; // selects wire 188let b = vec![vec![0, 0, 1, 0]]; // selects wire 289let c = vec![vec![0, 0, 0, 1]]; // selects wire 390let witness = vec![1, 3, 5, 15]; // [1, a, b, c]91assert!(check_r1cs_witness(&a, &b, &c, &witness, 97));92}93}949596