Spartan: High-speed zkSNARKs without trusted setup

Overview

Spartan: High-speed zkSNARKs without trusted setup

Rust

Spartan is a high-speed zero-knowledge proof system, a cryptographic primitive that enables a prover to prove a mathematical statement to a verifier without revealing anything besides the validity of the statement. This repository provides libspartan, a Rust library that implements a zero-knowledge succinct non-interactive argument of knowledge (zkSNARK), which is a type of zero-knowledge proof system with short proofs and fast verification times. The details of the Spartan proof system are described in our paper published at CRYPTO 2020. The security of the Spartan variant implemented in this library is based on the discrete logarithm problem in the random oracle model.

A simple example application is proving the knowledge of a secret s such that H(s) == d for a public d, where H is a cryptographic hash function (e.g., SHA-256, Keccak). A more complex application is a database-backed cloud service that produces proofs of correct state machine transitions for auditability. See this paper for an overview and this paper for details.

Note that this library has not received a security review or audit.

Highlights

We now highlight Spartan's distinctive features.

  • No "toxic" waste: Spartan is a transparent zkSNARK and does not require a trusted setup. So, it does not involve any trapdoors that must be kept secret or require a multi-party ceremony to produce public parameters.

  • General-purpose: Spartan produces proofs for arbitrary NP statements. libspartan supports NP statements expressed as rank-1 constraint satisfiability (R1CS) instances, a popular language for which there exists efficient transformations and compiler toolchains from high-level programs of interest.

  • Sub-linear verification costs and linear-time proving costs: Spartan is the first transparent proof system with sub-linear verification costs for arbitrary NP statements (e.g., R1CS). Spartan also features a linear-time prover, a property that has remained elusive for nearly all zkSNARKs in the literature.

  • Standardized security: Spartan's security relies on the hardness of computing discrete logarithms (a standard cryptographic assumption) in the random oracle model. libspartan uses ristretto255, a prime-order group abstraction atop curve25519 (a high-speed elliptic curve). We use curve25519-dalek for arithmetic over ristretto255.

  • State-of-the-art performance: Among transparent SNARKs, Spartan offers the fastest prover with speedups of 36–152× depending on the baseline, produces proofs that are shorter by 1.2–416×, and incurs the lowest verification times with speedups of 3.6–1326×. The only exception is proof sizes under Bulletproofs, but Bulletproofs incurs slower verification both asymptotically and concretely. When compared to the state-of-the-art zkSNARK with trusted setup, Spartan’s prover is 2× faster for arbitrary R1CS instances and 16× faster for data-parallel workloads.

Implementation details

libspartan uses merlin to automate the Fiat-Shamir transform. We also introduce a new type called RandomTape that extends a Transcript in merlin to allow the prover's internal methods to produce private randomness using its private transcript without having to create OsRng objects throughout the code. An object of type RandomTape is initialized with a new random seed from OsRng for each proof produced by the library.

Examples

To import libspartan into your Rust project, add the following dependency to Cargo.toml:

spartan = "0.4.1"

The following example shows how to use libspartan to create and verify a SNARK proof. Some of our public APIs' style is inspired by the underlying crates we use.

# extern crate libspartan;
# extern crate merlin;
# use libspartan::{Instance, SNARKGens, SNARK};
# use merlin::Transcript;
# fn main() {
    // specify the size of an R1CS instance
    let num_vars = 1024;
    let num_cons = 1024;
    let num_inputs = 10;
    let num_non_zero_entries = 1024;

    // produce public parameters
    let gens = SNARKGens::new(num_cons, num_vars, num_inputs, num_non_zero_entries);

    // ask the library to produce a synthentic R1CS instance
    let (inst, vars, inputs) = Instance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs);

    // create a commitment to the R1CS instance
    let (comm, decomm) = SNARK::encode(&inst, &gens);

    // produce a proof of satisfiability
    let mut prover_transcript = Transcript::new(b"snark_example");
    let proof = SNARK::prove(&inst, &decomm, vars, &inputs, &gens, &mut prover_transcript);

    // verify the proof of satisfiability
    let mut verifier_transcript = Transcript::new(b"snark_example");
    assert!(proof
      .verify(&comm, &inputs, &mut verifier_transcript, &gens)
      .is_ok());
    println!("proof verification successful!");
# }

Here is another example to use the NIZK variant of the Spartan proof system:

