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
pub mod private_input;
pub mod prover;
pub mod verifier;
mod challenge;
mod dlog_protocol;
mod fiat_shamir;
mod sig_serializer;
mod unchecked_tree;
mod unproven_tree;
use ergotree_ir::sigma_protocol::sigma_boolean::SigmaBoolean;
use k256::Scalar;
use dlog_protocol::FirstDlogProverMessage;
use std::convert::TryInto;
use unchecked_tree::{UncheckedSigmaTree, UncheckedTree};
use unproven_tree::{UnprovenLeaf, UnprovenSchnorr, UnprovenTree};
use self::challenge::Challenge;
pub trait ProverMessage {
fn bytes(&self) -> Vec<u8>;
}
pub enum FirstProverMessage {
FirstDlogProverMessage(FirstDlogProverMessage),
FirstDhtProverMessage,
}
impl ProverMessage for FirstProverMessage {
fn bytes(&self) -> Vec<u8> {
match self {
FirstProverMessage::FirstDlogProverMessage(fdpm) => fdpm.bytes(),
FirstProverMessage::FirstDhtProverMessage => todo!(),
}
}
}
pub enum ProofTree {
UncheckedTree(UncheckedTree),
UnprovenTree(UnprovenTree),
}
impl ProofTree {
pub fn with_challenge(&self, challenge: Challenge) -> ProofTree {
match self {
ProofTree::UncheckedTree(_) => todo!(),
ProofTree::UnprovenTree(ut) => match ut {
UnprovenTree::UnprovenLeaf(ul) => match ul {
UnprovenLeaf::UnprovenSchnorr(us) => ProofTree::UnprovenTree(
UnprovenSchnorr {
challenge_opt: Some(challenge),
..us.clone()
}
.into(),
),
},
},
}
}
}
impl<T: Into<UncheckedTree>> From<T> for ProofTree {
fn from(t: T) -> Self {
ProofTree::UncheckedTree(t.into())
}
}
pub trait ProofTreeLeaf {
fn proposition(&self) -> SigmaBoolean;
fn commitment_opt(&self) -> Option<FirstProverMessage>;
}
pub const GROUP_SIZE_BITS: usize = 256;
pub const GROUP_SIZE: usize = GROUP_SIZE_BITS / 8;
#[derive(PartialEq, Eq, Debug, Clone)]
pub struct GroupSizedBytes(pub Box<[u8; GROUP_SIZE]>);
impl From<GroupSizedBytes> for Scalar {
fn from(b: GroupSizedBytes) -> Self {
let sl: &[u8] = b.0.as_ref();
Scalar::from_bytes_reduced(sl.try_into().expect(""))
}
}
impl From<&[u8; GROUP_SIZE]> for GroupSizedBytes {
fn from(b: &[u8; GROUP_SIZE]) -> Self {
GroupSizedBytes(Box::new(*b))
}
}
pub const SOUNDNESS_BITS: usize = 192;
pub const SOUNDNESS_BYTES: usize = SOUNDNESS_BITS / 8;
#[cfg(test)]
#[cfg(feature = "arbitrary")]
mod tests {
use super::*;
#[allow(clippy::assertions_on_constants)]
#[test]
fn ensure_soundness_bits() {
assert!(SOUNDNESS_BITS < GROUP_SIZE_BITS);
assert!(SOUNDNESS_BYTES * 8 <= 512);
assert!(SOUNDNESS_BYTES % 8 == 0);
}
}