A pure-Rust implementation of Bulletproofs using Ristretto.

Overview

Bulletproofs

The fastest Bulletproofs implementation ever, featuring single and aggregated range proofs, strongly-typed multiparty computation, and a programmable constraint system API for proving arbitrary statements (under development).

This library implements Bulletproofs using Ristretto, using the ristretto255 implementation in curve25519-dalek. When using the parallel formulas in the curve25519-dalek AVX2 backend, it can verify 64-bit rangeproofs approximately twice as fast as the original libsecp256k1-based Bulletproofs implementation.

This library provides implementations of:

  • Single-party proofs of single or multiple ranges, using the aggregated rangeproof construction;

  • Online multi-party computation for rangeproof aggregation between multiple parties, using session types to statically enforce correct protocol flow;

  • A programmable constraint system API for expressing rank-1 constraint systems, and proving and verifying proofs of arbitrary statements (unstable, under development with the yoloproofs feature);

  • Online multi-party computation for aggregated constraint system proofs (planned future work).

These proofs are implemented using Merlin transcripts, allowing them to be arbitrarily composed with other proofs without implementation changes.

The development roadmap can be found in the Milestones section of the Github repo.

The constraint system API is provided FOR EXPERIMENTS ONLY, and must be enabled by specifying the yoloproofs feature. It is not covered by semver compatibility and is SUBJECT TO CHANGE WITHOUT NOTICE.

Currently, the yoloproofs feature is disabled in the published version of the crate, so it can only be used by specifying a git dependency on the develop branch. This means that it is not possible to publish a crate using the R1CS API, because it is FOR EXPERIMENTS ONLY.

Documentation

The user-facing documentation for this functionality can be found here. In addition, the library also contains extensive notes on how Bulletproofs work. These notes can be found in the library's internal documentation:

Comparative Performance

The following table gives comparative timings for proving and verification of a 64-bit rangeproof on an Intel Skylake-X i7-7800X (@3.5GHz, Turbo Boost disabled). Times are in microseconds (lower is better), with the relative speed compared to the fastest implementation.

Implementation Group Proving (μs) rel Verification (μs) rel
ours (avx2) ristretto255 7300 1.00x 1040 1.00x
ours (u64) ristretto255 11300 1.54x 1490 1.43x
libsecp+endo secp256k1 14300 1.96x 1900 1.83x
libsecp-endo secp256k1 16800 2.30x 2080 2.00x
Monero ed25519 (unsafe) 53300 7.30x 4810 4.63x

Use of the curve25519-dalek IFMA backend gives another 1.5x speedup on a Cannonlake i3-8121U, increasing the verification speedup 3x over libsecp and 7x over Monero, but these processors are not yet generally available.

This crate also contains other benchmarks; see the Tests and Benchmarks section below for details on how to run them all.

Example

The following example shows how to create and verify a 32-bit rangeproof.

# // The #-commented lines are hidden in Rustdoc but not in raw
# // markdown rendering, and contain boilerplate code so that the
# // code in the README.md is actually run as part of the test suite.
#
# extern crate rand;
# use rand::thread_rng;
#
# extern crate curve25519_dalek;
# use curve25519_dalek::scalar::Scalar;
#
# extern crate merlin;
# use merlin::Transcript;
#
# extern crate bulletproofs;
# use bulletproofs::{BulletproofGens, PedersenGens, RangeProof};
#
# fn main() {
// Generators for Pedersen commitments.  These can be selected
// independently of the Bulletproofs generators.
let pc_gens = PedersenGens::default();

// Generators for Bulletproofs, valid for proofs up to bitsize 64
// and aggregation size up to 1.
let bp_gens = BulletproofGens::new(64, 1);

// A secret value we want to prove lies in the range [0, 2^32)
let secret_value = 1037578891u64;

// The API takes a blinding factor for the commitment.
let blinding = Scalar::random(&mut thread_rng());

