Bellman zkSNARK library for community with Ethereum's BN256 support

Overview

bellman "Community edition"

Originally developed for ZCash, with extensions from us to make it a little more pleasant. Uses our "community edition" pairing for Ethereum's BN256 curve. Now published as bellman_ce on crate.io to allow ease of use.

Features

There are two available features to be used in production and are stable and will not be changed in terms of API. Those are Groth16 proof system implementation.

  • multicore feature (enabled by default) is intended to be run on PC and in environments that have support of a full std including threading.
  • singlecore feature is mainly intended for WASM systems, where non-compatible external crates are removed, along with all the multithreading.

Due to request to have a maintainable repo with WASM compatibility those features were implemented during the implementation of GM17 and SONIC proof systems. That's why there are two more features that are incomplete and will have breaking changes in a future. Those are for interested enthusiasts.

  • gm17 - is incomplete and most likely will get attention after putting SONIC to completeness.
  • sonic - 90% complete. Original implementation of helped protocol is integrated with API similar to the Groth16, along with wrapping adapters to use existing circuits without any changes. unhelped version is not yet complete, but all cryptographical primitives are implemented and tested. Right now it's a priority.

Future progress

It's intended to add GM17 proof system and SONIC proof system.

Features

There are two available features to be used in production and are stable and will not be changed in terms of API. Those are Groth16 proof system implementation.

  • multicore feature (enabled by default) is intended to be run on PC and in environments that have support of a full std including threading.
  • singlecore feature is mainly intended for WASM systems, where non-compatible external crates are removed, along with all the multithreading.

Due to request to have a maintainable repo with WASM compatibility those features were implemented during the implementation of GM17 and SONIC proof systems. That's why there are two more features that are incomplete and will have breaking changes in a future. Those are for interested enthusiasts.

  • gm17 - is incomplete and most likely will get attention after putting SONIC to completeness.
  • sonic - 90% complete. Original implementation of helped protocol is integrated with API similar to the Groth16, along with wrapping adapters to use existing circuits without any changes. unhelped version is not yet complete, but all cryptographical primitives are implemented and tested. Right now it's a priority.

Future progress

It's intended to add GM17 proof system and SONIC proof system.

License

Licensed under either of

at your option.

