{"id":13632261,"url":"https://github.com/snarkify/sirius","last_synced_at":"2025-04-18T02:32:18.966Z","repository":{"id":207161136,"uuid":"633699060","full_name":"snarkify/sirius","owner":"snarkify","description":"A Plonkish folding framework for Incrementally Verifiable Computation (IVC).","archived":true,"fork":false,"pushed_at":"2025-03-24T17:44:51.000Z","size":1878,"stargazers_count":169,"open_issues_count":37,"forks_count":25,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-04-06T23:35:26.760Z","etag":null,"topics":["cryptography","ivc","nova","proof-system","protostar","zero-knowledge-proofs","zkp"],"latest_commit_sha":null,"homepage":"https://docs.snarkify.io/sirius-folding/","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/snarkify.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-04-28T04:49:35.000Z","updated_at":"2025-03-24T17:45:05.000Z","dependencies_parsed_at":"2023-11-20T08:00:08.796Z","dependency_job_id":"3105e5f7-54f3-4e7a-b846-fea5501b2fe0","html_url":"https://github.com/snarkify/sirius","commit_stats":null,"previous_names":["snarkify/sirius"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snarkify%2Fsirius","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snarkify%2Fsirius/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snarkify%2Fsirius/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snarkify%2Fsirius/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/snarkify","download_url":"https://codeload.github.com/snarkify/sirius/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249414252,"owners_count":21267724,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cryptography","ivc","nova","proof-system","protostar","zero-knowledge-proofs","zkp"],"created_at":"2024-08-01T22:02:58.032Z","updated_at":"2025-04-18T02:32:18.948Z","avatar_url":"https://github.com/snarkify.png","language":"Rust","readme":"\u003cimg width=\"200\" alt=\"logo\" src=\"https://github.com/snarkify/sirius/assets/3767044/6afd527d-1ff3-4a1f-886a-071060121c91\"\u003e\n\n\u003e Sirius, renowned as the most luminous star in the night sky,\n\u003e deceives the naked eye by appearing as a solitary point of light when,\n\u003e in fact, it is a binary star system. Inspired by this duality,\n\u003e our project bears the name Sirius, capturing the essence of folded instances\n\u003e that give the illusion of being a singular entity.\n\n# Introduction\n\nSirius is an open-source **Plonkish Folding Framework** for Incrementally Verifiable Computation [[IVC](https://iacr.org/archive/tcc2008/49480001/49480001.pdf)]. \n\n\u003cp align=\"center\"\u003e\n\u003cimg width=\"500\" alt=\"fig1\" src=\"https://github.com/snarkify/sirius/assets/3767044/5adba269-ec82-45e2-9b05-427a05104553\"\u003e\n\u003c/p\u003e\n\n\nWithin 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 $z_i$ and $w$, and yields an output $z_{i+1}$.\n\n# Architecture\n\nThe `Sirius` folding framework is designed with a three-tiered architecture.\n\n\u003cp align=\"center\"\u003e\n\u003cimg width=\"800\" alt=\"fig2\" src=\"https://github.com/snarkify/sirius/assets/3767044/85381c56-053c-4399-8947-1509eec958bc\"\u003e\n\u003c/p\u003e\n\n- **Arithmetization Layer**: This layer serves as the interface of the constraint system. User-defined circuits and witness data are converted into an intermediate representation format defined by the folding scheme. Our current implementation follows the _special-sound interactive protocol_ (SPS) from [Protostar](https://eprint.iacr.org/2023/620).\n- **Folding Scheme Layer**: At the heart of the framework is the folding scheme IVC circuit that accumulates the computations of multiple steps. At each step, the prover first calculates the instance-witness pairs from the previous step and folds them into the accumulator, then computes the cross terms and error vector for the folded instance-witness pairs. An IVC circuit then takes the outputs from the prover and performs the following steps: apply the step function `F`, fold the previous step's instance into the accumulator instance, and verify the inputs of the IVC circuit.\n- **SNARK Layer**: The SNARK layer leverages Polynomial Interactive Oracle Proofs (PIOP) and Polynomial Commitment Schemes (PCS) to generate zkSNARKs for succinct and zero-knowledge verification. Polynomial relation checks of the IVC decider are converted to the _multivariate sum-check protocol_. The evaluation phase of the sum-check protocol depends on the polynomial commitment scheme (PCS) we choose, e.g. [Hyrax](https://eprint.iacr.org/2017/1132.pdf). It is worth noting that when the polynomials are sparse, we can use the Spark compiler from [Spartan](https://eprint.iacr.org/2019/550) to handle them efficiently. \n\n## Emerging Architectures for IVC\n\nSirius has evolved to support multiple IVC schemes that combine folding techniques with novel optimizations:\n\n### Sangria\n\nSangria adapts Nova's folding scheme for the more flexible PLONKish arithmetization. By incorporating relaxed gate equations with a scaling factor `u` and an error vector `e`, Sangria supports custom gates and higher-arity circuits while managing the additional cross-terms introduced by higher-degree constraints.\n\n### Cyclefold + Protogalaxy\n\nCyclefold represents a significant advancement in our folding scheme evolution. Its key insight is that folding-based recursive arguments can function without needing a full cycle of elliptic curves for every operation. Instead, Cyclefold delegates expensive non-native scalar multiplication and point addition operations to a compact \"co-processor\" circuit defined over a secondary elliptic curve. This dramatically reduces the size of the verifier circuit on the non-pairing-friendly curve and simplifies security reasoning.\n\nWhile Cyclefold targets the efficiency of recursive proof composition, Protogalaxy NIFS focuses on optimizing high-degree gate constraints. In many PLONKish circuits, custom gates may have degrees higher than two—and naive folding would increase cryptographic work linearly with the degree. Protogalaxy NIFS introduces optimizations that reduce this overhead nearly to a constant cost per high-degree gate.\n\nTogether, these IVC schemes form the foundation of Sirius, offering different trade-offs between flexibility, efficiency, and security to meet diverse application needs.\n\n# Roadmap\n- [x] 2023Q4 - [halo2](https://github.com/privacy-scaling-explorations/halo2) frontend support\n- [x] 2023Q4 - folding scheme for plonkish custom gates\n- [x] 2023Q4 - folding scheme for lookup arguments\n- [x] 2024Q1 - IVC circuit\n- [x] 2024Q1 - IVC Benchmarks\n- [x] [2024Q2](https://github.com/snarkify/sirius/milestone/2) - high-degree gates optimization from [Protogalaxy](https://eprint.iacr.org/2023/1106)\n- [x] [2024Q3](https://github.com/snarkify/sirius/milestone/3) - IVC with cyclefold\n\n_The estimated timeline is subject to change_.\n\n# Getting Started\n\n## Install Rust\n\nUse [rustup](https://rustup.rs/)\n\n## Add dependency\n\n```bash\ncargo add --git https://github.com/snarkify/sirius.git --tag v0.2.0 sirius\n```\n\n## Implement `StepCircuit` trait\n\n```rust,no_run\nuse sirius::ff::PrimeField;\nuse sirius::ivc::step_circuit::{ConstraintSystem, Layouter, AssignedCell, SynthesisError};\n\n/// The StepCircuit trait is the foundation for creating circuits that can be folded.\n/// It represents a single step of computation in an IVC chain.\n///\n/// `ARITY` - The number of input/output elements in your circuit\n/// `F` - The field type used for circuit arithmetic\npub trait StepCircuit\u003cconst ARITY: usize, F: PrimeField\u003e {\n    /// Configuration type for your circuit gates and constraints\n    type Config: Clone;\n    \n    /// Define the circuit's constraints and gates\n    /// This is similar to halo2's configure method\n    fn configure(cs: \u0026mut ConstraintSystem\u003cF\u003e) -\u003e Self::Config;\n    \n    /// This method implements the actual step function transformation: z_i → z_{i+1}\n    ///\n    /// Unlike standard `halo2::Circuit`, this method:\n    /// - Takes an array of assigned input values (z_in)\n    /// - Must return an array of assigned output values of the same size\n    /// - Uses the same layouter pattern as halo2 for region assignments\n    fn synthesize_step(\n        \u0026self,\n        config: Self::Config,                // Circuit configuration from configure()\n        layouter: \u0026mut impl Layouter\u003cF\u003e,\n        z_in: \u0026[AssignedCell\u003cF, F\u003e; ARITY],  // Input values from previous step (or initial values)\n    ) -\u003e Result\u003c[AssignedCell\u003cF, F\u003e; ARITY], SynthesisError\u003e;\n}\n``` \n\n## Setup and run `IVC` instance\n\nFor runnable examples, please check [examples](examples) folder.\n\nSirius supports multiple IVC schemes: **Sangria** \u0026 **Cyclefold**\n\n### Run `Sangria IVC`\n\n```rust,no_run\n/// Example demonstrating how to use Sangria IVC for incrementally verifiable computation\n\nuse std::{array, num::NonZeroUsize};\nuse sirius::{\n    commitment::CommitmentKey,\n    ivc::{step_circuit::trivial, SangriaIVC},\n    sangria_prelude::bn256::{new_default_pp, C1Affine, C1Scalar, C2Affine, C2Scalar},\n    ff::Field,\n};\n\n/// Sangria uses a dual-circuit architecture:\n/// 1. Primary circuit performs the actual computational steps\n/// 2. Secondary circuit handles cryptographic operations for folding\nconst PRIMARY_ARITY: usize = 5;   // Number of state elements for main computation circuit\nconst SECONDARY_ARITY: usize = 1; // Number of state elements for helper circuit \n\n/// Configuration parameters - must be tuned based on circuit complexity\n/// These are minimum values for the trivial example\nconst PRIMARY_COMMITMENT_KEY_SIZE: usize = 21;   // Controls polynomial degree (primary curve)\nconst SECONDARY_COMMITMENT_KEY_SIZE: usize = 21; // Controls polynomial degree (secondary curve)\n\nconst PRIMARY_CIRCUIT_TABLE_SIZE: u32 = 17;      // Minimum required table size for primary\nconst SECONDARY_CIRCUIT_TABLE_SIZE: u32 = 17;    // Minimum required table size for secondary\n\n// Step 1: Initialize primary and secondary circuits\n// Primary circuit operates on bn256 curve with 5 state elements\nlet primary_circuit = trivial::Circuit::\u003cPRIMARY_ARITY, C1Scalar\u003e::default();\n\n// Secondary circuit operates on grumpkin curve with 1 state element\nlet secondary_circuit = trivial::Circuit::\u003cSECONDARY_ARITY, C2Scalar\u003e::default();\n\n// Step 2: Set up commitment keys for polynomial commitments on both curves\nlet primary_key = CommitmentKey::\u003cC1Affine\u003e::setup(PRIMARY_COMMITMENT_KEY_SIZE, b\"bn256\");\nlet secondary_key = CommitmentKey::\u003cC2Affine\u003e::setup(SECONDARY_COMMITMENT_KEY_SIZE, b\"grumpkin\");\n\n// Step 3: Create the public parameters that define the Sangria IVC instance\nlet public_params = new_default_pp::\u003cPRIMARY_ARITY, _, SECONDARY_ARITY, _\u003e(\n    SECONDARY_CIRCUIT_TABLE_SIZE,\n    \u0026primary_key,\n    \u0026primary_circuit,\n    PRIMARY_CIRCUIT_TABLE_SIZE,\n    \u0026secondary_key,\n    \u0026secondary_circuit,\n);\n\n// Step 4: Execute folding for 10 steps, starting with specified initial values\n// This performs z_0 → z_1 → z_2 → ... → z_10 with proof accumulation\nlet result = SangriaIVC::fold_with_debug_mode(\n    \u0026public_params,\n    \u0026primary_circuit,\n    array::from_fn(|i| C1Scalar::from(i as u64)),   // Primary initial state [0,1,2,3,4]\n    \u0026secondary_circuit,\n    array::from_fn(|i| C2Scalar::from(i as u64)),   // Secondary initial state [0]\n    NonZeroUsize::new(10).unwrap(),                 // Number of fold steps to perform\n)\n.unwrap();\n```\n\nFor a complete working example with detailed comments about private inputs between steps, see the full implementation at [examples/sangria_trivial.rs](examples/sangria_trivial.rs)\n\n### Run `Cyclefold IVC`\n\n```rust,no_run\n/// Example demonstrating how to use Cyclefold IVC for incrementally verifiable computation\nuse std::array;\n\nuse sirius::{\n    commitment::CommitmentKey,\n    ivc::step_circuit::trivial,\n    cyclefold_prelude::{\n        bn256::{C1Affine, C1Scalar, C2Affine},\n        PublicParams, IVC,\n    },\n    ff::Field,\n};\n\nconst CIRCUIT_ARITY: usize = 5;   // Number of state elements in computation circuit\n\n/// Configuration parameters - must be tuned based on circuit complexity\n/// For production use, these values typically need to be larger\nconst PRIMARY_COMMITMENT_KEY_SIZE: usize = 23;   // Controls polynomial degree (primary curve)\nconst SECONDARY_COMMITMENT_KEY_SIZE: usize = 23; // Controls polynomial degree (secondary curve)\nconst PRIMARY_CIRCUIT_TABLE_SIZE: u32 = 20;      // Minimum required table size\n\n// Step 1: Initialize the main computation circuit\n// This circuit operates on the bn256 curve with 5 state elements\nlet circuit = trivial::Circuit::\u003cCIRCUIT_ARITY, C1Scalar\u003e::default();\n\n// Step 2: Set up commitment keys for both curves\n// Primary key for the main circuit (bn256 curve)\nlet primary_key = CommitmentKey::\u003cC1Affine\u003e::setup(PRIMARY_COMMITMENT_KEY_SIZE, b\"bn256\");\n// Secondary key for the co-processor (grumpkin curve)\nlet secondary_key = CommitmentKey::\u003cC2Affine\u003e::setup(SECONDARY_COMMITMENT_KEY_SIZE, b\"grumpkin\");\n\n// Step 3: Create public parameters for Cyclefold IVC\n// Note: Parameters are mutable during initialization (unlike Sangria)\nlet mut public_params = PublicParams::new(\n    \u0026circuit,\n    primary_key,\n    secondary_key,\n    PRIMARY_CIRCUIT_TABLE_SIZE,\n)\n.unwrap();\n\n// Step 4: Initialize and execute IVC step-by-step with verification\n// This demonstrates the incremental nature of Cyclefold IVC\nlet ivc_result = IVC::new(\u0026mut public_params, \u0026circuit, array::from_fn(|_| C1Scalar::ZERO)) // Initialize with z_0 = [0,0,0,0,0]\n    .expect(\"Failed to initialize IVC (step=0)\")\n    .next(\u0026public_params, \u0026circuit)                                         // Compute z_1 = F(z_0, w_1)\n    .expect(\"Failed to compute next step (step=1)\")\n    .verify(\u0026public_params)                                                 // Verify the computation\n    .expect(\"Failed to verify computation\");\n```\n\nFor a complete working example with detailed comments about private inputs between steps, see the full implementation at [examples/cyclefold_trivial.rs](examples/cyclefold_trivial.rs)\n\n## Key Differences Between Sangria and Cyclefold\n\nBoth examples demonstrate how to set up and run IVC instances, but they highlight important architectural differences:\n\n**Sangria IVC**:\n- Uses a **dual-circuit approach**: primary for actual computation, secondary for cryptographic operations\n- Requires separate configuration of both circuits with matching commitment settings\n- Executes all steps at once via `fold_with_debug_mode` (i.e., runs 10 steps in a single call)\n- The public parameters are immutable\n\n**Cyclefold IVC**:\n- Uses a **single main circuit** with a specialized co-processor architecture\n- The co-processor handles expensive elliptic curve operations internally\n- Follows a step-by-step execution model via `new()`, `next()`, and `verify()`\n- The public parameters are mutable during initialization\n- Typically offers better performance for recursive proof composition\n\nChoose between them based on your specific requirements for efficiency, flexibility, and complexity.\n\n# Run examples\n\nFor runnable examples, please check [examples](examples) folder.\n\n```bash\n# 're' is short for 'run example'\n\n# Alias to run IVC with parameterization via cli arguments\ncargo re-cli --help\n\n# Alias for run the IVC for trivial `StepCircuit` (just returns its input unchanged)\ncargo re-trivial\n\n# Alias for run the IVC for the poseidon-circuit\ncargo re-poseidon\n```\n\n# Time-Profiling \n\nSpan lifetime tracking implemented, which allows you to understand in detail\nhow long a particular step takes to complete.\n\n```bash\n# 're' is short for 'run example'\n\n# By default, it will output all spans with a lifetime greater than 1s\ncargo re-poseidon | python3 .scripts/build_profiling.py\n\n# It is possible to specify the bottom border of the output span\ncargo re-poseidon | python3 .scripts/build_profiling.py --min-runtime 0.1s\n\n# You can also store logs and process them at a later date\ncargo re-poseidon \u003e log; cat log | python3 .scripts/build_profiling.py \n```\n\n# Memory-Profiling \nThe [dhat](https://valgrind.org/docs/manual/dh-manual.html) utility and the [dhat-rs](https://github.com/nnethercote/dhat-rs) experimental crate are used\n\n```bash\n# Run dhat with default IVC (poseidon+trivial)\ncargo cli-dhat\n\n# Check available params of run\ncargo cli-dhat --help\n```\n\n# Benchmark \n\nFor benches, please check [benches](benches) folder.\n\n```bash\ncargo bench\n```\n\n## Criterion\nYou can also get a more detailed report. Please check for info [criterion.rs](https://github.com/bheisler/criterion.rs)\n\n```bash\ncargo criterion\n```\n\n# Getting Involved\n\nWe'd love for you to be a part of our community!\n\nIf 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.\n\n:point_right: [Join our developer community](https://t.me/+oQ04SUgs6KMyMzlh)\n\nThank you for your interest in contributing to `Sirius`! :sparkles:\n","funding_links":[],"categories":["Rust","Code (software repositories)"],"sub_categories":["Teaching / experimental implementations"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsnarkify%2Fsirius","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsnarkify%2Fsirius","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsnarkify%2Fsirius/lists"}