// The proof can be chained to an existing transcript.
// Here we create a transcript with a doctest domain separator.
let mut prover_transcript = Transcript::new(b"doctest example");

// Create a 32-bit rangeproof.
let (proof, committed_value) = RangeProof::prove_single(
    &bp_gens,
    &pc_gens,
    &mut prover_transcript,
    secret_value,
    &blinding,
    32,
).expect("A real program could handle errors");

// Verification requires a transcript with identical initial state:
let mut verifier_transcript = Transcript::new(b"doctest example");
assert!(
    proof
        .verify_single(&bp_gens, &pc_gens, &mut verifier_transcript, &committed_value, 32)
        .is_ok()
);
# }

Building

To compile successfully, you will need to have nightly Rust installed, rather than stable.

You can install nightly Rust with rustup:

rustup default nightly

Tests and Benchmarks

Run tests with cargo test. Run benchmarks with cargo bench. This crate uses criterion.rs for benchmarks.

Features

The yoloproofs feature enables support for rank-1 constraint system proofs. It is UNSTABLE AND UNSUITABLE FOR DEPLOYMENT, and PROVIDED FOR TESTING ONLY.

The avx2_backend feature enables curve25519-dalek's AVX2 backend, which implements curve arithmetic using parallel formulas. To use it for Bulletproofs, the target_cpu must support AVX2:

RUSTFLAGS="-C target_cpu=skylake" cargo bench --features "avx2_backend"

Skylake-X CPUs have double the AVX2 registers. To use them, try

RUSTFLAGS="-C target_cpu=skylake-avx512" cargo bench --features "avx2_backend"

This prevents spills in the AVX2 parallel field multiplication code, but causes worse code generation elsewhere ¯\_(ツ)_/¯

About

This is a research project sponsored by Interstellar, developed by Henry de Valence, Cathie Yun, and Oleg Andreev.

