1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// Copyright (c) 2024, The Tari Project
// SPDX-License-Identifier: BSD-3-Clause
//! An experimental Rust implementation of the Triptych zero-knowledge proving system.
//!
//! # Overview
//!
//! [Triptych](https://eprint.iacr.org/2020/018) is a zero-knowledge proving system designed to function as a linkable ring signature.
//! This is a construction that allows a signer to sign a message against a set of arbitrary verification keys.
//! Successful verification of a signature means that the signer knew the signing key corresponding to one of the
//! verification keys, but does not reveal which. It also produces a linking tag; if any two verified signatures have
//! the same linking tag, they were produced using the same signing key. However, it is not possible to determine the
//! signing key associated to a linking tag, nor the corresponding verification key.
//!
//! Triptych proofs scale nicely, with their size increasingly only logarithmically with the size of the verification
//! key set. Proofs sharing the same verification key set can also be verified efficiently in batches to save time.
//!
//! More formally, let `G` and `U` be fixed independent generators of the Ristretto group.
//! Let `N = n**m`, where `n, m > 1` are fixed parameters.
//! The Triptych proving system protocol is a sigma protocol for the following relation, where `M` is an `N`-vector of
//! group elements:
//!
//! `{ M, J ; (l, r) : M[l] = r*G, r*J = U }`
//!
//! It's possible to use the Fiat-Shamir transformation to produce a non-interactive protocol that can additionally bind
//! an arbitrary message into the transcript. This produces the linkable ring signature.
//!
//! This library also supports [parallel proving functionality](`crate::parallel`).
//!
//! # Implementation notes
//!
//! This implementation makes several opinionated choices:
//! - It uses [Ristretto](https://ristretto.group/) for group operations.
//! - It uses [Merlin](https://merlin.cool/) for Fiat-Shamir transcript operations.
//! - It uses [BLAKE3](https://github.com/BLAKE3-team/BLAKE3) for other cryptographic hashing operations.
//!
//! The implementation keeps dependencies to a minimum, and is `no_std` friendly.
//!
//! There are several features that are enabled by default:
//! - `rand`: adds additional prover functionality that supplies a cryptographically-secure random number generator
//! - `serde`: adds proof serialization and deserialization via `serde`
//! - `std`: adds corresponding dependency features
//!
//! The underlying [curve library](https://crates.io/crates/curve25519-dalek) chooses an arithmetic backend based on CPU feature detection.
//! Using a nightly compiler broadens the backend set, and may provide better performance.
//! You can examine performance using the benchmarks: either `cargo bench` or `cargo +nightly bench`.
//!
//! Proofs support a custom serialization format designed to be efficient and canonical.
//! This functionality has an associated fuzzer that can be run using a nightly compiler: `cargo +nightly fuzz run
//! proofs`.
//!
//! # Warning
//!
//! While this implementation is written with security in mind, it is currently **experimental** and not suitable for
//! production use.
//!
//! # Example
//!
//! Here's a complete example of how to generate and verify a Triptych proof; see the documentation for additional
//! functionality.
//!
//! ```
//! # #[cfg(feature = "rand")]
//! # {
//! # extern crate alloc;
//! use alloc::sync::Arc;
//!
//! use curve25519_dalek::RistrettoPoint;
//! use rand_core::OsRng;
//! use triptych::*;
//!
//! let mut rng = OsRng;
//!
//! // Generate parameters
//! // This is `Arc`-wrapped to facilitate efficient reuse!
//! const n: u32 = 2;
//! const m: u32 = 3;
//! let params = Arc::new(TriptychParameters::new(n, m).unwrap());
//!
//! // Generate a random witness, which includes the signing key and an index where it will appear
//! let witness = TriptychWitness::random(¶ms, &mut rng);
//!
//! // Generate an input set of random verification keys, placing ours at the chosen index
//! // This is `Arc`-wrapped to facilitate efficient reuse!
//! let M = (0..params.get_N())
//! .map(|i| {
//! if i == witness.get_l() {
//! witness.compute_verification_key()
//! } else {
//! RistrettoPoint::random(&mut rng)
//! }
//! })
//! .collect::<Vec<RistrettoPoint>>();
//! let input_set = Arc::new(TriptychInputSet::new(&M).unwrap());
//!
//! // Generate the statement, which includes the verification key vector and linking tag
//! let J = witness.compute_linking_tag();
//! let statement = TriptychStatement::new(¶ms, &input_set, &J).unwrap();
//!
//! // Generate a transcript
//! let mut transcript = Transcript::new(b"Test transcript");
//!
//! // Generate a proof from the witness
//! let proof = TriptychProof::prove(&witness, &statement, &mut transcript.clone()).unwrap();
//!
//! // The proof should verify against the same statement and transcript
//! assert!(proof.verify(&statement, &mut transcript).is_ok());
//! # }
//! ```
extern crate alloc;
pub use Transcript;
pub const TRANSCRIPT_HASH_BYTES: usize = 32;
/// Iterated arbitrary-base Gray code functionaity.
pub
/// Public parameters used for generating and verifying Triptych proofs.
pub use TriptychParameters;
/// Triptych proofs.
pub use TriptychProof;
/// Triptych proof statements.
pub use ;
/// Triptych proof transcripts.
pub
/// Various utility functionality.
pub
/// Triptych proof witnesses.
pub use TriptychWitness;
/// Parallel Triptych functionality.