1use alloc::format;
2
3use serde::{Deserialize, Serialize};
4use slop_algebra::{AbstractExtensionField, AbstractField, Field};
5use sp1_primitives::{SP1ExtensionField, SP1Field};
6
7use super::{
8 Builder, Config, DslIr, ExtConst, ExtHandle, FeltHandle, FromConstant, SymbolicExt,
9 SymbolicFelt, SymbolicVar, VarHandle, Variable,
10};
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
16pub struct Var<N> {
17 pub(crate) idx: u32,
18 pub(crate) handle: *mut VarHandle<N>,
19}
20
21#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
25pub struct Felt<F> {
26 pub(crate) idx: u32,
27 pub(crate) handle: *mut FeltHandle<F>,
28}
29
30#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
34pub struct Ext<F, EF> {
35 pub(crate) idx: u32,
36 pub(crate) handle: *mut ExtHandle<F, EF>,
37}
38
39unsafe impl<N> Send for Var<N> {}
40unsafe impl<F, EF> Send for Ext<F, EF> {}
41unsafe impl<F> Send for Felt<F> {}
42
43unsafe impl<N> Sync for Var<N> {}
44unsafe impl<F, EF> Sync for Ext<F, EF> {}
45unsafe impl<F> Sync for Felt<F> {}
46
47#[derive(Debug, Clone, Default, Serialize, Deserialize)]
48pub struct Witness<C: Config> {
49 pub vars: Vec<C::N>,
50 pub felts: Vec<SP1Field>,
51 pub exts: Vec<SP1ExtensionField>,
52 pub vkey_hash: C::N,
53 pub committed_values_digest: C::N,
54 pub exit_code: C::N,
55 pub proof_nonce: C::N,
56 pub vk_root: C::N,
57}
58
59impl<C: Config> Witness<C> {
60 pub fn write_vkey_hash(&mut self, vkey_hash: C::N) {
61 self.vars.push(vkey_hash);
62 self.vkey_hash = vkey_hash;
63 }
64
65 pub fn write_committed_values_digest(&mut self, committed_values_digest: C::N) {
66 self.vars.push(committed_values_digest);
67 self.committed_values_digest = committed_values_digest
68 }
69
70 pub fn write_exit_code(&mut self, exit_code: C::N) {
71 self.vars.push(exit_code);
72 self.exit_code = exit_code;
73 }
74
75 pub fn write_vk_root(&mut self, vk_root: C::N) {
76 self.vars.push(vk_root);
77 self.vk_root = vk_root;
78 }
79
80 pub fn write_proof_nonce(&mut self, proof_nonce: C::N) {
81 self.vars.push(proof_nonce);
82 self.proof_nonce = proof_nonce;
83 }
84}
85
86impl<N> Var<N> {
87 pub(crate) const fn new(idx: u32, handle: *mut VarHandle<N>) -> Self {
88 Self { idx, handle }
89 }
90
91 pub(crate) fn id(&self) -> String {
92 format!("var{}", self.idx)
93 }
94}
95
96impl<F> Felt<F> {
97 pub(crate) const fn new(id: u32, handle: *mut FeltHandle<F>) -> Self {
98 Self { idx: id, handle }
99 }
100
101 pub(crate) fn id(&self) -> String {
102 format!("felt{}", self.idx)
103 }
104
105 pub(crate) fn inverse(&self) -> SymbolicFelt<F>
106 where
107 F: Field,
108 {
109 SymbolicFelt::<F>::one() / *self
110 }
111}
112
113impl<F, EF> Ext<F, EF> {
114 pub(crate) const fn new(id: u32, handle: *mut ExtHandle<F, EF>) -> Self {
115 Self { idx: id, handle }
116 }
117
118 pub(crate) fn id(&self) -> String {
119 format!("ext{}", self.idx)
120 }
121}
122
123impl<C: Config> Variable<C> for Var<C::N> {
124 type Expression = SymbolicVar<C::N>;
125
126 fn uninit(builder: &mut Builder<C>) -> Self {
127 let id = builder.variable_count();
128 let var = Var::new(id, builder.var_handle.as_mut());
129 builder.inner.get_mut().variable_count += 1;
130 var
131 }
132
133 fn assign(&self, src: Self::Expression, builder: &mut Builder<C>) {
134 match src {
135 SymbolicVar::Const(src) => {
136 builder.push_op(DslIr::ImmV(*self, src));
137 }
138 SymbolicVar::Val(src) => {
139 builder.push_op(DslIr::AddVI(*self, src, C::N::zero()));
140 }
141 }
142 }
143
144 fn assert_eq(
145 lhs: impl Into<Self::Expression>,
146 rhs: impl Into<Self::Expression>,
147 builder: &mut Builder<C>,
148 ) {
149 let lhs = lhs.into();
150 let rhs = rhs.into();
151
152 match (lhs, rhs) {
153 (SymbolicVar::Const(lhs), SymbolicVar::Const(rhs)) => {
154 assert_eq!(lhs, rhs, "Assertion failed at compile time");
155 }
156 (SymbolicVar::Const(lhs), SymbolicVar::Val(rhs)) => {
157 builder.push_traced_op(DslIr::AssertEqVI(rhs, lhs));
158 }
159 (SymbolicVar::Val(lhs), SymbolicVar::Const(rhs)) => {
160 builder.push_traced_op(DslIr::AssertEqVI(lhs, rhs));
161 }
162 (SymbolicVar::Val(lhs), SymbolicVar::Val(rhs)) => {
163 builder.push_traced_op(DslIr::AssertEqV(lhs, rhs));
164 }
165 }
166 }
167
168 fn assert_ne(
169 lhs: impl Into<Self::Expression>,
170 rhs: impl Into<Self::Expression>,
171 builder: &mut Builder<C>,
172 ) {
173 let lhs = lhs.into();
174 let rhs = rhs.into();
175
176 match (lhs, rhs) {
177 (SymbolicVar::Const(lhs), SymbolicVar::Const(rhs)) => {
178 assert_ne!(lhs, rhs, "Assertion failed at compile time");
179 }
180 (SymbolicVar::Const(lhs), SymbolicVar::Val(rhs)) => {
181 builder.push_traced_op(DslIr::AssertNeVI(rhs, lhs));
182 }
183 (SymbolicVar::Val(lhs), SymbolicVar::Const(rhs)) => {
184 builder.push_traced_op(DslIr::AssertNeVI(lhs, rhs));
185 }
186 (SymbolicVar::Val(lhs), SymbolicVar::Val(rhs)) => {
187 builder.push_traced_op(DslIr::AssertNeV(lhs, rhs));
188 }
189 }
190 }
191}
192
193impl<C: Config> Variable<C> for Felt<SP1Field> {
194 type Expression = SymbolicFelt<SP1Field>;
195
196 fn uninit(builder: &mut Builder<C>) -> Self {
197 let idx = builder.variable_count();
198 let felt = Felt::<SP1Field>::new(idx, builder.felt_handle.as_mut());
199 builder.inner.get_mut().variable_count += 1;
200 felt
201 }
202
203 fn assign(&self, src: Self::Expression, builder: &mut Builder<C>) {
204 match src {
205 SymbolicFelt::Const(src) => {
206 builder.push_op(DslIr::ImmF(*self, src));
207 }
208 SymbolicFelt::Val(src) => {
209 builder.push_op(DslIr::AddFI(*self, src, SP1Field::zero()));
210 }
211 }
212 }
213
214 fn assert_eq(
215 lhs: impl Into<Self::Expression>,
216 rhs: impl Into<Self::Expression>,
217 builder: &mut Builder<C>,
218 ) {
219 let lhs = lhs.into();
220 let rhs = rhs.into();
221
222 match (lhs, rhs) {
223 (SymbolicFelt::Const(lhs), SymbolicFelt::Const(rhs)) => {
224 assert_eq!(lhs, rhs, "Assertion failed at compile time");
225 }
226 (SymbolicFelt::Const(lhs), SymbolicFelt::Val(rhs)) => {
227 builder.push_traced_op(DslIr::AssertEqFI(rhs, lhs));
228 }
229 (SymbolicFelt::Val(lhs), SymbolicFelt::Const(rhs)) => {
230 builder.push_traced_op(DslIr::AssertEqFI(lhs, rhs));
231 }
232 (SymbolicFelt::Val(lhs), SymbolicFelt::Val(rhs)) => {
233 builder.push_traced_op(DslIr::AssertEqF(lhs, rhs));
234 }
235 }
236 }
237
238 fn assert_ne(
239 lhs: impl Into<Self::Expression>,
240 rhs: impl Into<Self::Expression>,
241 builder: &mut Builder<C>,
242 ) {
243 let lhs = lhs.into();
244 let rhs = rhs.into();
245
246 match (lhs, rhs) {
247 (SymbolicFelt::Const(lhs), SymbolicFelt::Const(rhs)) => {
248 assert_ne!(lhs, rhs, "Assertion failed at compile time");
249 }
250 (SymbolicFelt::Const(lhs), SymbolicFelt::Val(rhs)) => {
251 builder.push_traced_op(DslIr::AssertNeFI(rhs, lhs));
252 }
253 (SymbolicFelt::Val(lhs), SymbolicFelt::Const(rhs)) => {
254 builder.push_traced_op(DslIr::AssertNeFI(lhs, rhs));
255 }
256 (SymbolicFelt::Val(lhs), SymbolicFelt::Val(rhs)) => {
257 builder.push_traced_op(DslIr::AssertNeF(lhs, rhs));
258 }
259 }
260 }
261}
262
263impl<C: Config> Variable<C> for Ext<SP1Field, SP1ExtensionField> {
264 type Expression = SymbolicExt<SP1Field, SP1ExtensionField>;
265
266 fn uninit(builder: &mut Builder<C>) -> Self {
267 let idx = builder.variable_count();
268 let ext = Ext::<SP1Field, SP1ExtensionField>::new(idx, builder.ext_handle.as_mut());
269 builder.inner.get_mut().variable_count += 1;
270 ext
271 }
272
273 fn assign(&self, src: Self::Expression, builder: &mut Builder<C>) {
274 match src {
275 SymbolicExt::Const(src) => {
276 builder.push_op(DslIr::ImmE(*self, src));
277 }
278 SymbolicExt::Base(src) => match src {
279 SymbolicFelt::Const(src) => {
280 builder.push_op(DslIr::ImmE(*self, SP1ExtensionField::from_base(src)));
281 }
282 SymbolicFelt::Val(src) => {
283 builder.push_op(DslIr::AddEFFI(*self, src, SP1ExtensionField::zero()));
284 }
285 },
286 SymbolicExt::Val(src) => {
287 builder.push_op(DslIr::AddEI(*self, src, SP1ExtensionField::zero()));
288 }
289 }
290 }
291
292 fn assert_eq(
293 lhs: impl Into<Self::Expression>,
294 rhs: impl Into<Self::Expression>,
295 builder: &mut Builder<C>,
296 ) {
297 let lhs = lhs.into();
298 let rhs = rhs.into();
299
300 match (lhs, rhs) {
301 (SymbolicExt::Const(lhs), SymbolicExt::Const(rhs)) => {
302 assert_eq!(lhs, rhs, "Assertion failed at compile time");
303 }
304 (SymbolicExt::Const(lhs), SymbolicExt::Val(rhs)) => {
305 builder.push_traced_op(DslIr::AssertEqEI(rhs, lhs));
306 }
307 (SymbolicExt::Const(lhs), rhs) => {
308 let rhs_value = Self::uninit(builder);
309 rhs_value.assign(rhs, builder);
310 builder.push_traced_op(DslIr::AssertEqEI(rhs_value, lhs));
311 }
312 (SymbolicExt::Val(lhs), SymbolicExt::Const(rhs)) => {
313 builder.push_traced_op(DslIr::AssertEqEI(lhs, rhs));
314 }
315 (SymbolicExt::Val(lhs), SymbolicExt::Val(rhs)) => {
316 builder.push_traced_op(DslIr::AssertEqE(lhs, rhs));
317 }
318 (SymbolicExt::Val(lhs), rhs) => {
319 let rhs_value = Self::uninit(builder);
320 rhs_value.assign(rhs, builder);
321 builder.push_traced_op(DslIr::AssertEqE(lhs, rhs_value));
322 }
323 (lhs, rhs) => {
324 let lhs_value = Self::uninit(builder);
325 lhs_value.assign(lhs, builder);
326 let rhs_value = Self::uninit(builder);
327 rhs_value.assign(rhs, builder);
328 builder.push_traced_op(DslIr::AssertEqE(lhs_value, rhs_value));
329 }
330 }
331 }
332
333 fn assert_ne(
334 lhs: impl Into<Self::Expression>,
335 rhs: impl Into<Self::Expression>,
336 builder: &mut Builder<C>,
337 ) {
338 let lhs = lhs.into();
339 let rhs = rhs.into();
340
341 match (lhs, rhs) {
342 (SymbolicExt::Const(lhs), SymbolicExt::Const(rhs)) => {
343 assert_ne!(lhs, rhs, "Assertion failed at compile time");
344 }
345 (SymbolicExt::Const(lhs), SymbolicExt::Val(rhs)) => {
346 builder.push_traced_op(DslIr::AssertNeEI(rhs, lhs));
347 }
348 (SymbolicExt::Const(lhs), rhs) => {
349 let rhs_value = Self::uninit(builder);
350 rhs_value.assign(rhs, builder);
351 builder.push_traced_op(DslIr::AssertNeEI(rhs_value, lhs));
352 }
353 (SymbolicExt::Val(lhs), SymbolicExt::Const(rhs)) => {
354 builder.push_traced_op(DslIr::AssertNeEI(lhs, rhs));
355 }
356 (SymbolicExt::Val(lhs), SymbolicExt::Val(rhs)) => {
357 builder.push_traced_op(DslIr::AssertNeE(lhs, rhs));
358 }
359 (SymbolicExt::Val(lhs), rhs) => {
360 let rhs_value = Self::uninit(builder);
361 rhs_value.assign(rhs, builder);
362 builder.push_traced_op(DslIr::AssertNeE(lhs, rhs_value));
363 }
364 (lhs, rhs) => {
365 let lhs_value = Self::uninit(builder);
366 lhs_value.assign(lhs, builder);
367 let rhs_value = Self::uninit(builder);
368 rhs_value.assign(rhs, builder);
369 builder.push_traced_op(DslIr::AssertNeE(lhs_value, rhs_value));
370 }
371 }
372 }
373}
374
375impl<C: Config> FromConstant<C> for Var<C::N> {
376 type Constant = C::N;
377
378 fn constant(value: Self::Constant, builder: &mut Builder<C>) -> Self {
379 builder.eval(value)
380 }
381}
382
383impl<C: Config> FromConstant<C> for Felt<SP1Field> {
384 type Constant = SP1Field;
385
386 fn constant(value: Self::Constant, builder: &mut Builder<C>) -> Self {
387 builder.eval(value)
388 }
389}
390
391impl<C: Config> FromConstant<C> for Ext<SP1Field, SP1ExtensionField> {
392 type Constant = SP1ExtensionField;
393
394 fn constant(value: Self::Constant, builder: &mut Builder<C>) -> Self {
395 builder.eval(value.cons())
396 }
397}