Comments
  • Implement no_std support

    Implement no_std support

    This change implements no_std support for the bulletproofs crate. The changes are mostly mechanical. This is the culmination several PRs worth of work, with changes to curve25519 and merlin crates already merged and released.

    It was necessary to make minor modifications to some APIs, particularly in regards to RNGs. As discussed by @isislovecruft in #275, the APIs in this change are backwards compatible for those building the crate in std mode. So current users of the bulletproofs crate will see no change. Users wishing to build bulletproofs in no_std mode will need to call the new *_with_rng prove and verfiy functions, and pass in a RNG.

    This change is based on the main branch rather than the develop branch. This is because the main branch in the dalek repo has several changes that are not in the develop branch. This made rebasing my change on the upstream develop branch to be problematic.

    opened by xoloki 33
  • Two-phase circuit construction with intermediate commitments

    Two-phase circuit construction with intermediate commitments

    Problem

    Our current R1CS interface allows constructing constraints using challenges bound to the external variables (V). This, however, may be risky for complex circuits. For example, a shuffle gadget is only binding if inputs on both sides are committed. However, if one side remains uncommitted (e.g. when there is a circuit in between two shuffles and only "outer" sides are ultimately committed), then the low-level variables on that side can be forged based on the knowledge of the challenge.

    Disclaimer

    This is an over-the-napkin draft of a maybe-solution. Little attempt was made to analyze the alternatives or soundness of this proposal.

    Goal

    Make gadgets locally sound by giving an opportunity to commit to input low-level variables, regardless of whether they are indirectly committed via high-level variables.

    Proposal

    We split the circuit construction in two phases: wireframing phase and completion phase.

    Wireframing phase

    Gadgets can allocate low-level variables, add constraints, but cannot use challenges. This phase produces first pair of vector commitments A_I1 and A_O1 to these variables. The constraint system trait is called WireframeCS.

    This allow allocating all the gadgets and all variables between them, assigning required values to these variables. But not all gadgets can implement their internal constraints yet because they need challenge values.

    The phase ends with two points A_I1 and A_O1 computed and sent to the transcript, committing to all the low-level variables allocated so far.

    Completion phase

    Gadgets can allocate more low-level variables, add more constraints and can use challenges. This phase produces second pair of vector commitments A_I2 and A_O2 to these additional low-level variables. The constraint system trait is called CompleteCS.

    This allows implementing gadgets, such as shuffle or merge using challenges, making them locally sound because all input variables for any given gadget are already committed via A_I1/A_O1.

    After the Completion Phase is complete, full commitments to the low level variables are computed and sent to the transcript:

    transcript.commit_point(A_I2);
    transcript.commit_point(A_O2);
    let e = transcript.challenge_scalar();
    let A_I = A_I1 + e*A_I2;
    let A_O = A_O1 + e*A_O2;
    

    The verifier's logic is:

    1. The proof now contains 2 more points (A_I1,A_I2,A_O1,A_O2 instead of A_I,A_O).
    2. The verifier starts by making the wireframe of the circuit: allocating variables and adding constraints that do not use challenge values.
    3. Then, the verifier sends A_I1, A_O1 to the transcript.
    4. The verifier then completes the circuit by allocating more variables, adding more constraints and using challenges to compute weights for these constraints.
    5. The verifier sends A_I2, A_O2 to the transcript and gets a challenge e that prevents cancelling of one part of commitment by another.
    6. Finally, vector commitments are summed up to A_I and A_O which are used in the rest of the protocol: A_I = A_I1 + e*A_I2, A_O = A_O1 + e*A_O2. Note: we do not need to commit the resulting sum A_I as in current BP protocol because we've already committed both components individually (A_I1 and A_I2).
    7. The protocol proceeds as usual, only with challenge e applied to second subset of generators.

    Alternative: committing via additional high-level variables

    Committing to required low-level variables via additional high-level variables. This works using the current architecture almost w/o changes, but the proof size grows linearly with the size of the circuit.

    Alternative: multi-phase protocol

    The scheme above can be generalized to have arbitrary number of phases with A_I1,A_I2,A_I3,... etc. intermediate commitments. With use cases at hand, it seems that two phases might be enough. Also, the two-phase protocol guarantees a constant (64-byte) overhead in the proof size, while more flexible API could allow the proof to grow unbounded and harder to reason about its size.

    T-api E-medium T-r1cs 
    opened by oleganza 15
  • Make closure of challenge phase FnOnce.

    Make closure of challenge phase FnOnce.

    It allows for the challenge phase to accept closures that take some more context, e.g. moving non-Clone values in the challenge closure.

    This works in stable since Rust 1.35; cfr. https://github.com/rust-lang/rust/issues/28796.

    This closes issue #244.


    ~~In other news: I'm not yet happy with the 'static bound on the closures. Since I'm not yet worried about that kind of performance (just hacking around currently), I'm not going to fight the borrow checker there, yet.~~ Cfr #323

    opened by rubdos 13
  • Implement API for two-phase constraint system proofs

    Implement API for two-phase constraint system proofs

    This provides the implementation for two-phase protocol redesign as described in #222.

    Challenges are available in a section of code within a closure provided to cs.specify_randomized_constraints call:

    cs.specify_randomized_constraints(move |cs| {
        let z = cs.challenge_scalar(b"shuffle challenge");
        ...
    })
    

    Prover and Verifier now allow interspersing high-level variable commitments with the constraints in the first phase (which allows gadgets to introduce their own high-level variables during CS construction).

    Since the callbacks must return a known-to-the-framework error type (R1CSError) and some gadgets can be composed within the second phase (cf. tuple shuffle + scalar shuffle), this PR also introduces a catch-all error variant R1CSError::GadgetError which allows gadgets to signal inconsistency in their parameters.

    opened by oleganza 13
  • Update rand_core, curve25519-dalek, merlin versions.

    Update rand_core, curve25519-dalek, merlin versions.

    This is a breaking API change that will require a 2.0.0 version, but it keeps the crate up-to-date with the rand ecosystem. A possible further simplification of the dep tree would be to replace clear_on_drop by zeroize, but this could be done at any later point because clear_on_drop is an implementation detail.

    opened by hdevalence 11
  • Add benchmarks for BulletproofGens and PedersenGens

    Add benchmarks for BulletproofGens and PedersenGens

    I noticed BulletproofGens is quite slow with larger generator sizes. This commit adds a benchmark for both generators. Figured it may come in handy some day.

    opened by rubdos 11
  • Canonical serialization format for RangeProof

    Canonical serialization format for RangeProof

    This adds a canonical encoding algorithm for a RangeProof in form of to_bytes/from_bytes API. Serde trait is implemented in terms of these.

    The layout of an 2^n-bit range proof is defined as:

    • 4 compressed Ristretto points A, S, T_1, T_2,
    • 3 scalars t_x, t_x_blinding, e_blinding,
    • 2*n pairs of compressed Ristretto points L_0, R_0, ..., L_{n-1}, R_{n-1},
    • two scalars a and b.

    Total size: 32*(9+2*n) bytes.

    64-bit range proofs are encoded in 672 bytes, 32-bit range proofs are encoded in 608 bytes.

    Bonus: the compressed data is cached and reused in verification, so we do not incur unnecessary cost of compressing points that we decompressed just prior to verification.

    PS. Serde is intentionally not implemented for IPP as we don't seem to be exposing it directly to users. If we ever need to, we can add ser/de trait implementation like we do with RangeProof.

    PTAL T-optimization 
    opened by oleganza 11
  • Aggregated range proofs

    Aggregated range proofs

    done:

    • [x] get basic state machine prover & verifier to work
    • [x] restructure states to have separate commitment parts (suggestions from @oleganza )
    • [x] renaming suggestions from @oleganza
    • [x] make Proof::prove shortcut for single player version
    • [x] generate n*m generators for G, H
    • [x] update proof generation to index into generators correctly
    • [x] use random oracle API instead of commit function
    • [x] commit to other parts of the proof (n, m , V, etc)
    • [x] combine the state machine range proof approach with the aggregated proof math
    • [x] write an aggregator / "manager" (e.g. for getting commitments, returning challenges?)
    • [x] update verifier to work for aggregated proofs
    • [x] change j indexing to start at 0 instead of 1
    • [x] always pass in RNG (never create)
    • [x] store input in statement (instead of just inputCommitment)

    further work (in a later PR - #57 )

    • [x] where to fit errors in the states (if one party's share doesn't parse correctly, or if we have to check whether things were valid)
    • [x] can we do per-party share validity checks?
    • [ ] proof & commitments passed into verifier separately (?)

    NOTE: since we are integrating the IPP, and the IPP requires vectors of length 2^k where k is an integer, we have to choose the number of parties we use accordingly.

    T-api T-optimization 
    opened by cathieyun 11
  • Unify single and aggregate rangeproofs

    Unify single and aggregate rangeproofs

    This removes the AggregatedProof struct entirely and moves its validation logic into the RangeProof struct, which now handles both aggregated and unaggregated proofs. The former RangeProof::verify is now RangeProof::verify_single, a convenience wrapper.

    Closes #74 Closes #75

    PTAL T-api 
    opened by hdevalence 10
  • Optional API for challenge-based R1CS proofs

    Optional API for challenge-based R1CS proofs

    (This is a summary of an issue raised by @hdevalence in an offline discussion.)

    The challenge-based constraints in R1CS API (#222) are pretty novel and not have a formal security proof yet. It makes sense to make the use of those optional with respect to the rest of the R1CS API.

    Proposal

    First, it should be possible for the verifier to ensure that randomization API is not available throughout the hierarchy of gadgets unless it was explicitly turned on. This makes challenge-based circuits an "opt-in" feature.

    The proofs for non-randomized constraints should be compatible with the proofs for randomizable constraints: that is, they could be verified by a less conservative verifier, as well as a conservative one. For this we'd simply need to pad the transcript with dummy zero commitments (A_I2, A_O2, S2). This padding should obviously not affect the correctness of the original R1CS protocol.

    Questions

    1. Do we have different proof types for with randomization and without randomization; or do we use the uniform type with a flag distinguishing the two?
    2. Do we try to save 96 bytes of all-zero second-phase commitments (A_I2, A_O2, S2) for the proofs of non-randomized CS, or just have a uniform proof format?
    3. Do we turn on/off the randomization API dynamically or statically? E.g. is a subtrait of a RandomizableConstraintSystem: ConstraintSystem? Gadgets that do not use randomization could use a more conservative supertrait, but gadgets that need it would use a subtrait.

    WDYT? @hdevalence @cathieyun

    opened by oleganza 9
  • Two-phase low-level variable commitments in R1CS protocol

    Two-phase low-level variable commitments in R1CS protocol

    Addresses #222.

    At this stage, this PR adds notes on how we update the protocol to enable two-phase low-level variable commitments, enabling use of challenges encapsulated inside the gadgets.

    FYI: the previous iteration of this was in PR #196. This PR basically "rebases" the older one on top of the latest code layout and documentation.

    opened by oleganza 9
  • [Question] Support for disjunctive proofs

    [Question] Support for disjunctive proofs

    Is there any support planned (or already available) for disjunctive proofs, or, alternatively, generating a "fake" RangeProof and/or InnerProductProof given the challenge scalars in advance, in support of CDS94 style disjunctive proofs? It's entirely possible that this machinery is already available, in which case I haven't discovered it yet, and I suppose it would be nice to add some more documentation for it.

    Please forgive my ignorance if this question is better suited for the Merlin repository, or if I've made some other error in judgement; I'm not a cryptographer.

    opened by based-a-tron 1
  • error: could not compile `packed_simd_2` due to 3 previous errors

    error: could not compile `packed_simd_2` due to 3 previous errors

    Error report

    I git clone this repo and then run cargo test. And the error information came out.

    $ cargo test
        Updating crates.io index
      Downloaded serde_derive v1.0.147
      Downloaded serde v1.0.147
      Downloaded serde_json v1.0.87
      Downloaded syn v1.0.103
      Downloaded libc v0.2.137
      Downloaded 5 crates (1.1 MB) in 10.09s
    warning: invalid feature `yoloproofs` in required-features of target `r1cs`: `yoloproofs` is not present in [features] section
       Compiling proc-macro2 v1.0.47
       Compiling quote v1.0.21
       Compiling unicode-ident v1.0.5
       Compiling syn v1.0.103
       Compiling autocfg v1.1.0
       Compiling cfg-if v1.0.0
       Compiling libc v0.2.137
       Compiling serde_derive v1.0.147
       Compiling serde v1.0.147
       Compiling typenum v1.15.0
       Compiling crossbeam-utils v0.8.12
       Compiling getrandom v0.1.16
       Compiling memchr v2.5.0
       Compiling unicode-xid v0.2.4
       Compiling libm v0.1.4
       Compiling rayon-core v1.9.3
       Compiling byteorder v1.4.3
       Compiling scopeguard v1.1.0
       Compiling packed_simd_2 v0.3.8
       Compiling serde_json v1.0.87
       Compiling either v1.8.0
       Compiling byte-tools v0.3.1
       Compiling ryu v1.0.11
       Compiling cc v1.0.73
       Compiling unicode-width v0.1.10
       Compiling itoa v1.0.4
       Compiling ppv-lite86 v0.2.16
       Compiling keccak v0.1.2
       Compiling regex-automata v0.1.10
       Compiling plotters-backend v0.3.4
       Compiling thiserror v1.0.37
       Compiling lazy_static v1.4.0
       Compiling same-file v1.0.6
       Compiling subtle v2.4.1
       Compiling bitflags v1.3.2
       Compiling opaque-debug v0.2.3
       Compiling cast v0.3.0
       Compiling itoa v0.4.8
       Compiling half v1.8.2
       Compiling regex-syntax v0.6.27
       Compiling oorandom v11.1.3
       Compiling hex v0.3.2
       Compiling memoffset v0.6.5
       Compiling crossbeam-epoch v0.9.11
       Compiling num-traits v0.2.15
       Compiling rayon v1.5.3
       Compiling block-padding v0.1.5
       Compiling itertools v0.10.5
       Compiling textwrap v0.11.0
       Compiling walkdir v2.3.2
       Compiling plotters-svg v0.3.3
       Compiling clap v2.34.0
       Compiling crossbeam-channel v0.5.6
       Compiling num_cpus v1.13.1
       Compiling atty v0.2.14
       Compiling regex v1.6.0
       Compiling clear_on_drop v0.2.5
       Compiling csv-core v0.1.10
       Compiling generic-array v0.12.4
       Compiling rand_core v0.5.1
       Compiling criterion-plot v0.4.5
       Compiling plotters v0.3.4
       Compiling crossbeam-deque v0.8.2
       Compiling rand_chacha v0.2.2
       Compiling digest v0.8.1
       Compiling block-buffer v0.7.3
    error[E0554]: `#![feature]` may not be used on the stable release channel
     --> /home/tours/.cargo/registry/src/github.com-1ecc6299db9ec823/clear_on_drop-0.2.5/src/lib.rs:2:34
      |
    2 | #![cfg_attr(feature = "nightly", feature(min_specialization))]
      |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    
    For more information about this error, try `rustc --explain E0554`.
    error: could not compile `clear_on_drop` due to previous error
    warning: build failed, waiting for other jobs to finish...
    error[E0554]: `#![feature]` may not be used on the stable release channel
       --> /home/tours/.cargo/registry/src/github.com-1ecc6299db9ec823/packed_simd_2-0.3.8/src/lib.rs:214:1
        |
    214 | / #![feature(
    215 | |     adt_const_params,
    216 | |     repr_simd,
    217 | |     rustc_attrs,
    ...   |
    224 | |     custom_inner_attributes,
    225 | | )]
        | |__^
    
    error[E0554]: `#![feature]` may not be used on the stable release channel
       --> /home/tours/.cargo/registry/src/github.com-1ecc6299db9ec823/packed_simd_2-0.3.8/src/lib.rs:219:5
        |
    219 |     stdsimd,
        |     ^^^^^^^
    
    error[E0554]: `#![feature]` may not be used on the stable release channel
       --> /home/tours/.cargo/registry/src/github.com-1ecc6299db9ec823/packed_simd_2-0.3.8/src/lib.rs:222:5
        |
    222 |     core_intrinsics,
        |     ^^^^^^^^^^^^^^^
    
    error: could not compile `packed_simd_2` due to 3 previous errors
    

    Is there anything I should noticed?

    opened by bo-hub 7
  • Question about

    Question about "Q" in the InnerProductProof

    Context:

    The InnerProductProofs takes a few inputs including g_vec, h_vec, a_vec, b_vec, Q and basically gives a point P and a proof that we know a_vec, b_vec such that

    (g_vec^a_vec) (h_vec^b_vec) Q^<a_vec, b_vec> = P

    My question:

    It seems to me that Q can be any point as long as finding a non trivial discrete log relation between elements of g_vec, h_vec and Q is hard. It particular, I think Q = RISTRETTO_BASEPOINT_POINT (aka self.pc_gens.B) would do. Well, as long as we didn't pick one of the points of g_vec or h_vec to be a known power of RISTRETTO_BASEPOINT_POINT.

    In the range proof, this is how Q is defined:

    // Get a challenge value to combine statements for the IPP let w = self.transcript.challenge_scalar(b"w"); let Q = w * self.pc_gens.B;

    I'm wondering what is the motivation for constructing it with a challenge. Do we need this point to not be predictable?

    opened by valchichelapierre 1
  • notes-rp.md questions/clarification

    notes-rp.md questions/clarification

    I have some questions in understanding the notes-rp.md documentation. Would be great if these questions could be answered or maybe the documentation could be improved.

    Here are the following sections:

    1. Line 77

    https://github.com/dalek-cryptography/bulletproofs/blob/1a10ce1a5b87299014658770346b376a858e7691/docs/notes-rp.md?plain=1#L76-L77 The second half of this sentence is confusing: ", a vector of statements about each entry." What is meant by "about each entry"? "entry" of what?

    2. Line 80

    https://github.com/dalek-cryptography/bulletproofs/blob/1a10ce1a5b87299014658770346b376a858e7691/docs/notes-rp.md?plain=1#L80 There are 3 statements in total (lines 62-64) (and all of them are "statements about vectors" as written two sentences before). So which of the 3 statements are meant by each of the two vector-statements? I guess the last two are meant, but the confusing part is that even after the transformation of adding challenger y to statement 2 and 3 there are still 3 statements. How is this supposed to combine statement 2 and 3 into a single one? What's also a bit confusing is that statement 2 and 3 switch position between line 62-64 and 86-88:

    https://github.com/dalek-cryptography/bulletproofs/blob/1a10ce1a5b87299014658770346b376a858e7691/docs/notes-rp.md?plain=1#L86-L88

    Anyway, after line 88 we still have 3 statements. What have we achieved? Wasn't the idea to get down to 2 statements? And how can adding a random vector "challenger y" combine two statements into one? What's the math/rules behind this?

    3. Linex 93 - 101

    https://github.com/dalek-cryptography/bulletproofs/blob/1a10ce1a5b87299014658770346b376a858e7691/docs/notes-rp.md?plain=1#L93-L94 What is meant by "in the same way"? Previously we added a "challenger vector y" to statement 2 and 3 but still had 3 statements. Now it seems like "challenger scalar z" is added to statement 1 (in square) and to statement 2 but not statement 3 and we add the 3 statements together and end up with one. So it's definitely not "in the same way" and now the 3 statements which were previously separated by a comma are now combined into one statement by plus/addition. It would be helpful to mention the math/rules that allow this transformation. Just a little hint at least for further reading would be great.

    opened by yojoe 0
  • Fix LaTeX rendering in r1cs_proof.

    Fix LaTeX rendering in r1cs_proof.

    There is an issue with the LaTeX rendering here: https://doc-internal.dalek.rs/bulletproofs/notes/r1cs_proof/index.html#variables

    Perhaps other documentation pages are also affected.

    opened by ndcroos 1