Code Examples:

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Comments
  • what does field STATE_WIDTH and CAN_ACCESS_NEXT_TRACE_STEP mean of PlonkConstraintSystemParams?

    what does field STATE_WIDTH and CAN_ACCESS_NEXT_TRACE_STEP mean of PlonkConstraintSystemParams?

    in latest better_better_cs module, PlonkConstraintSystemParams as follow: pub trait PlonkConstraintSystemParams<E: Engine>: Sized + Copy + Clone + Send + Sync { const STATE_WIDTH: usize; const WITNESS_WIDTH: usize; const HAS_WITNESS_POLYNOMIALS: bool; const HAS_CUSTOM_GATES: bool; const CAN_ACCESS_NEXT_TRACE_STEP: bool; }

    here what does field STATE_WIDTH and CAN_ACCESS_NEXT_TRACE_STEP mean?
    and what is difference between STATE_WIDTH and WITNESS_WIDTH? looks confusing . Can anybody explain ?

    Thanks in advance !

    opened by DreamWuGit 9
  • performance(PLONK): prove_by_steps vs prove

    performance(PLONK): prove_by_steps vs prove

    I wonder why in exit we use prove_by_steps (https://github.com/matter-labs/bellman/blob/f551a55d83d2ea604b2dbfe096fd9dcfdaedb189/src/plonk/mod.rs#L132) instead of prove (https://github.com/matter-labs/bellman/blob/f551a55d83d2ea604b2dbfe096fd9dcfdaedb189/src/plonk/mod.rs#L324)?

    Is it because prove_by_steps has a better performance?

    opened by HAOYUatHZ 5
  • Using pairing_ce verison 0.21 will cause pinic when handle GroupDecodingError?

    Using pairing_ce verison 0.21 will cause pinic when handle GroupDecodingError?

    https://github.com/matter-labs/bellman/blob/8a96585679a8bee091d510a931e9c2d79b7a3e0b/src/groth16/mod.rs#L65 I choose a false case using an invalid proof(a point is not on curve). It will be panic here.

    When input an invalid ec point and call into_affine, then get GroupDecodingError. It will cause panic, stack overflowed.

    The error may be from the recent commit in pairing_ce verison 0.21. https://github.com/matter-labs/pairing/blob/977b192b3fe9a14acf943fa0f04a41add1208725/src/lib.rs#L330 In pairing_ce verison 0.21, modified to "self.to_string()" from "self.description()" would cause recursive calling.

    opened by XuyangSong 5
  • Make logging a compile option in order to support ewasm compatibility

    Make logging a compile option in order to support ewasm compatibility

    Hey Matter-Labs team,

    We are currently using bellman on an execution environment, and running it with scout. It runs great, the only thing we needed to change is to remove the logging capability. This PR adds the feature nolog which deactivate the logging capability.

    In order to use bellman in an Eth2.0 EE, one would need to import it with:

    features = ["wasm", "nolog"], default-features = false
    

    I did it with a minimal amount of changes. For instance, I choosed to prefix all the stopwatch variable with an underscore (which, I agree, is not the cleaniest the way to deal with unused variable) instead of compiling out every occurence of stopwatch when nolog is enabled because that would be less maintainable.

    Also, I made sure that this compile with:

    • wasm
    • sonic
    • gm17

    Please let me know, if you think anything should be changed

    opened by AlexandreBelling 5
  • Question about plonk proof input fields

    Question about plonk proof input fields

    hi, experts I see bellman plonk proof structure pub struct Proof<E: Engine, P: PlonkConstraintSystemParams> { pub num_inputs: usize, pub n: usize, pub input_values: Vec<E::Fr>, pub wire_commitments: Vec<E::G1Affine>, pub grand_product_commitment: E::G1Affine, pub quotient_poly_commitments: Vec<E::G1Affine>, pub wire_values_at_z: Vec<E::Fr>, pub wire_values_at_z_omega: Vec<E::Fr>, pub grand_product_at_z_omega: E::Fr, pub quotient_polynomial_at_z: E::Fr, pub linearization_polynomial_at_z: E::Fr, pub permutation_polynomials_at_z: Vec<E::Fr>, pub opening_at_z_proof: E::G1Affine, pub opening_at_z_omega_proof: E::G1Affine, pub(crate) _marker: std::marker::PhantomData

    } my understanding of filed num_inputs is number of public input elements and field " input_values" is public input element 's values , So the input_values.length should be equal to num_inputs? if yes, num_inputs can be omit , am I right ? correct me if I am wrong , Thanks a lot

    opened by DreamWuGit 4
  • Enforce for Transpiler in PLONK system

    Enforce for Transpiler in PLONK system

    In the enforce function for Transpiler, when handle the type of constraint LC * const = LC or const * LC = LC, the free_constant_term is set as follows. https://github.com/matter-labs/bellman/blob/f551a55d83d2ea604b2dbfe096fd9dcfdaedb189/src/plonk/better_cs/adaptor.rs#L1030-L1032 However, the free_constant_term should be initialized as a_constant_term or b_constant_term, depending on which one is the linear combination.

    opened by skipjack8 4
  • Adding Single-threaded mode

    Adding Single-threaded mode

    Since this one is not getting anywhere and people are still looking for a solution to target wasm.


    Hello everybody, a couple of people in the community seem to be interested to run bellman in single-threaded mode, in particular to target wasm. This PR adds a "multithread" compile option which is activated as default. In order to run in single-threaded mode compile using --no-std-features.

    opened by stefandeml 3
  • fix crash & incorrect z_omega computation in prove step for target wasm

    fix crash & incorrect z_omega computation in prove step for target wasm

    We are implementing the Web&NodeJS bellman prover plonkjs, and met the same issue as #38.

    Issue and fix

    After diving into the difference between the two proof of wasm and multicore, we found that the code block in https://github.com/matter-labs/bellman/blob/beta/src/plonk/better_cs/prover/prove_steps.rs#L1296 is not correctly implemented.

    Explain it with a simple example as below:

    fn main() {
        let mut polys = vec![(1, 2), (5, 6), (20, 30)];
        let count = 1;
        for p in polys.chunks_mut(2) {
            println!("p : {:?}", p);      // **p : [(1, 2), (5, 6)];** p : [(20, 30)] 
            for elem in p.iter_mut() {
                let (m, n) = elem;
                println!("m, n = {} {}", m, n);  // **m, n = 1 2;** m, n = 5 6
                *elem = ((*m) + (*n), *n);
                println!("updated tuple {:?}", elem); // **updated tuple (3, 2), updated tuple (11, 6);**  updated tuple (50, 30)
            }
        }
    }
    

    In bellmen's current implementation, the Scope limits the task for each thread, but line 6 above is missed:

    worker.scope(polys.len(), |scope, chunk| {
                for p in polys.chunks_mut(chunk) {
                    scope.spawn(move |_| {
                        let (poly, at) = &p[0];
                        let at = *at;
                        let result = divide_single::<E>(poly.as_ref(), at);
                        p[0] = (Polynomial::from_coeffs(result).unwrap(), at);
                    });
                }
            });
    

    For feature wasm, the p is a chunk with 2 tuples(with polys.lens() elements in polys, which means all the elements), and each time it just calculates the poly_to_divide_at_z, ignoring the poly_to_divide_at_z_omega.

    For feature multicore, it seems to work as expected each time, actually, it did. Because the code below

          let chunk_size = self.get_chunk_size(elements);
    
         crossbeam::scope(|scope| {
                f(scope, chunk_size)
            }).expect("must run")
        }
    
    

    digests the whole polys array, and splits it into chunks of chunk_size=1. The get_chunk_size always returns 1.

    So the fix here is to put the number of chunk_size elements in scope, as we expected.

    Another fix for wasm is due to the import of std::time::Instant, which raises crash in wasm. we can replace it with https://github.com/sebcrozet/instant.

    Test

    Just use the repo in #38 and modify the bellman's git to https://github.com/0xEigenLabs/bellman at branch beta. you can check out both proofs are valid.

    @shamatar Plz check out our fix. @weijiekoh Feel free to verify the fix for issue #38.

    opened by eigmax 2
  • WASM compatibility

    WASM compatibility

    Extracted all logs and timers calls to a separate file Added WASM specific logging and profiling

    now wasm cross compilation works out of the box without runtime crashes when used with wasm feature and no multicore feature

    opened by poma 2
  • Wrong size in commit_fe?

    Wrong size in commit_fe?

    https://github.com/matter-labs/bellman/blob/455480a2db44ecc0423785b295981074800913e6/src/plonk/commitments/transcript/keccak_transcript.rs#L135

    Should it be the element size rather than the fr size?

    commit_fe is used as follows, input a fq as parameter.

    https://github.com/matter-labs/bellman/blob/455480a2db44ecc0423785b295981074800913e6/src/plonk/better_cs/utils.rs#L249

    It has the same size on bn curv, with result 32bytes. It will be different on bls12_381 curv.

    opened by XuyangSong 1
  • fix build for x86 arch

    fix build for x86 arch

    This PR fixes the build to the i686-linux-android architecture.

    I tried to cross-compile the zksync-crypto library for Android and I have the following errors:

    $ cargo build --target i686-linux-android
       Compiling bellman_ce v0.3.2
    error[E0433]: failed to resolve: could not find `x86_64` in `arch`
      --> src/prefetch.rs:43:64
       |
    43 |                 _mm_prefetch(pointer as *const i8, core::arch::x86_64::_MM_HINT_T0);
       |                                                                ^^^^^^ could not find `x86_64` in `arch`
    
    error[E0433]: failed to resolve: could not find `x86_64` in `arch`
      --> src/prefetch.rs:56:64
       |
    56 |                 _mm_prefetch(pointer as *const i8, core::arch::x86_64::_MM_HINT_T1);
       |                                                                ^^^^^^ could not find `x86_64` in `arch`
    
    error[E0433]: failed to resolve: could not find `x86_64` in `arch`
      --> src/prefetch.rs:69:64
       |
    69 |                 _mm_prefetch(pointer as *const i8, core::arch::x86_64::_MM_HINT_T2);
       |                                                                ^^^^^^ could not find `x86_64` in `arch`
    
    error[E0433]: failed to resolve: could not find `x86_64` in `arch`
      --> src/prefetch.rs:82:78
       |
    82 |                 _mm_prefetch(reference as *const T as *const i8, core::arch::x86_64::_MM_HINT_T0);
       |                                                                              ^^^^^^ could not find `x86_64` in `arch`
    
    error[E0433]: failed to resolve: could not find `x86_64` in `arch`
      --> src/prefetch.rs:95:78
       |
    95 |                 _mm_prefetch(reference as *const T as *const i8, core::arch::x86_64::_MM_HINT_T1);
       |                                                                              ^^^^^^ could not find `x86_64` in `arch`
    
    error[E0433]: failed to resolve: could not find `x86_64` in `arch`
       --> src/prefetch.rs:108:78
        |
    108 |                 _mm_prefetch(reference as *const T as *const i8, core::arch::x86_64::_MM_HINT_T2);
        |                                                                              ^^^^^^ could not find `x86_64` in `arch`
    
    error: aborting due to 6 previous errors
    
    For more information about this error, try `rustc --explain E0433`.
    error: could not compile `bellman_ce`.
    
    To learn more, run the command again with --verbose.
    
    opened by adetante 1
  • Circuit is satisfied but plonk proof verification fails

    Circuit is satisfied but plonk proof verification fails

    Hi! I have the following test using the current tip of dev (09474a):

      #[test]
      fn setup_prove_verify() {
          // the program `def main(public field a) -> field { return a }`
          let program: Prog<Bn128Field> = Prog {
              arguments: vec![Parameter::public(Variable::new(0))],
              return_count: 1,
              statements: vec![Statement::constraint(Variable::new(0), Variable::public(0))],
          };
    
          // generate a dummy universal setup of size 2**10
          let crs: Crs<<Bn128Field as BellmanFieldExtensions>::BellmanEngine, CrsForMonomialForm> =
          Crs::<<Bn128Field as BellmanFieldExtensions>::BellmanEngine, CrsForMonomialForm>::dummy_crs(2usize.pow(10) as usize);
    
          // transpile
          let hints = transpile(Computation::without_witness(program.clone())).unwrap();
    
          // run a circuit specific (transparent) setup
          let pols = setup(Computation::without_witness(program.clone()), &hints).unwrap();
    
          // generate a verification key from the circuit specific setup and the crs
          let vk = make_verification_key(&pols, &crs).unwrap();
    
          // run the program
          let interpreter = Interpreter::default();
    
          // extract the witness
          let witness = interpreter
              .execute(program.clone(), &[Bn128Field::from(42)])
              .unwrap();
    
          // bundle the program and the witness together
          let computation = Computation::with_witness(program.clone(), witness);
          // transpile
          let hints = transpile(Computation::without_witness(program.clone())).unwrap();
    
          // check that the circuit is satisfied
          assert!(is_satisfied(computation.clone(), &hints).is_ok());
    
          // generate a proof with no setup precomputations and no init params for the transcript, using Blake2s
          let proof: BellmanProof<<Bn128Field as BellmanFieldExtensions>::BellmanEngine, PlonkCsWidth4WithNextStepParams> =
                  prove_by_steps::<_, _, Blake2sTranscript<_>>(
                      computation,
                      &hints,
                      &pols,
                      None,
                      &crs,
                      None,
                  )
                  .unwrap();
    
          // verify the proof using Blake2s
          let ans = verify::<_, Blake2sTranscript<_>>(&proof, &vk).unwrap();
    
          // check that the proof is verified
          assert!(ans);
      }
    

    I would have expected the proof to be verified correctly because the circuit is satisfied, but this test fails. I checked and it fails in the last check in verification.

    Is there something I am doing wrong here? Thanks!

    opened by Schaeff 4
  • how to read snarkjs generated proof.json file?

    how to read snarkjs generated proof.json file?

    I am trying to verify the result with snarkjs generated files (proof.json, public.json and verfication_key.json). But I didn't see any example for it. How to achieve this?

    opened by howjmay 0
  • Plonk proofs are invalid if bellman is compiled with the wasm feature

    Plonk proofs are invalid if bellman is compiled with the wasm feature

    Thank you for writing this library! I'm experimenting with using it to produce Plonk proofs in WASM. However, I'm facing an issue.

    If I compile using the wasm feature, the Plonk proofs produced are invalid. If I do so with multicore, however, the proofs are valid. This can be seen through this demonstration: https://github.com/weijiekoh/bellman_ce_bug

    The underlying issue is that the opening_at_z_omega_proof differs. All other values of the proof match.

    opened by weijiekoh 6
  • GPU implementation for multiexp and fft

    GPU implementation for multiexp and fft

    I have implemented GPU accelerate for multiexp and FFT motived by the filecoin implementation, which can greatly improve the efficiency of prover. I use this implementation to accelerate the recursive snarks of PLONK, the native implementation of recursive_aggregation_circuit need nearly 6hours to generate a merge proof for 2 proofs, while our GPU implementation, it spent only 10 minutes.

    opened by chenhuan14 7
