Struct merlin::Transcript [−][src]
pub struct Transcript { /* fields omitted */ }
A transcript of a public-coin argument.
The prover's messages are added to the transcript using commit_bytes
,
and the verifier's challenges can be computed using challenge_bytes
.
Usage
Implementations of proof protocols should take a &mut Transcript
as a parameter, not construct one internally. This provides
three benefits:
-
It forces the API client to initialize their own transcript using
Transcript::new()
. Since that function takes a domain separation string, this ensures that all proofs are domain-separated. -
It ensures that protocols are sequentially composable, by running them on a common transcript. (Since transcript instances are domain-separated, it should not be possible to extract a sub-protocol's challenges and commitments as a standalone proof).
-
It allows API clients to commit contextual data to the proof transcript prior to running the protocol, allowing them to bind proof statements to arbitrary application data.
Defining protocol behaviour with extension traits
This API is byte-oriented, while an actual protocol likely requires typed data — for instance, a protocol probably wants to receive challenge scalars, not challenge bytes. The recommended way to bridge this abstraction gap is to define a protocol-specific extension trait.
For instance, consider a discrete-log based protocol which commits to Ristretto points and requires challenge scalars for the Ristretto group. This protocol can define a protocol-specific extension trait in its crate as follows:
extern crate curve25519_dalek; use curve25519_dalek::ristretto::RistrettoPoint; use curve25519_dalek::ristretto::CompressedRistretto; use curve25519_dalek::scalar::Scalar; extern crate merlin; use merlin::Transcript; trait TranscriptProtocol { fn domain_sep(&mut self); fn commit_point(&mut self, label: &'static [u8], point: &CompressedRistretto); fn challenge_scalar(&mut self, label: &'static [u8]) -> Scalar; } impl TranscriptProtocol for Transcript { fn domain_sep(&mut self) { self.commit_bytes(b"dom-sep", b"TranscriptProtocol Example"); } fn commit_point(&mut self, label: &'static [u8], point: &CompressedRistretto) { self.commit_bytes(label, point.as_bytes()); } fn challenge_scalar(&mut self, label: &'static [u8]) -> Scalar { let mut buf = [0; 64]; self.challenge_bytes(label, &mut buf); Scalar::from_bytes_mod_order_wide(&buf) } } fn example(transcript: &mut Transcript, A: &RistrettoPoint, B: &RistrettoPoint) { // Since the TranscriptProtocol trait is in scope, the extension // methods are available on the `transcript` object: transcript.domain_sep(); transcript.commit_point(b"A", &A.compress()); transcript.commit_point(b"B", &B.compress()); let c = transcript.challenge_scalar(b"c"); // ... }
Now, the implementation of the protocol can use the domain_sep
to add domain seperation to an existing &mut Transcript
, and
then call the commit_point
and challenge_scalar
methods,
rather than calling commit_bytes
and
challenge_bytes
directly.
However, because the protocol-specific behaviour is defined in a
protocol-specific trait, different protocols can use the same
Transcript
instance without imposing any extra type constraints.
Methods
impl Transcript
[src]
impl Transcript
pub fn new(label: &'static [u8]) -> Transcript
[src]
pub fn new(label: &'static [u8]) -> Transcript
Initialize a new transcript with the supplied label
, which
is used as a domain separator.
Note
This function should be called by a protocol's API consumer, and not by the protocol implementation. See above for details.
Implementation
Initializes a STROBE-128 context with a Merlin domain-separator label, then commits the user-supplied label using the STROBE operations
meta-AD( b"dom-sep" || LE32(label.len()) );
AD( label );
pub fn commit_bytes(&mut self, label: &'static [u8], message: &[u8])
[src]
pub fn commit_bytes(&mut self, label: &'static [u8], message: &[u8])
Commit a prover's message
to the transcript.
The label
parameter is metadata about the message, and is
also committed to the transcript.
Implementation
Performs the STROBE operations
meta-AD( label || LE32(message.len()) );
AD( message );
pub fn challenge_bytes(&mut self, label: &'static [u8], dest: &mut [u8])
[src]
pub fn challenge_bytes(&mut self, label: &'static [u8], dest: &mut [u8])
Fill the supplied buffer with the verifier's challenge bytes.
The label
parameter is metadata about the challenge, and is
also committed to the transcript.
Implementation
Performs the STROBE operations
meta-AD( label || LE32(dest.len()) );
dest <- PRF();
pub fn build_rng(&self) -> TranscriptRngBuilder
[src]
pub fn build_rng(&self) -> TranscriptRngBuilder
Fork the current Transcript
to construct an RNG whose output is bound
to the current transcript state as well as prover's secrets.
See the TranscriptRngBuilder
documentation for more details.
Trait Implementations
impl Clone for Transcript
[src]
impl Clone for Transcript
fn clone(&self) -> Transcript
[src]
fn clone(&self) -> Transcript
Returns a copy of the value. Read more
fn clone_from(&mut self, source: &Self)
1.0.0[src]
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read more
Auto Trait Implementations
impl Send for Transcript
impl Send for Transcript
impl Sync for Transcript
impl Sync for Transcript