# extern crate libspartan;
# extern crate merlin;
# use libspartan::{Instance, NIZKGens, NIZK};
# use merlin::Transcript;
# fn main() {
    // specify the size of an R1CS instance
    let num_vars = 1024;
    let num_cons = 1024;
    let num_inputs = 10;

    // produce public parameters
    let gens = NIZKGens::new(num_cons, num_vars, num_inputs);

    // ask the library to produce a synthentic R1CS instance
    let (inst, vars, inputs) = Instance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs);

    // produce a proof of satisfiability
    let mut prover_transcript = Transcript::new(b"nizk_example");
    let proof = NIZK::prove(&inst, vars, &inputs, &gens, &mut prover_transcript);

    // verify the proof of satisfiability
    let mut verifier_transcript = Transcript::new(b"nizk_example");
    assert!(proof
      .verify(&inst, &inputs, &mut verifier_transcript, &gens)
      .is_ok());
    println!("proof verification successful!");
# }

Finally, we provide an example that specifies a custom R1CS instance instead of using a synthetic instance

#![allow(non_snake_case)]
# extern crate curve25519_dalek;
# extern crate libspartan;
# extern crate merlin;
# use curve25519_dalek::scalar::Scalar;
# use libspartan::{InputsAssignment, Instance, SNARKGens, VarsAssignment, SNARK};
# use merlin::Transcript;
# use rand::rngs::OsRng;
# fn main() {
  // produce a tiny instance
  let (
    num_cons,
    num_vars,
    num_inputs,
    num_non_zero_entries,
    inst,
    assignment_vars,
    assignment_inputs,
  ) = produce_tiny_r1cs();

  // produce public parameters
  let gens = SNARKGens::new(num_cons, num_vars, num_inputs, num_non_zero_entries);

  // create a commitment to the R1CS instance
  let (comm, decomm) = SNARK::encode(&inst, &gens);

  // produce a proof of satisfiability
  let mut prover_transcript = Transcript::new(b"snark_example");
  let proof = SNARK::prove(
    &inst,
    &decomm,
    assignment_vars,
    &assignment_inputs,
    &gens,
    &mut prover_transcript,
  );

  // verify the proof of satisfiability
  let mut verifier_transcript = Transcript::new(b"snark_example");
  assert!(proof
    .verify(&comm, &assignment_inputs, &mut verifier_transcript, &gens)
    .is_ok());
  println!("proof verification successful!");
# }

# fn produce_tiny_r1cs() -> (
#  usize,
#  usize,
#  usize,
#  usize,
#  Instance,
#  VarsAssignment,
#  InputsAssignment,
# ) {
  // We will use the following example, but one could construct any R1CS instance.
  // Our R1CS instance is three constraints over five variables and two public inputs
  // (Z0 + Z1) * I0 - Z2 = 0
  // (Z0 + I1) * Z2 - Z3 = 0
  // Z4 * 1 - 0 = 0

  // parameters of the R1CS instance rounded to the nearest power of two
  let num_cons = 4;
  let num_vars = 5;
  let num_inputs = 2;
  let num_non_zero_entries = 5;

  // We will encode the above constraints into three matrices, where
  // the coefficients in the matrix are in the little-endian byte order
  let mut A: Vec<(usize, usize, [u8; 32])> = Vec::new();
  let mut B: Vec<(usize, usize, [u8; 32])> = Vec::new();
  let mut C: Vec<(usize, usize, [u8; 32])> = Vec::new();

  // The constraint system is defined over a finite field, which in our case is
  // the scalar field of ristreeto255/curve25519 i.e., p =  2^{252}+27742317777372353535851937790883648493
  // To construct these matrices, we will use `curve25519-dalek` but one can use any other method.

  // a variable that holds a byte representation of 1
  let one = Scalar::one().to_bytes();

  // R1CS is a set of three sparse matrices A B C, where is a row for every 
  // constraint and a column for every entry in z = (vars, 1, inputs)
  // An R1CS instance is satisfiable iff:
  // Az \circ Bz = Cz, where z = (vars, 1, inputs)

  // constraint 0 entries in (A,B,C)
  // constraint 0 is (Z0 + Z1) * I0 - Z2 = 0.
  // We set 1 in matrix A for columns that correspond to Z0 and Z1
  // We set 1 in matrix B for column that corresponds to I0
  // We set 1 in matrix C for column that corresponds to Z2
  A.push((0, 0, one));
  A.push((0, 1, one));
  B.push((0, num_vars + 1, one));
  C.push((0, 2, one));

  // constraint 1 entries in (A,B,C)
  A.push((1, 0, one));
  A.push((1, num_vars + 2, one));
  B.push((1, 2, one));
  C.push((1, 3, one));

  // constraint 3 entries in (A,B,C)
  A.push((2, 4, one));
  B.push((2, num_vars, one));

  let inst = Instance::new(num_cons, num_vars, num_inputs, &A, &B, &C).unwrap();

  // compute a satisfying assignment
  let mut csprng: OsRng = OsRng;
  let i0 = Scalar::random(&mut csprng);
  let i1 = Scalar::random(&mut csprng);
  let z0 = Scalar::random(&mut csprng);
  let z1 = Scalar::random(&mut csprng);
  let z2 = (z0 + z1) * i0; // constraint 0
  let z3 = (z0 + i1) * z2; // constraint 1
  let z4 = Scalar::zero(); //constraint 2

  // create a VarsAssignment
  let mut vars = vec![Scalar::zero().to_bytes(); num_vars];
  vars[0] = z0.to_bytes();
  vars[1] = z1.to_bytes();
  vars[2] = z2.to_bytes();
  vars[3] = z3.to_bytes();
  vars[4] = z4.to_bytes();
  let assignment_vars = VarsAssignment::new(&vars).unwrap();

  // create an InputsAssignment
  let mut inputs = vec![Scalar::zero().to_bytes(); num_inputs];
  inputs[0] = i0.to_bytes();
  inputs[1] = i1.to_bytes();
  let assignment_inputs = InputsAssignment::new(&inputs).unwrap();
  
  // check if the instance we created is satisfiable
  let res = inst.is_sat(&assignment_vars, &assignment_inputs);
  assert_eq!(res.unwrap(), true);

  (
    num_cons,
    num_vars,
    num_inputs,
    num_non_zero_entries,
    inst,
    assignment_vars,
    assignment_inputs,
  )