Releases(audit_2)
  • audit_2(Apr 9, 2020)

  • 0.3.1(Jul 15, 2019)

    • Some potentially time-consuming operations such as scalars conversion from Montgomery form are now parallelized
    • Multicore users can now use nightly version of Rust and specify nightly feature to get ~10% speedup on for proof generation over large circuits due to faster multiexponentiation
    Source code(tar.gz)
    Source code(zip)
  • 0.3.0(Mar 31, 2019)

    Publish to crates.io as bellman_ce. No more pain for users specifying dependencies. Now can also use ff_ce, ff_derive_ce and pairing_ce as dependencies.

    Source code(tar.gz)
    Source code(zip)
  • 0.2.0(Mar 5, 2019)

    • Add singlethreaded version
    • Now “ff” and “pairing” crates are re-exported as “bellman::pairing::ff” and ”bellman::pairing”
    • If for some reason you need to use “pairing” or “ff” directly and don’t want to use re-exports, than to avoid errors you should specify tag 0.16.2 for “pairing” and 0.5 for “ff”
    Source code(tar.gz)
    Source code(zip)
Owner
Matter Labs
Practical applications of Zero-Knowledge Proofs
Matter Labs
A Rust library for the Marlin preprocessing zkSNARK

Marlin marlin is a Rust library that implements a preprocessing zkSNARK for R1CS with universal and updatable SRS This library was initially developed

