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 Groth16V2_2 = 0xbb001d44,
48 Groth16V3_0 = 0x73c457ba,
49 SetVerifierV0_1 = 0xbfca9ccb,
50 SetVerifierV0_2 = 0x16a15cc8,
51 SetVerifierV0_4 = 0xf443ad7b,
52 SetVerifierV0_5 = 0xf2e6e6dc,
53 SetVerifierV0_6 = 0x80479d24,
54 SetVerifierV0_7 = 0x0f63ffd5,
55 SetVerifierV0_9 = 0x242f9d5b,
56}
57
58impl Display for Selector {
59 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
60 write!(f, "{:#010x}", *self as u32)
61 }
62}
63
64impl TryFrom<u32> for Selector {
65 type Error = SelectorError;
66
67 fn try_from(value: u32) -> Result<Self, Self::Error> {
68 match value {
69 0xFFFFFFFF => Ok(Selector::FakeReceipt),
70 0x50bd1769 => Ok(Selector::Groth16V1_1),
71 0xc101b42b => Ok(Selector::Groth16V1_2),
72 0x9f39696c => Ok(Selector::Groth16V2_0),
73 0xf536085a => Ok(Selector::Groth16V2_1),
74 0xbb001d44 => Ok(Selector::Groth16V2_2),
75 0x73c457ba => Ok(Selector::Groth16V3_0),
76 0xbfca9ccb => Ok(Selector::SetVerifierV0_1),
77 0x16a15cc8 => Ok(Selector::SetVerifierV0_2),
78 0xf443ad7b => Ok(Selector::SetVerifierV0_4),
79 0xf2e6e6dc => Ok(Selector::SetVerifierV0_5),
80 0x80479d24 => Ok(Selector::SetVerifierV0_6),
81 0x0f63ffd5 => Ok(Selector::SetVerifierV0_7),
82 0x242f9d5b => Ok(Selector::SetVerifierV0_9),
83 _ => Err(SelectorError::UnsupportedSelector),
84 }
85 }
86}
87
88impl Selector {
89 pub fn verifier_parameters_digest(self) -> Result<Digest, SelectorError> {
90 match self {
91 Selector::FakeReceipt => {
92 Err(SelectorError::NoVerifierParameters(Selector::FakeReceipt))
93 }
94 Selector::Groth16V1_1 => Ok(Digest::from_hex(
95 "50bd1769093e74abda3711c315d84d78e3e282173f6304a33272d92abb590ef5",
96 )
97 .unwrap()),
98 Selector::Groth16V1_2 => Ok(Digest::from_hex(
99 "c101b42bcacd62e35222b1207223250814d05dd41d41f8cadc1f16f86707ae15",
100 )
101 .unwrap()),
102 Selector::Groth16V2_0 => Ok(Digest::from_hex(
103 "9f39696cb3ae9d6038d6b7a55c09017f0cf35e226ad7582b82dbabb0dae53385",
104 )
105 .unwrap()),
106 Selector::Groth16V2_1 => Ok(Digest::from_hex(
107 "f536085a791bdbc6cb46ab3074f88e9e94eabb192de8daca3caee1f4ed811b08",
108 )
109 .unwrap()),
110 Selector::Groth16V2_2 => Ok(Digest::from_hex(
111 "bb001d444841d70e8bc0c7d034b349044bf3cf0117afb702b2f1e898b7dd13cc",
112 )
113 .unwrap()),
114 Selector::Groth16V3_0 => Ok(Digest::from_hex(
115 "73c457ba541936f0d907daf0c7253a39a9c5c427c225ba7709e44702d3c6eedc",
116 )
117 .unwrap()),
118 Selector::SetVerifierV0_1 => Ok(Digest::from_hex(
119 "bfca9ccb59eb38b8c78ddc399a734d8e0e84e8028b7d616fa54fe707a1ff1b3b",
120 )
121 .unwrap()),
122 Selector::SetVerifierV0_2 => Ok(Digest::from_hex(
123 "16a15cc8c94a59dc3e4e41226bc560ecda596a371a487b7ecc6b65d9516dfbdb",
124 )
125 .unwrap()),
126 Selector::SetVerifierV0_4 => Ok(Digest::from_hex(
127 "f443ad7bfe538ec90fa38498afd30b27b7d06336f20249b620a6d85ab3c615b6",
128 )
129 .unwrap()),
130 Selector::SetVerifierV0_5 => Ok(Digest::from_hex(
131 "f2e6e6dc660ed3ec9d8abb666cd481509c74990fc4d599f3f4a34b9df151f3fd",
132 )
133 .unwrap()),
134 Selector::SetVerifierV0_6 => Ok(Digest::from_hex(
135 "80479d24c20613acbaae52f5498cb60f661a26c0681ff2b750611dbaf9ecaa66",
136 )
137 .unwrap()),
138 Selector::SetVerifierV0_7 => Ok(Digest::from_hex(
139 "0f63ffd5b1579bf938597f82089ca639a393341e888f58c12d0c91065eb2a3de",
140 )
141 .unwrap()),
142 Selector::SetVerifierV0_9 => Ok(Digest::from_hex(
143 "242f9d5b8df6e1660fd7cadeec6f213501adaadb3d03d76b2ba400cf25366e2b",
144 )
145 .unwrap()),
146 }
147 }
148
149 pub fn get_type(self) -> SelectorType {
150 match self {
151 Selector::FakeReceipt => SelectorType::FakeReceipt,
152 Selector::Groth16V1_1
153 | Selector::Groth16V1_2
154 | Selector::Groth16V2_0
155 | Selector::Groth16V2_1
156 | Selector::Groth16V2_2
157 | Selector::Groth16V3_0 => SelectorType::Groth16,
158 Selector::SetVerifierV0_1
159 | Selector::SetVerifierV0_2
160 | Selector::SetVerifierV0_4
161 | Selector::SetVerifierV0_5
162 | Selector::SetVerifierV0_6
163 | Selector::SetVerifierV0_7
164 | Selector::SetVerifierV0_9 => SelectorType::SetVerifier,
165 }
166 }
167
168 pub fn from_bytes(bytes: [u8; 4]) -> Option<Self> {
169 Self::try_from(u32::from_be_bytes(bytes)).ok()
170 }
171
172 pub const fn groth16_latest() -> Self {
174 Self::Groth16V3_0
175 }
176
177 pub const fn set_inclusion_latest() -> Self {
180 Self::SetVerifierV0_9
181 }
182}
183
184#[cfg(test)]
185mod tests {
186 use super::Selector;
187 use hex::FromHex;
188 use risc0_aggregation::SetInclusionReceiptVerifierParameters;
189 use risc0_zkvm::{
190 sha::{Digest, Digestible},
191 Groth16ReceiptVerifierParameters,
192 };
193
194 const SET_BUILDER_ID: &str = "70909b25db0db00f1d4b4016aeb876f53568a3e5a8e6397cb562d79947a02cc9";
196
197 #[test]
198 fn print_verifier_parameters() {
199 let groth16_digest = Groth16ReceiptVerifierParameters::default().digest();
200 println!("Groth16ReceiptVerifierParameters {groth16_digest}");
201
202 let set_inclusion_digest = SetInclusionReceiptVerifierParameters {
203 image_id: Digest::from_hex(SET_BUILDER_ID).unwrap(),
204 }
205 .digest();
206 println!("SetInclusionReceiptVerifierParameters {set_inclusion_digest}");
207
208 assert_eq!(
209 groth16_digest,
210 Selector::groth16_latest()
211 .verifier_parameters_digest()
212 .unwrap()
213 );
214 assert_eq!(
215 set_inclusion_digest,
216 Selector::set_inclusion_latest()
217 .verifier_parameters_digest()
218 .unwrap()
219 );
220 }
221}