# }

For more examples, see examples/ directory in this repo.

Building libspartan

Install rustup

Switch to nightly Rust using rustup:

rustup default nightly

Clone the repository:

git clone https://github.com/Microsoft/Spartan
cd Spartan

To build docs for public APIs of libspartan:

cargo doc

To run tests:

RUSTFLAGS="-C target_cpu=native" cargo test

To build libspartan:

RUSTFLAGS="-C target_cpu=native" cargo build --release

NOTE: We enable SIMD instructions in curve25519-dalek by default, so if it fails to build remove the "simd_backend" feature argument in Cargo.toml.

Supported features

  • profile: enables fine-grained profiling information (see below for its use)

Performance

End-to-end benchmarks

libspartan includes two benches: benches/nizk.rs and benches/snark.rs. If you report the performance of Spartan in a research paper, we recommend using these benches for higher accuracy instead of fine-grained profiling (listed below).

To run end-to-end benchmarks:

RUSTFLAGS="-C target_cpu=native" cargo bench

Fine-grained profiling

Build libspartan with profile feature enabled. It creates two profilers: ./target/release/snark and ./target/release/nizk.

These profilers report performance as depicted below (for varying R1CS instance sizes). The reported performance is from running the profilers on a Microsoft Surface Laptop 3 on a single CPU core of Intel Core i7-1065G7 running Ubuntu 20.04 (atop WSL2 on Windows 10). See Section 9 in our paper to see how this compares with other zkSNARKs in the literature.

$ ./target/release/snark 
Profiler:: SNARK
  * number_of_constraints 1048576
  * number_of_variables 1048576
  * number_of_inputs 10
  * number_non-zero_entries_A 1048576
  * number_non-zero_entries_B 1048576
  * number_non-zero_entries_C 1048576
  * SNARK::encode
  * SNARK::encode 14.2644201s
  * SNARK::prove
    * R1CSProof::prove
      * polycommit
      * polycommit 2.7175848s
      * prove_sc_phase_one
      * prove_sc_phase_one 683.7481ms
      * prove_sc_phase_two
      * prove_sc_phase_two 846.1056ms
      * polyeval
      * polyeval 193.4216ms
    * R1CSProof::prove 4.4416193s
    * len_r1cs_sat_proof 47024
    * eval_sparse_polys
    * eval_sparse_polys 377.357ms
    * R1CSEvalProof::prove
      * commit_nondet_witness
      * commit_nondet_witness 14.4507331s
      * build_layered_network
      * build_layered_network 3.4360521s
      * evalproof_layered_network
        * len_product_layer_proof 64712
      * evalproof_layered_network 15.5708066s
    * R1CSEvalProof::prove 34.2930559s
    * len_r1cs_eval_proof 133720
  * SNARK::prove 39.1297568s
  * SNARK::proof_compressed_len 141768
  * SNARK::verify
    * verify_sat_proof
    * verify_sat_proof 20.0828ms
    * verify_eval_proof
      * verify_polyeval_proof
        * verify_prod_proof
        * verify_prod_proof 1.1847ms
        * verify_hash_proof
        * verify_hash_proof 81.06ms
      * verify_polyeval_proof 82.3583ms
    * verify_eval_proof 82.8937ms
  * SNARK::verify 103.0536ms