arkworks 215 Dec 6, 2022
The Light Protocol program verifies zkSNARK proofs to enable anonymous transactions on Solana.

Light Protocol DISCLAIMER: THIS SOFTWARE IS NOT AUDITED. Do not use in production! Tests cd ./program && cargo test-bpf deposit_should_succeed cd ./pr

null 36 Dec 17, 2022
L2 validity rollup combined with blind signatures over elliptic curves inside zkSNARK, to provide offchain anonymous voting with onchain binding execution on Ethereum

blind-ovote Blind-OVOTE is a L2 voting solution which combines the validity rollup ideas with blind signatures over elliptic curves inside zkSNARK, to

Aragon ZK Research 3 Nov 18, 2022
An Ethereum compatible Substrate blockchain for bounties and governance for the Devcash community.

Substrate Node Template A fresh FRAME-based Substrate node, ready for hacking ?? Getting Started Follow the steps below to get started with the Node T

null 4 Mar 30, 2022
Examples of cw20 usage, extracted from cw-plus, maintained by the community

CosmWasm Tokens This is a collection of cw20-related contracts extracted from cw-plus. These serve as examples of what is possible to build and as sta

CosmWasm 59 Jan 2, 2023
The Polkadot Hackathon Global Series North America edition is the second in a series of hackathons that brings the cutting edge of blockchain to a global community.