Owner
dalek cryptography
Fast, safe, pure-rust elliptic curve cryptography
dalek cryptography
A pure-Rust implementation of group operations on Ristretto and Curve25519

curve25519-dalek A pure-Rust implementation of group operations on Ristretto and Curve25519. curve25519-dalek is a library providing group operations

dalek cryptography 611 Dec 25, 2022
DAPOL+ Proof of Liabilities using Bulletproofs and Sparse Merkle trees

DAPOL+ implementation Implementation of the DAPOL+ protocol introduced in the "Generalized Proof of Liabilities" by Yan Ji and Konstantinos Chalkias A

Mysten Labs 5 Apr 9, 2023
Schnorr VRFs and signatures on the Ristretto group

schnorrkel Schnorrkel implements Schnorr signature on Ristretto compressed Ed25519 points, as well as related protocols like HDKD, MuSig, and a verifi

Web3 Foundation 252 Dec 21, 2022
X25519 elliptic curve Diffie-Hellman key exchange in pure-Rust, using curve25519-dalek.

x25519-dalek A pure-Rust implementation of x25519 elliptic curve Diffie-Hellman key exchange, with curve operations provided by curve25519-dalek. This

dalek cryptography 252 Dec 26, 2022
A (mostly) pure-Rust implementation of various cryptographic algorithms.