$ ./target/release/nizk 
Profiler:: NIZK
  * number_of_constraints 1048576
  * number_of_variables 1048576
  * number_of_inputs 10
  * number_non-zero_entries_A 1048576
  * number_non-zero_entries_B 1048576
  * number_non-zero_entries_C 1048576
  * NIZK::prove
    * R1CSProof::prove
      * polycommit
      * polycommit 2.7220635s
      * prove_sc_phase_one
      * prove_sc_phase_one 722.5487ms
      * prove_sc_phase_two
      * prove_sc_phase_two 862.6796ms
      * polyeval
      * polyeval 190.2233ms
    * R1CSProof::prove 4.4982305s
    * len_r1cs_sat_proof 47024
  * NIZK::prove 4.5139888s
  * NIZK::proof_compressed_len 48134
  * NIZK::verify
    * eval_sparse_polys
    * eval_sparse_polys 395.0847ms
    * verify_sat_proof
    * verify_sat_proof 19.286ms
  * NIZK::verify 414.5102ms

LICENSE

See LICENSE

Contributing

See CONTRIBUTING

Comments
  • The `num_nz_entries` should be more generic

    The `num_nz_entries` should be more generic

    Hi, the num_nz_entries is fixed to be equal to num_cons, and there's some assertion in the commit and prove schedule,as:

    assert_eq!(gens_n.n, self.len());
    

    But actually, though it's sparse, the non zero entries can be more than the constraint number, e.g., Vitalik Buterin's blog Quardratic Arithmetic Programs: from Zero to Hero. I think it would be better to make it more generic?

        //let max_nz_entries = num_cons;
        let max_nz_entries = ((num_cons * (num_vars + num_inputs + 1))as usize).next_power_of_two(); //make it more generic, for one constraint for A should have more than 1 zeros.
    
    opened by 3for 7
  • Arbitrary number of variables and contraints

    Arbitrary number of variables and contraints

    This commit makes adding an arbitrary number of variables and constraints possible. This eliminates the assertions on number of constraints and number of variables imposed on user input.

    1. When creating a new R1CS Instance throught the public interface, it is required # constraints and # of vars be a power of 2. I remove that requirement by padding with dummy constraints and vars until the nearest power of 2.
    2. The sumcheck protocol in src/sumcheck.rs does not work for 1 constraint, even though 1 is a power of 2. I have to pad to a minimum of two constraints.
    3. Added a test in src/lib.rs called test_padded_constraints.
    opened by elefthei 6
  • Add example proving knowledge of cubic equation solution

    Add example proving knowledge of cubic equation solution

    The example of knowing a solution to the cubic equation of x^3 + x + 5 = y is effectively the first thing you come across when dissecting the zkSNARKs knowledge if your background is in blockchain. This is probably thanks to Vitalik who decomposes the problem into the primitives in his blog post here.

    This commit adds this as a working example to Spartan repo.

    opened by kubkon 6
  • Cleaner Error handling + Refactor to idiomatic Result/Option patterns

    Cleaner Error handling + Refactor to idiomatic Result/Option patterns

    This:

    • introduces a small thiserror-powered enum to improve ProofVerifyError's messages,
    • refactors point decompression errors into a variant of that enum, thereby suppressing the panics which occur when decompresison fails.
    • folds other panics into the Error cases of their enclosing Result return
    opened by huitseeker 5
  • Compatibility with circom

    Compatibility with circom

    Circom is a project founded by iden3 and can be used to define custom circuits. The circom library outputs an r1cs file which I wish to use with libspartan. However, I have a hard time porting the r1cs format outputted by circom to spartan. The circom r1cs format is defined here - https://github.com/iden3/r1csfile/blob/master/doc/r1cs_bin_format.md

    opened by m0bi5 4
  • Some minor tweaks

    Some minor tweaks

    A few other questions/comments:

    • Is the PC scheme Hydrax-PC? I think it would be good to mention it explicitly.

    • Have you thought about using VartimeEdwardsPrecomputation for commitments? I think most users would be happy with that tradeoff (faster proofs, slower precomputation, a bit more memory), though maybe not 100%.

    opened by dlubarov 4
  • How to use externally generated R1CS?

    How to use externally generated R1CS?

    I'm looking to use Spartan as a backend. The README states the following:

    libspartan supports NP statements expressed as rank-1 constraint satisfiability (R1CS) instances, a popular language for which there exists efficient transformations and compiler toolchains from high-level programs of interest.

    But how do you use this library with R1CS constraints as generated by such toolchains?

    opened by Tails 3
  • How Do I Construct R1CS Using Negative Values?

    How Do I Construct R1CS Using Negative Values?

    Hi,

    I am looking to construct a R1CS but need some help. I would like to know how I can use a negative value for the R1CS like it says in this blog post. They use x2 - 4 but i do not know how to make an R1CS Circuit with negative numbers.

    I would really appreciate some help with a few other things too.

    Thank you.

    opened by AtropineTears 2
  • Differences between Spartan and ZkSTARKs

    Differences between Spartan and ZkSTARKs

    Since ZkSTARKS is also transparent and does not require a trusted setup, a documentation outlining Spartan works in general and how it's different from the first can be really helpful for users.

    opened by jochasinga 2
  • Adapter for ZKInterface

    Adapter for ZKInterface

    A nice interface layer has been developed that loosely connects R1CS frontends with backends. It would be great if Spartan would have an adapter to plug into ZKInterface, so circuits could easily be defined in a frontend tool, such as ZoKrates or others.

    https://medium.com/@gokulbabyalex/zkinterface-an-emerging-standard-for-zero-knowledge-frameworks-93e02bcd664d

    https://github.com/QED-it/zkinterface

    opened by Tails 2
  • Make releases from time to time

    Make releases from time to time

    Some people (like me) watch the repo using "Releases only" would be cool to make release from time to time.

    If you need to I can try to make the mechanism of releasing.

    opened by TomaszWaszczyk 2
  • Where to find the example of proof H(s)==d?

    Where to find the example of proof H(s)==d?

    Thanks for the great job you have done. In the README, it is said that there is an example of proofing H(s)==d, but it is not in the examples folder. Where can I find it?

    Thank you again.

    James

    opened by jamesdang 0
  • Post-quantum variant of Spartan

    Post-quantum variant of Spartan

    In the paper there is a post quantum variant of Spartan called Spartan_RO. Is there an implementation of this somewhere? If not, how difficult is it to introduce it?

    opened by kc1212 0
  • [E0061]  in readme.md    Examples   produce a proof of satisfiability

    [E0061] in readme.md Examples produce a proof of satisfiability

    // produce a proof of satisfiability
    let proof = SNARK::prove(&inst, &comm, &decomm, vars, &inputs, &gens, &mut prover_transcript);
    

    This function takes 6 parameters but 7 parameters were supplied [E0061]

    ===>

    let proof = SNARK::prove(&inst, &decomm, vars, &inputs, &gens, &mut prover_transcript);
    
      /// A method to produce a SNARK proof of the satisfiability of an R1CS instance
      pub fn prove(
        inst: &Instance,
        decomm: &ComputationDecommitment,
        vars: VarsAssignment,
        inputs: &InputsAssignment,
        gens: &SNARKGens,
        transcript: &mut Transcript,
      ) -> Self {}
    
    opened by HLRJ 1
  • Add More Examples

    Add More Examples

    I really would like if you added more examples of what you can do with Spartan. For instance, proving knowledge of a preimage of a hash with Poseidon.

    This would be really helpful!

    opened by AtropineTears 2
  • Add another challenge in dotproduct proof?

    Add another challenge in dotproduct proof?

    opened by 3for 2