Polkadot Hackathon Project We are translating Uniswap v2 to Ink. Dependencies Install cargo-contract for building Ink contracts: cargo install dylint-

Kristiyan Dilov 3 Jun 28, 2022
Meta-repository for Miscreant: misuse-resistant symmetric encryption library with AES-SIV (RFC 5297) and AES-PMAC-SIV support

The best crypto you've never heard of, brought to you by Phil Rogaway A misuse resistant symmetric encryption library designed to support authenticate

miscreant. 480 Dec 8, 2022
Library with support for de/serialization, parsing and executing on data-structures and network messages related to Bitcoin

Rust Bitcoin Library with support for de/serialization, parsing and executing on data-structures and network messages related to Bitcoin. Heads up for

Rust Bitcoin Community 1.3k Dec 29, 2022
shavee is a Program to automatically decrypt and mount ZFS datasets using Yubikey HMAC as 2FA or any USB drive with support for PAM to auto mount home directories.

shavee is a simple program to decrypt and mount encrypted ZFS user home directories at login using Yubikey HMAC or a Simple USB drive as 2FA written in rust.

Ashutosh Verma 38 Dec 24, 2022
NFT & Marketplace Contracts with royalties and fungible token support. Sample React app included.

NFT Market Reference Implementation A PoC backbone for NFT Marketplaces on NEAR Protocol. Reference Changelog Changelog Progress: basic purchase of NF

