risc0_ethereum_contracts/
selector.rs1use std::fmt::{self, Display, Formatter};
16
17use hex::FromHex;
18use risc0_zkvm::sha::Digest;
19use thiserror::Error;
20
21#[derive(Debug, Error)]
22#[non_exhaustive]
23pub enum SelectorError {
24 #[error("Unsupported selector")]
25 UnsupportedSelector,
26 #[error("Selector {0} does not have verifier parameters")]
27 NoVerifierParameters(Selector),
28}
29
30#[derive(Debug, Clone, Copy, PartialEq, Eq)]
31#[non_exhaustive]
32pub enum SelectorType {
33 FakeReceipt,
34 Groth16,
35 SetVerifier,
36}
37
38#[repr(u32)]
39#[derive(Debug, Clone, Copy, PartialEq, Eq)]
40#[non_exhaustive]
41pub enum Selector {
42 FakeReceipt = 0xFFFFFFFF,
43 Groth16V1_1 = 0x50bd1769,
44 Groth16V1_2 = 0xc101b42b,
45 Groth16V2_0 = 0x9f39696c,
46 Groth16V2_1 = 0xf536085a,
47 SetVerifierV0_1 = 0xbfca9ccb,
48 SetVerifierV0_2 = 0x16a15cc8,
49 SetVerifierV0_4 = 0xf443ad7b,
50 SetVerifierV0_5 = 0xf2e6e6dc,
51 SetVerifierV0_6 = 0x80479d24,
52 SetVerifierV0_7 = 0x0f63ffd5,
53}
54
55impl Display for Selector {
56 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
57 write!(f, "{:#010x}", *self as u32)
58 }
59}
60
61impl TryFrom<u32> for Selector {
62 type Error = SelectorError;
63
64 fn try_from(value: u32) -> Result<Self, Self::Error> {
65 match value {
66 0xFFFFFFFF => Ok(Selector::FakeReceipt),
67 0x50bd1769 => Ok(Selector::Groth16V1_1),
68 0xc101b42b => Ok(Selector::Groth16V1_2),
69 0x9f39696c => Ok(Selector::Groth16V2_0),
70 0xf536085a => Ok(Selector::Groth16V2_1),
71 0xbfca9ccb => Ok(Selector::SetVerifierV0_1),
72 0x16a15cc8 => Ok(Selector::SetVerifierV0_2),
73 0xf443ad7b => Ok(Selector::SetVerifierV0_4),
74 0xf2e6e6dc => Ok(Selector::SetVerifierV0_5),
75 0x80479d24 => Ok(Selector::SetVerifierV0_6),
76 0x0f63ffd5 => Ok(Selector::SetVerifierV0_7),
77 _ => Err(SelectorError::UnsupportedSelector),
78 }
79 }
80}
81
82impl Selector {
83 pub fn verifier_parameters_digest(self) -> Result<Digest, SelectorError> {
84 match self {
85 Selector::FakeReceipt => {
86 Err(SelectorError::NoVerifierParameters(Selector::FakeReceipt))
87 }
88 Selector::Groth16V1_1 => Ok(Digest::from_hex(
89 "50bd1769093e74abda3711c315d84d78e3e282173f6304a33272d92abb590ef5",
90 )
91 .unwrap()),
92 Selector::Groth16V1_2 => Ok(Digest::from_hex(
93 "c101b42bcacd62e35222b1207223250814d05dd41d41f8cadc1f16f86707ae15",
94 )
95 .unwrap()),
96 Selector::Groth16V2_0 => Ok(Digest::from_hex(
97 "9f39696cb3ae9d6038d6b7a55c09017f0cf35e226ad7582b82dbabb0dae53385",
98 )
99 .unwrap()),
100 Selector::Groth16V2_1 => Ok(Digest::from_hex(
101 "f536085a791bdbc6cb46ab3074f88e9e94eabb192de8daca3caee1f4ed811b08",
102 )
103 .unwrap()),
104 Selector::SetVerifierV0_1 => Ok(Digest::from_hex(
105 "bfca9ccb59eb38b8c78ddc399a734d8e0e84e8028b7d616fa54fe707a1ff1b3b",
106 )
107 .unwrap()),
108 Selector::SetVerifierV0_2 => Ok(Digest::from_hex(
109 "16a15cc8c94a59dc3e4e41226bc560ecda596a371a487b7ecc6b65d9516dfbdb",
110 )
111 .unwrap()),
112 Selector::SetVerifierV0_4 => Ok(Digest::from_hex(
113 "f443ad7bfe538ec90fa38498afd30b27b7d06336f20249b620a6d85ab3c615b6",
114 )
115 .unwrap()),
116 Selector::SetVerifierV0_5 => Ok(Digest::from_hex(
117 "f2e6e6dc660ed3ec9d8abb666cd481509c74990fc4d599f3f4a34b9df151f3fd",
118 )
119 .unwrap()),
120 Selector::SetVerifierV0_6 => Ok(Digest::from_hex(
121 "80479d24c20613acbaae52f5498cb60f661a26c0681ff2b750611dbaf9ecaa66",
122 )
123 .unwrap()),
124 Selector::SetVerifierV0_7 => Ok(Digest::from_hex(
125 "0f63ffd5b1579bf938597f82089ca639a393341e888f58c12d0c91065eb2a3de",
126 )
127 .unwrap()),
128 }
129 }
130
131 pub fn get_type(self) -> SelectorType {
132 match self {
133 Selector::FakeReceipt => SelectorType::FakeReceipt,
134 Selector::Groth16V1_1
135 | Selector::Groth16V1_2
136 | Selector::Groth16V2_0
137 | Selector::Groth16V2_1 => SelectorType::Groth16,
138 Selector::SetVerifierV0_1
139 | Selector::SetVerifierV0_2
140 | Selector::SetVerifierV0_4
141 | Selector::SetVerifierV0_5
142 | Selector::SetVerifierV0_6
143 | Selector::SetVerifierV0_7 => SelectorType::SetVerifier,
144 }
145 }
146
147 pub fn from_bytes(bytes: [u8; 4]) -> Option<Self> {
148 Self::try_from(u32::from_be_bytes(bytes)).ok()
149 }
150
151 pub const fn groth16_latest() -> Self {
153 Self::Groth16V2_1
154 }
155
156 pub const fn set_inclusion_latest() -> Self {
159 Self::SetVerifierV0_7
160 }
161}
162
163#[cfg(test)]
164mod tests {
165 use hex::FromHex;
166 use risc0_aggregation::SetInclusionReceiptVerifierParameters;
167 use risc0_zkvm::{
168 sha::{Digest, Digestible},
169 Groth16ReceiptVerifierParameters,
170 };
171
172 const SET_BUILDER_ID: &str = "a218e889a26852fd3d57a80983c76b53ff6d5fa4b469779511dd4d99329ae7aa";
174
175 #[test]
176 fn print_verifier_parameters() {
177 let digest = Groth16ReceiptVerifierParameters::default().digest();
178 println!("Groth16ReceiptVerifierParameters {}", digest);
179
180 let digest = SetInclusionReceiptVerifierParameters {
181 image_id: Digest::from_hex(SET_BUILDER_ID).unwrap(),
182 }
183 .digest();
184 println!("SetInclusionReceiptVerifierParameters {}", digest);
185 }
186}