snarkify / sirius

A Plonkish folding framework for Incrementally Verifiable Computation (IVC).
MIT License
106 stars 15 forks source link
cryptography ivc nova proof-system protostar zero-knowledge-proofs zkp
logo

Sirius, renowned as the most luminous star in the night sky, deceives the naked eye by appearing as a solitary point of light when, in fact, it is a binary star system. Inspired by this duality, our project bears the name Sirius, capturing the essence of folded instances that give the illusion of being a singular entity.

Introduction

Sirius is an open-source Plonkish Folding Framework for Incrementally Verifiable Computation [IVC].

fig1

Within the context of an IVC scheme, the prover's role is to demonstrate that, upon consecutively applying a step function F exactly n times to an initial value $z_0$, the result is $z_n$. Here, the step function F takes two inputs $zi$ and $w$, and yields an output $z{i+1}$.

Architecture

The Sirius folding framework is designed with a three-tiered architecture.

fig2

Roadmap

The estimated timeline is subject to change.

Getting Started

Install Rust

Use rustup

Add dependency

cargo add --git https://github.com/snarkify/sirius.git --tag v0.1.0 sirius

Implement StepCircuit trait

/// To allow your circuit to be folded, impl this trait
/// `ARITY` - size of input & output
pub trait StepCircuit<const ARITY: usize, F: PrimeField> {
    type Config: Clone;
    fn configure(cs: &mut ConstraintSystem<F>) -> Self::Config;
    /// This method represents step function `F: z_i -> z_{i+1}`
    ///
    /// Unlike `halo2::Circuit`, it takes array of assigned cells
    /// and returns array of assigned cells
    fn synthesize_step(
        &self,
        config: Self::Config,
        layouter: &mut impl Layouter<F>,
        z_in: &[AssignedCell<F, F>; ARITY],
    ) -> Result<[AssignedCell<F, F>; ARITY], SynthesisError>;
}

Setup and run IVC instance

For runnable examples, please check examples folder.

An example of using the API of IVC:

fn main() {
    let primary = poseidon_step_circuit::TestPoseidonCircuit::default();
    let secondary = step_circuit::trivial::Circuit::<ARITY2, _>::default();

    // Specifications for random oracle used as part of the IVC algorithm
    let primary_spec = RandomOracleConstant::<C1Scalar>::new(10, 10);
    let secondary_spec = RandomOracleConstant::<C2Scalar>::new(10, 10);

    let primary_commitment_key = get_or_create_commitment_key::<C1Affine>(COMMITMENT_KEY_SIZE, "bn256");
    let secondary_commitment_key = get_or_create_commitment_key::<C2Affine>(COMMITMENT_KEY_SIZE, "grumpkin");

    let pp = PublicParams::<
        '_,
        ARITY1,
        ARITY2,
        MAIN_GATE_SIZE,
        C1Affine,
        C2Affine,
        TestPoseidonCircuit<_>,
        step_circuit::trivial::Circuit<ARITY, _>,
        RandomOracle,
        RandomOracle,
    >::new(
        CircuitPublicParamsInput::new(
            PRIMARY_CIRCUIT_TABLE_SIZE as u32,
            &primary_commitment_key,
            primary_spec,
            &primary,
        ),
        CircuitPublicParamsInput::new(
            SECONDARY_CIRCUIT_TABLE_SIZE as u32,
            &secondary_commitment_key,
            secondary_spec,
            &secondary,
        ),
        LIMB_WIDTH,
        LIMBS_COUNT,
    )
    .expect("failed to create public params");

    let primary_input = array::from_fn(|i| C1Scalar::from_u128(i as u128));
    let secondary_input = array::from_fn(|i| C2Scalar::from_u128(i as u128));
    let fold_step_count = NonZeroUsize::new(10).unwrap();

    IVC::fold(
        &pp,
        primary,
        primary_input,
        secondary,
        secondary_input,
        fold_step_count,
    )
    .expect("failed to run IVC");
}

This code will run fold_step_count of folding steps, and also check the proof after execution.

Run examples

For runnable examples, please check examples folder.

# Alias to run IVC with parameterization via cli arguments
cargo cli-example --help

# Alias for run the IVC for trivial `StepCircuit` (just returns its input unchanged)
cargo trivial-example

# Alias for run the IVC for the poseidon-circuit
cargo poseidon-example

Time-Profiling

Span lifetime tracking implemented, which allows you to understand in detail how long a particular step takes to complete.

# By default, it will output all spans with a lifetime greater than 1s
cargo poseidon-example | python3 .scripts/build_profiling.py

# It is possible to specify the bottom border of the output span
cargo poseidon-example | python3 .scripts/build_profiling.py --min-runtime 0.1s

# You can also store logs and process them at a later date
cargo poseidon-example > log; cat log | python3 .scripts/build_profiling.py 

Memory-Profiling

The dhat utility and the dhat-rs experimental crate are used

# Run dhat with default IVC (poseidon+trivial)
cargo cli-dhat

# Check available params of run
cargo cli-dhat --help

Benchmark

For benches, please check benches folder.

cargo bench

Criterion

You can also get a more detailed report. Please check for info criterion.rs

cargo criterion

Getting Involved

We'd love for you to be a part of our community!

If you're as enthusiastic about Sirius as we are, we invite you to join our developer community at Telegram. It's a great place to stay updated, get involved, and contribute to the project. Whether you're looking to contribute code, provide feedback, or simply stay in the loop, our Telegram group is the place to be.

:point_right: Join our developer community

Thank you for your interest in contributing to Sirius! :sparkles: