hotshot_types/traits/qc.rs
1// Copyright (c) 2021-2024 Espresso Systems (espressosys.com)
2// This file is part of the HotShot repository.
3
4// You should have received a copy of the MIT License
5// along with the HotShot repository. If not, see <https://mit-license.org/>.
6
7//! The quorum certificate (QC) trait is a certificate of a sufficient quorum of distinct
8//! parties voted for a message or statement.
9
10use ark_std::{
11 rand::{CryptoRng, RngCore},
12 vec::Vec,
13};
14use bitvec::prelude::*;
15use digest::generic_array::{ArrayLength, GenericArray};
16use jf_signature::{AggregateableSignatureSchemes, SignatureError};
17
18/// Trait for validating a QC built from different signatures on the same message
19pub trait QuorumCertificateScheme<A: AggregateableSignatureSchemes> {
20 /// Public parameters for generating the QC
21 /// E.g: snark proving/verifying keys, list of (or pointer to) public keys stored in the smart contract.
22 type QcProverParams<'a>;
23
24 /// Public parameters for validating the QC
25 /// E.g: verifying keys, stake table commitment
26 type QcVerifierParams<'a>;
27
28 /// Allows to fix the size of the message at compilation time.
29 type MessageLength: ArrayLength<A::MessageUnit>;
30
31 /// Type of the actual quorum certificate object
32 type Qc;
33
34 /// Type of the quorum size (e.g. number of votes or accumulated weight of signatures)
35 type QuorumSize;
36
37 /// Produces a partial signature on a message with a single user signing key
38 /// NOTE: the original message (vote) should be prefixed with the hash of the stake table.
39 /// * `agg_sig_pp` - public parameters for aggregate signature
40 /// * `message` - message to be signed
41 /// * `sk` - user signing key
42 /// * `returns` - a "simple" signature
43 ///
44 /// # Errors
45 ///
46 /// Should return error if the underlying signature scheme fail to sign.
47 fn sign<R: CryptoRng + RngCore, M: AsRef<[A::MessageUnit]>>(
48 pp: &A::PublicParameter,
49 sk: &A::SigningKey,
50 msg: M,
51 prng: &mut R,
52 ) -> Result<A::Signature, SignatureError> {
53 A::sign(pp, sk, msg, prng)
54 }
55
56 /// Computes an aggregated signature from a set of partial signatures and the verification keys involved
57 /// * `qc_pp` - public parameters for generating the QC
58 /// * `signers` - a bool vector indicating the list of verification keys corresponding to the set of partial signatures
59 /// * `sigs` - partial signatures on the same message
60 ///
61 /// # Errors
62 ///
63 /// Will return error if some of the partial signatures provided are invalid or the number of
64 /// partial signatures / verifications keys are different.
65 fn assemble(
66 qc_pp: &Self::QcProverParams<'_>,
67 signers: &BitSlice,
68 sigs: &[A::Signature],
69 ) -> Result<Self::Qc, SignatureError>;
70
71 /// Checks an aggregated signature over some message provided as input
72 /// * `qc_vp` - public parameters for validating the QC
73 /// * `message` - message to check the aggregated signature against
74 /// * `qc` - quorum certificate
75 /// * `returns` - the quorum size if the qc is valid, an error otherwise.
76 ///
77 /// # Errors
78 ///
79 /// Return error if the QC is invalid, either because accumulated weight didn't exceed threshold,
80 /// or some partial signatures are invalid.
81 fn check(
82 qc_vp: &Self::QcVerifierParams<'_>,
83 message: &GenericArray<A::MessageUnit, Self::MessageLength>,
84 qc: &Self::Qc,
85 ) -> Result<Self::QuorumSize, SignatureError>;
86
87 /// Trace the list of signers given a qc.
88 ///
89 /// # Errors
90 ///
91 /// Return error if the inputs mismatch (e.g. wrong verifier parameter or original message).
92 fn trace(
93 qc_vp: &Self::QcVerifierParams<'_>,
94 message: &GenericArray<A::MessageUnit, Self::MessageLength>,
95 qc: &Self::Qc,
96 ) -> Result<Vec<A::VerificationKey>, SignatureError>;
97}