Skip to content

Commit

Permalink
Move most crate docs to readme
Browse files Browse the repository at this point in the history
  • Loading branch information
cargodog committed Sep 16, 2020
1 parent 910dcb1 commit d66e4a6
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 86 deletions.
85 changes: 82 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,89 @@
# Arcturus
A pure Rust implementation of [Arcturus](https://eprint.iacr.org/2020/312) zero-knowledge proofs.
# arcturus

A pure Rust, light-weight, and performant implementation of the Arcturus zero-knowledge
proof system [[link][arcturus-paper]].

Arcturus enables efficient proof and verification of confidential transactions with very large
anonymity sets. A correct proof provides the following guarantees:
1) The signer posesses the signing key for each spent output in the ring.
1) The sum of spent inputs matches the sum of newly minted outputs.<sup>[1](#notes)</sup>
1) Each spent input is accompanied with a unique, deterministic, linking tag to detect double
spends.<sup>[2](#notes)</sup>
1) The transaction input and output values are hidden (aka confidential).
1) The transaction inputs and signing keys are hidden in a large anonymity set.<sup>[3](#notes)</sup>

## ⚠️ Security Warning
This crate is a work in progress and has not been independently audited!

USE AT YOUR OWN RISK!

## Documentation
Detailed documentation can be found [here](https://docs.rs/arcturus).
Detailed documentation can be found [here][docs-external].

# Example:
```rust
use arcturus::*;
use curve25519_dalek::ristretto::RistrettoPoint;
use curve25519_dalek::scalar::Scalar;
use merlin::Transcript;
use rand::rngs::OsRng; // You should use a more secure RNG

// Set up proof generators for 5 bit binary proofs with up to 2 spends in a proof.
let gens = ArcturusGens::new(2, 5, 2).unwrap();

// Given a ring of UTXOs, assume the signer controls outputs at indices 13 & 14 (signer knows spend
// key, amount, and blinding factor for each of his inputs) and wishes to spend those inputs in a
// transaction which mints a new output whose value balances against the inputs:
let ring: Vec<Arcturus::Output> = ...;

// Indices of UTXOs to spend as transaction inputs
let idxs = vec![13, 14];

// Secret data to spend each input UTXO
let spends = vec![ // Secret data to spend each input UTXO
SpendSecret::new(spend_key_13, spend_amt_13, spend_blind_13),
SpendSecret::new(spend_key_14, spend_amt_14, spend_blind_14)
];

// Secret data for new minted outputs (Total mint ammounts must balance total input ammounts).
let mints = vec![MintSecret::new(mint_pubkey, mint_amt, mint_blind)];

// Signer computes the transaction proof
let mut t = Transcript::new(b"Test proof");
let proof = gens.prove(&mut t, &ring[..], &idxs[..], &spends[..], &mints[..]).unwrap();

// The verifier my verify the proof as follows:
let mut t = Transcript::new(b"Test proof");
let proofs = vec![proof];
assert!(gens.verify(&mut t, &ring[..], &proofs[..]).is_ok());
```

# Performance
Benchmarks are run using [criterion.rs][criterion-crate].
```sh
export RUSTFLAGS="-C target_cpu=native"
cargo bench
```

# Contributing
Please see [CONTRIBUTING.md][contributing].

# Notes
Note 1: This library does not include range proofs. To ensure no input or output value is
negative, each input and output commitment should be accompanied with a range proof, such as
[bulletproofs][bulletproofs-crate]. Failure to prevent negative inputs or outputs
could allow an attacker to create new coins (e.g. inflation bug).

Note 2: To prevent double spends, each input's linking tag should be checke for uniqueness and
recorded in a list of spent outputs. If a tag is ever seen twice, this means that the
corresponding input has already been spent.

Note 3: This library leaves selection of the anonymity set up to the user. Selecting a good
ring of UTXOs is essential to providing anonymity for the signer and his transaction inputs.


[arcturus-paper]: https://eprint.iacr.org/2020/312
[docs-external]: https://docs.rs/arcturus
[bulletproofs-crate]: https://crates.io/crates/bulletproofs
[criterion-crate]: https://crates.io/crates/criterion
[contributing]: https://github.com/cargodog/arcturus/blob/master/CONTRIBUTING.md
83 changes: 0 additions & 83 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,88 +1,5 @@
//! A light-weight and performant implementation of the Arcturus zero-knowledge proof system
//! [[link](https://eprint.iacr.org/2020/312)].
//!
//! Arcturus enables efficient proof and verification of confidential transactions with very large
//! anonymity sets. A correct proof provides the following guarantees:
//! 1) The signer posesses the signing key for each spent output in the ring.
//! 1) The sum of spent inputs matches the sum of newly minted outputs.<sup>[1](#notes)</sup>
//! 1) Each spent input is accompanied with a unique, deterministic, linking tag to detect double
//! spends.<sup>[2](#notes)</sup>
//! 1) The transaction input and output values are hidden (aka confidential).
//! 1) The transaction inputs and signing keys are hidden in a large anonymity set.<sup>[3](#notes)</sup>
//!
//! # Example:
//! ```
//! use arcturus::*;
//! use curve25519_dalek::ristretto::RistrettoPoint;
//! use curve25519_dalek::scalar::Scalar;
//! use merlin::Transcript;
//! use rand::rngs::OsRng; // You should use a more secure RNG
//! # use std::iter;
//!
//! // Set up proof generators for 5 bit binary proofs with up to 2 spends in a proof.
//! let gens = ArcturusGens::new(2, 5, 2).unwrap();
//!
//! // Given a ring of UTXOs, assume the signer controls outputs at indices 13 & 14, with the
//! // following spend keys, amounts, and blinding factors:
//! let spend_key_13 = Scalar::random(&mut OsRng);
//! let spend_amt_13 = 100;
//! let spend_blind_13 = Scalar::random(&mut OsRng);
//! let spend_key_14 = Scalar::random(&mut OsRng);
//! let spend_amt_14 = 200;
//! let spend_blind_14 = Scalar::random(&mut OsRng);
//!
//! // Assume the spender wishes to mint the following output, which balance against the spent
//! // inputs:
//! let mint_pubkey = RistrettoPoint::random(&mut OsRng);
//! let mint_amt = 300;
//! let mint_blind = Scalar::random(&mut OsRng);
//!
//! // Compute the spend proof as follows:
//! let idxs = vec![13, 14];
//! let spends = vec![
//! SpendSecret::new(spend_key_13, spend_amt_13, spend_blind_13),
//! SpendSecret::new(spend_key_14, spend_amt_14, spend_blind_14)
//! ];
//! let mints = vec![MintSecret::new(mint_pubkey, mint_amt, mint_blind)];
//! # let mut ring = iter::repeat_with(|| {
//! # Output::new(RistrettoPoint::random(&mut OsRng), RistrettoPoint::random(&mut OsRng))
//! # })
//! # .take(gens.ring_size())
//! # .collect::<Vec<_>>();
//! # ring[13] = spends[0].to_output();
//! # ring[14] = spends[1].to_output();
//! #
//! let mut t = Transcript::new(b"Test proof");
//! let proof = gens.prove(&mut t, &ring[..], &idxs[..], &spends[..], &mints[..]).unwrap();
//!
//! // The verifier my verify the proof as follows:
//! let mut t = Transcript::new(b"Test proof");
//! let proofs = vec![proof];
//! assert!(gens.verify(&mut t, &ring[..], &proofs[..]).is_ok());
//! ```
//!
//! # Performance
//! Benchmarks are run using [criterion.rs](https://github.com/japaric/criterion.rs):
//! ```
//! export RUSTFLAGS="-C target_cpu=native"
//! cargo bench
//! ```
//!
//! # Contributing
//! Please see [CONTRIBUTING.md](https://github.com/cargodog/arcturus/blob/master/CONTRIBUTING.md).
//!
//! # Notes
//! Note 1: This library does not include range proofs. To ensure no input or output value is
//! negative, each input and output commitment should be accompanied with a range proof, such as
//! [bulletproofs](https://docs.rs/bulletproofs). Failure to prevent negative inputs or outputs
//! could allow an attacker to create new coins (e.g. inflation bug).
//!
//! Note 2: To prevent double spends, each input's linking tag should be checke for uniqueness and
//! recorded in a list of spent outputs. If a tag is ever seen twice, this means that the
//! corresponding input has already been spent.
//!
//! Note 3: This library leaves selection of the anonymity set up to the user. Selecting a good
//! ring of UTXOs is essential to providing anonymity for the signer and his transaction inputs.
#![no_std]
#![feature(test)]
Expand Down

0 comments on commit d66e4a6

Please sign in to comment.