Releases(v0.4.1)
Owner
Microsoft
Open source projects and samples from Microsoft
Microsoft
A toolbox for zkSNARKs on Ethereum

ZoKrates ZoKrates is a toolbox for zkSNARKs on Ethereum. This is a proof-of-concept implementation. It has not been tested for production. Getting Sta

ZoKrates 1.5k Jan 5, 2023
An experimental rust zksnarks compiler with embeeded bellman-bn128 prover

Za! An experimental port of the circom zk-SNARK compiler in Rust with embedded bellman-bn128 prover. I created it as a PoC port of the existing JavaSc

adria0.eth 39 Aug 26, 2022
Diem’s mission is to build a trusted and innovative financial network that empowers people and businesses around the world.

Note to readers: On December 1, 2020, the Libra Association was renamed to Diem Association. The project repos are in the process of being migrated. A

Diem 16.7k Jan 9, 2023
Enigma Core library. The domain: Trusted and Untrusted App in Rust.

Enigma Core library Service Master Develop CI Badge Pure Rust Enclave && Untrusted in Rust. Core is part of the Enigma node software stack. The Core c

SCRT Labs 89 Sep 14, 2022
Confidential credit scores and loan disbursal, powered by zkSNARKs and NEAR Protocol

zkLoans zkLoans brings confidential Credit Scores. It proves to a counterparty if you meet threshold requirements for a credit score without revealing