Rust-Crypto A (mostly) pure-Rust implementation of various common cryptographic algorithms. Rust-Crypto seeks to create practical, auditable, pure-Rus

null 1.2k Dec 27, 2022
A prototype implementation of the Host Identity Protocol v2 for bare-metal systems, written in pure-rust.

Host Identity Protocol for bare-metal systems, using Rust I've been evaluating TLS replacements in constrained environments for a while now. Embedded

null 31 Dec 12, 2022
An implementation of the FP-Growth algorithm in pure Rust.

fp-growth-rs An implementation of the FP-Growth algorithm in pure Rust, which is inspired by enaeseth/python-fp-growth. Usage Add this to your Cargo.t

JmPotato 13 Dec 20, 2022
A pure-Rust implementation of various threshold secret sharing schemes

Threshold Secret Sharing Efficient pure-Rust library for secret sharing, offering efficient share generation and reconstruction for both traditional S

Snips 137 Dec 29, 2022
Pure Rust implementation of the RNCryptor cryptographic format by Rob Napier

rncryptor Rust Implementation of the RNCryptor spec This library implements the specification for the RNCryptor encrypted file format by Rob Napier. d

null 7 Jun 29, 2022
Pure Rust implementation of the Leighton Micali Signature scheme.

Leighton-Micali Hash-Based Signatures LMS implementation in Rust according to the IETF RFC 8554. This implementation is binary compatible with the ref

