elastic_elgamal/proofs/
mod.rs1use core::fmt;
4
5use merlin::Transcript;
6
7use crate::{
8 alloc::vec,
9 group::{Group, RandomBytesProvider},
10};
11
12mod commitment;
13mod log_equality;
14mod mul;
15mod possession;
16mod range;
17mod ring;
18
19pub use self::{
20 commitment::CommitmentEquivalenceProof,
21 log_equality::LogEqualityProof,
22 mul::SumOfSquaresProof,
23 possession::ProofOfPossession,
24 range::{PreparedRange, RangeDecomposition, RangeProof},
25 ring::{RingProof, RingProofBuilder},
26};
27
28pub(crate) trait TranscriptForGroup {
30 fn start_proof(&mut self, proof_label: &'static [u8]);
31
32 fn append_element_bytes(&mut self, label: &'static [u8], element_bytes: &[u8]);
33
34 fn append_element<G: Group>(&mut self, label: &'static [u8], element: &G::Element);
35
36 fn challenge_scalar<G: Group>(&mut self, label: &'static [u8]) -> G::Scalar;
37}
38
39impl TranscriptForGroup for Transcript {
40 fn start_proof(&mut self, proof_label: &'static [u8]) {
41 self.append_message(b"dom-sep", proof_label);
42 }
43
44 fn append_element_bytes(&mut self, label: &'static [u8], element_bytes: &[u8]) {
45 self.append_message(label, element_bytes);
46 }
47
48 fn append_element<G: Group>(&mut self, label: &'static [u8], element: &G::Element) {
49 let mut output = vec![0_u8; G::ELEMENT_SIZE];
50 G::serialize_element(element, &mut output);
51 self.append_element_bytes(label, &output);
52 }
53
54 fn challenge_scalar<G: Group>(&mut self, label: &'static [u8]) -> G::Scalar {
55 G::scalar_from_random_bytes(RandomBytesProvider::new(self, label))
56 }
57}
58
59#[derive(Debug)]
62#[non_exhaustive]
63pub enum VerificationError {
64 ChallengeMismatch,
69 LenMismatch {
74 collection: &'static str,
76 expected: usize,
78 actual: usize,
80 },
81}
82
83impl VerificationError {
84 pub(crate) fn check_lengths(
85 collection: &'static str,
86 expected: usize,
87 actual: usize,
88 ) -> Result<(), Self> {
89 if expected == actual {
90 Ok(())
91 } else {
92 Err(Self::LenMismatch {
93 collection,
94 expected,
95 actual,
96 })
97 }
98 }
99}
100
101impl fmt::Display for VerificationError {
102 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
103 match self {
104 Self::ChallengeMismatch => formatter.write_str(
105 "restored challenge scalar does not match the one provided in the proof",
106 ),
107
108 Self::LenMismatch {
109 collection,
110 expected,
111 actual,
112 } => write!(
113 formatter,
114 "number of {collection} ({actual}) differs from expected ({expected})",
115 ),
116 }
117 }
118}
119
120#[cfg(feature = "std")]
121impl std::error::Error for VerificationError {}