NEAR App Examples 156 Apr 28, 2022
Generates a Nix expression for buildDotnetModule, with support for non nuget.org repos.

nuget2nix Generates a Nix expression for buildDotnetModule, with support for non nuget.org repos. Usage Similar to the nuget-to-nix command available

Winter 9 Dec 10, 2022
A simple to use dos tool to support Ukraine 🇺🇦

A short explanation How to download section | Guide for Windows | Guide for macOS This program visits various russian websites in order to keep the se

Grrwahrr 10 Apr 15, 2022
DFIP 2111-B: VOC: Ethereum Virtual Machine (EVM) Support

DeFiCh/metachain is a codename research & development for DFIP 2111-B: VOC: Ethereum Virtual Machine (EVM) Support . Proposed as a DFIP on Nov 2021; D

DeFiChain 19 Dec 6, 2022
An open source Rust high performance cryptocurrency trading API with support for multiple exchanges and language wrappers. written in rust(🦀) with ❤️

Les.rs - Rust Cryptocurrency Exchange Library An open source Rust high performance cryptocurrency trading API with support for multiple exchanges and

Crabby AI 4 Jan 9, 2023
High-level networking library that extends the bevy_replicon library to allow snapshot interpolation and client-side prediction

bevy_replicon_snap A Snapshot Interpolation plugin for the networking solution bevy_replicon in the Bevy game engine. This library is a very rough pro

Ben 3 Oct 15, 2023
A Rust library for working with Bitcoin SV

Rust-SV A library to build Bitcoin SV applications in Rust. Documentation Features P2P protocol messages (construction and serialization) Address enco

Brenton Gunning 51 Oct 13, 2022
A Rust library for generating cryptocurrency wallets

Table of Contents 1. Overview 2. Build Guide 2.1 Install Rust 2.2a Build from Homebrew 2.2b Build from Crates.io 2.2c Build from Source Code 3. Usage

Aleo 552 Dec 29, 2022
A modern TLS library in Rust

Rustls is a modern TLS library written in Rust. It's pronounced 'rustles'. It uses ring for cryptography and libwebpki for certificate verification. S

ctz 4k Jan 9, 2023
Sodium Oxide: Fast cryptographic library for Rust (bindings to libsodium)

sodiumoxide |Crate|Documentation|Gitter| |:---:|:-----------:|:--------:|:-----:|:------:|:----:| |||| NaCl (pronounced "salt") is a new easy-to-use h

sodiumoxide 642 Dec 17, 2022