Fraunhofer AISEC 6 Jun 2, 2022
In addition to encryption library, pure RUST implementation of SSH-2.0 client protocol

In addition to encryption library, pure RUST implementation of SSH-2.0 client protocol

陈年旧事。 73 Jan 1, 2023
Pure Rust implementation of components of the Secure Shell (SSH) protocol

RustCrypto: SSH Pure Rust implementation of components of the Secure Shell (SSH) protocol. Crates Name crates.io Docs Description ssh—encoding Decoder

Rust Crypto 27 Dec 27, 2022
Usable, easy and safe pure-Rust crypto

orion About Orion is a cryptography library written in pure Rust. It aims to provide easy and usable crypto while trying to minimize the use of unsafe

Johannes 476 Dec 22, 2022
Collection of cryptographic hash functions written in pure Rust

RustCrypto: hashes Collection of cryptographic hash functions written in pure Rust. All algorithms reside in the separate crates and implemented using

Rust Crypto 1.2k Jan 8, 2023
Master Password in Pure Rust

Master Password •••| This is the Rust version of the original found here. This can be used as a drop-in replacement for the reference C version, offer

Rust India 34 Apr 13, 2022
An encrypted multi client messaging system written in pure Rust

?? Preamble This is a pure Rust multi-client encrypted messaging system, also known as Edode's Secured Messaging System. It is an end-to-end(s) commun

Edode 3 Sep 16, 2022
Pure-Rust traits and utilities for constant-time cryptographic implementations.

subtle Pure-Rust traits and utilities for constant-time cryptographic implementations. It consists of a Choice type, and a collection of traits using

dalek cryptography 196 Dec 13, 2022
Collection of block cipher algorithms written in pure Rust

RustCrypto: block ciphers Collection of block ciphers and block modes written in pure Rust. Warnings Currently only the aes crate provides constant-ti

Rust Crypto 506 Jan 3, 2023
Convert private keys to PKCS#8 format in pure Rust

topk8 Convert private keys to PKCS#8 format in pure Rust. The following formats are supported at the moment: PKCS#1 PEM (RSA PRIVATE KEY) SEC1 PEM (EC

kazk 1 Dec 10, 2021