Anirudha Bose 2 Sep 13, 2022
Spartan2: High-speed zero-knowledge SNARKs.

Spartan2: High-speed zero-knowledge SNARKs. Spartan is a high-speed zkSNARK, where a zkSNARK is type cryptographic proof system that enables a prover

Microsoft 7 Jul 28, 2023
This is my home environment setup for monitoring temperature and humidity

Home EnViroNment Motivation This is my IoT temperature and humidity monitoring solution for where i live. I found it cheaper to go buy sensors and hoo

Fredrik 1 Jan 5, 2022
Consensus layer peer-to-peer connection setup

Consensus Layer P2P This project is a basic setup for a consensus layer peer-to-peer connection, as specified in the consensus layer specifications of

Brechy 11 Dec 31, 2022
Easy setup for Edge host.

Pod's Edge Staking GUI (beta) Features Easily setup your Edge host with a GUI (Graphical User Interface). Uses the device token staking method. Has no

null 3 Apr 29, 2023
reth-indexer reads directly from the reth db and indexes the data into a postgres database all decoded with a simple config file and no extra setup alongside exposing a API ready to query the data.

reth-indexer reth-indexer reads directly from the reth db and indexes the data into a postgres database all decoded with a simple config file and no e

Josh Stevens 306 Jul 12, 2023
Modern, lightweight & standard-compliant bitcoin wallet runtime & cli without rust-bitcoin dependencies

Bitcoin protocol command-line wallet & tools Modern, minimalistic & standard-compliant cold wallet from LNP/BP Standards Association. Contributing Con

BP: Bitcoin protocol 3 Jul 31, 2023
A Minimalistic Rust library to extract all potential function selectors from EVM bytecode without source code.

EVM Hound A Minimalistic Rust library to extract all potential function selectors from EVM bytecode without source code. Installation $ cargo add evm_

null 34 Dec 3, 2023
a Solana program for granting friends permissions on your account without revealing your private key.

Delegatooooor Granting Permission: An account holder (the delegator) decides to grant permission to a delegate. They create and sign a transaction tha

0xGhostMac 3 Apr 3, 2024
A high performance blockchain kernel for enterprise users.

English | 简体中文 What is CITA CITA is a fast and scalable blockchain kernel for enterprises. CITA supports both native contract and EVM contract, by whi

CITAHub 1.3k Dec 22, 2022
An extremely high performance matching engine written in Rust.

Galois Introduction Galois is an extremely high performance matching engine written in Rust, typically used for the crypto currency exchange service.

UINB Tech 66 Jan 7, 2023
High Performance Blockchain Deserializer

bitcoin-explorer bitcoin_explorer is an efficient library for reading bitcoin-core binary blockchain file as a database (utilising multi-threading). D

Congyu 18 Dec 22, 2022
Authenticated Encryption with Associated Data Algorithms: high-level encryption ciphers

RustCrypto: Authenticated Encryption with Associated Data (AEAD) Algorithms Collection of Authenticated Encryption with Associated Data (AEAD) algorit

Rust Crypto 457 Jan 4, 2023
AMCOS - A high-peformance parallel monte-carlo simulation for estimating the fair value of options in finance

antoons-monte-carlo-options-sim A high-peformance parallel monte-carlo simulation for estimating the fair value of options in finance. Written in Rust

null 4 Jun 18, 2022
An easy-to-use, high-performance Interledger implementation written in Rust

Interledger implementation in Rust ?? Requirements All crates require Rust 2018 edition and are tested on the following channels: stable Connecting to

Interledger.rs 184 Dec 13, 2022