1use super::felt252::Felt252Type;
2use super::non_zero::nonzero_ty;
3use super::range_check::RangeCheckType;
4use crate::define_libfunc_hierarchy;
5use crate::extensions::lib_func::{
6 BranchSignature, DeferredOutputKind, LibfuncSignature, OutputVarInfo, ParamSignature,
7 SierraApChange, SignatureSpecializationContext,
8};
9use crate::extensions::{
10 NamedType, NoGenericArgsGenericLibfunc, NoGenericArgsGenericType, OutputVarReferenceInfo,
11 SpecializationError,
12};
13use crate::ids::GenericTypeId;
14
15#[derive(Default)]
17pub struct EcOpType {}
18impl NoGenericArgsGenericType for EcOpType {
19 const ID: GenericTypeId = GenericTypeId::new_inline("EcOp");
20 const STORABLE: bool = true;
21 const DUPLICATABLE: bool = false;
22 const DROPPABLE: bool = false;
23 const ZERO_SIZED: bool = false;
24}
25
26#[derive(Default)]
28pub struct EcPointType {}
29impl NoGenericArgsGenericType for EcPointType {
30 const ID: GenericTypeId = GenericTypeId::new_inline("EcPoint");
31 const STORABLE: bool = true;
32 const DUPLICATABLE: bool = true;
33 const DROPPABLE: bool = true;
34 const ZERO_SIZED: bool = false;
35}
36
37#[derive(Default)]
39pub struct EcStateType {}
40impl NoGenericArgsGenericType for EcStateType {
41 const ID: GenericTypeId = GenericTypeId::new_inline("EcState");
42 const STORABLE: bool = true;
43 const DUPLICATABLE: bool = true;
44 const DROPPABLE: bool = true;
45 const ZERO_SIZED: bool = false;
46}
47
48define_libfunc_hierarchy! {
49 pub enum EcLibfunc {
50 IsZero(EcIsZeroLibfunc),
51 Neg(EcNegLibfunc),
52 StateAdd(EcStateAddLibfunc),
53 TryNew(EcCreatePointLibfunc),
54 StateFinalize(EcStateFinalizeLibfunc),
55 StateInit(EcStateInitLibfunc),
56 StateAddMul(EcStateAddMulLibfunc),
57 PointFromX(EcPointFromXLibfunc),
58 UnwrapPoint(EcUnwrapPointLibfunc),
59 Zero(EcZeroLibfunc),
60 }, EcConcreteLibfunc
61}
62
63#[derive(Default)]
65pub struct EcZeroLibfunc {}
66impl NoGenericArgsGenericLibfunc for EcZeroLibfunc {
67 const STR_ID: &'static str = "ec_point_zero";
68
69 fn specialize_signature(
70 &self,
71 context: &dyn SignatureSpecializationContext,
72 ) -> Result<LibfuncSignature, SpecializationError> {
73 let ecpoint_ty = context.get_concrete_type(EcPointType::id(), &[])?;
74
75 Ok(LibfuncSignature::new_non_branch(
76 vec![],
77 vec![OutputVarInfo {
78 ty: ecpoint_ty,
79 ref_info: OutputVarReferenceInfo::Deferred(DeferredOutputKind::Const),
80 }],
81 SierraApChange::Known { new_vars_only: true },
82 ))
83 }
84}
85
86#[derive(Default)]
89pub struct EcCreatePointLibfunc {}
90impl NoGenericArgsGenericLibfunc for EcCreatePointLibfunc {
91 const STR_ID: &'static str = "ec_point_try_new_nz";
92
93 fn specialize_signature(
94 &self,
95 context: &dyn SignatureSpecializationContext,
96 ) -> Result<LibfuncSignature, SpecializationError> {
97 let ecpoint_ty = context.get_concrete_type(EcPointType::id(), &[])?;
98 let nonzero_ecpoint_ty = nonzero_ty(context, &ecpoint_ty)?;
99 let felt252_param = ParamSignature::new(context.get_concrete_type(Felt252Type::id(), &[])?);
100
101 Ok(LibfuncSignature {
102 param_signatures: vec![felt252_param.clone(), felt252_param],
103 branch_signatures: vec![
104 BranchSignature {
106 vars: vec![OutputVarInfo {
107 ty: nonzero_ecpoint_ty,
108 ref_info: OutputVarReferenceInfo::Deferred(DeferredOutputKind::Generic),
109 }],
110 ap_change: SierraApChange::Known { new_vars_only: false },
111 },
112 BranchSignature {
114 vars: vec![],
115 ap_change: SierraApChange::Known { new_vars_only: false },
116 },
117 ],
118 fallthrough: Some(0),
119 })
120 }
121}
122
123#[derive(Default)]
129pub struct EcPointFromXLibfunc {}
130impl NoGenericArgsGenericLibfunc for EcPointFromXLibfunc {
131 const STR_ID: &'static str = "ec_point_from_x_nz";
132
133 fn specialize_signature(
134 &self,
135 context: &dyn SignatureSpecializationContext,
136 ) -> Result<LibfuncSignature, SpecializationError> {
137 let felt252_ty = context.get_concrete_type(Felt252Type::id(), &[])?;
138 let ecpoint_ty = context.get_concrete_type(EcPointType::id(), &[])?;
139 let nonzero_ecpoint_ty = nonzero_ty(context, &ecpoint_ty)?;
140 let range_check_type = context.get_concrete_type(RangeCheckType::id(), &[])?;
141
142 let rc_output_info = OutputVarInfo::new_builtin(range_check_type.clone(), 0);
143 Ok(LibfuncSignature {
144 param_signatures: vec![
145 ParamSignature::new(range_check_type).with_allow_add_const(),
146 ParamSignature::new(felt252_ty),
147 ],
148 branch_signatures: vec![
149 BranchSignature {
151 vars: vec![
152 rc_output_info.clone(),
153 OutputVarInfo {
154 ty: nonzero_ecpoint_ty,
155 ref_info: OutputVarReferenceInfo::Deferred(DeferredOutputKind::Generic),
156 },
157 ],
158 ap_change: SierraApChange::Known { new_vars_only: false },
159 },
160 BranchSignature {
162 vars: vec![rc_output_info],
163 ap_change: SierraApChange::Known { new_vars_only: false },
164 },
165 ],
166 fallthrough: Some(0),
167 })
168 }
169}
170
171#[derive(Default)]
173pub struct EcUnwrapPointLibfunc {}
174impl NoGenericArgsGenericLibfunc for EcUnwrapPointLibfunc {
175 const STR_ID: &'static str = "ec_point_unwrap";
176
177 fn specialize_signature(
178 &self,
179 context: &dyn SignatureSpecializationContext,
180 ) -> Result<LibfuncSignature, SpecializationError> {
181 let felt252_ty = context.get_concrete_type(Felt252Type::id(), &[])?;
182 let ecpoint_ty = context.get_concrete_type(EcPointType::id(), &[])?;
183 let nonzero_ecpoint_ty = nonzero_ty(context, &ecpoint_ty)?;
184
185 let felt252_partial_param_0_output_info = OutputVarInfo {
186 ty: felt252_ty,
187 ref_info: OutputVarReferenceInfo::PartialParam { param_idx: 0 },
188 };
189 Ok(LibfuncSignature::new_non_branch(
191 vec![nonzero_ecpoint_ty],
192 vec![felt252_partial_param_0_output_info.clone(), felt252_partial_param_0_output_info],
193 SierraApChange::Known { new_vars_only: true },
194 ))
195 }
196}
197
198#[derive(Default)]
200pub struct EcNegLibfunc {}
201impl NoGenericArgsGenericLibfunc for EcNegLibfunc {
202 const STR_ID: &'static str = "ec_neg";
203
204 fn specialize_signature(
205 &self,
206 context: &dyn SignatureSpecializationContext,
207 ) -> Result<LibfuncSignature, SpecializationError> {
208 let ecpoint_ty = context.get_concrete_type(EcPointType::id(), &[])?;
209
210 Ok(LibfuncSignature::new_non_branch(
211 vec![ecpoint_ty.clone()],
212 vec![OutputVarInfo {
213 ty: ecpoint_ty,
214 ref_info: OutputVarReferenceInfo::Deferred(DeferredOutputKind::Generic),
215 }],
216 SierraApChange::Known { new_vars_only: true },
217 ))
218 }
219}
220
221#[derive(Default)]
223pub struct EcIsZeroLibfunc {}
224impl NoGenericArgsGenericLibfunc for EcIsZeroLibfunc {
225 const STR_ID: &'static str = "ec_point_is_zero";
226
227 fn specialize_signature(
228 &self,
229 context: &dyn SignatureSpecializationContext,
230 ) -> Result<LibfuncSignature, SpecializationError> {
231 let ecpoint_ty = context.get_concrete_type(EcPointType::id(), &[])?;
232 let nonzero_ecpoint_ty = nonzero_ty(context, &ecpoint_ty)?;
233
234 Ok(LibfuncSignature {
235 param_signatures: vec![ParamSignature::new(ecpoint_ty)],
236 branch_signatures: vec![
237 BranchSignature {
239 vars: vec![],
240 ap_change: SierraApChange::Known { new_vars_only: true },
241 },
242 BranchSignature {
244 vars: vec![OutputVarInfo {
245 ty: nonzero_ecpoint_ty,
246 ref_info: OutputVarReferenceInfo::SameAsParam { param_idx: 0 },
247 }],
248 ap_change: SierraApChange::Known { new_vars_only: true },
249 },
250 ],
251 fallthrough: Some(0),
252 })
253 }
254}
255
256#[derive(Default)]
258pub struct EcStateInitLibfunc {}
259impl NoGenericArgsGenericLibfunc for EcStateInitLibfunc {
260 const STR_ID: &'static str = "ec_state_init";
261
262 fn specialize_signature(
263 &self,
264 context: &dyn SignatureSpecializationContext,
265 ) -> Result<LibfuncSignature, SpecializationError> {
266 Ok(LibfuncSignature::new_non_branch(
267 vec![],
268 vec![OutputVarInfo {
269 ty: context.get_concrete_type(EcStateType::id(), &[])?,
270 ref_info: OutputVarReferenceInfo::NewTempVar { idx: 0 },
271 }],
272 SierraApChange::Known { new_vars_only: false },
273 ))
274 }
275}
276
277#[derive(Default)]
279pub struct EcStateAddLibfunc {}
280impl NoGenericArgsGenericLibfunc for EcStateAddLibfunc {
281 const STR_ID: &'static str = "ec_state_add";
282
283 fn specialize_signature(
284 &self,
285 context: &dyn SignatureSpecializationContext,
286 ) -> Result<LibfuncSignature, SpecializationError> {
287 let state_ty = context.get_concrete_type(EcStateType::id(), &[])?;
288 let ecpoint_ty = context.get_concrete_type(EcPointType::id(), &[])?;
289 let nonzero_ecpoint_ty = nonzero_ty(context, &ecpoint_ty)?;
290
291 Ok(LibfuncSignature::new_non_branch(
292 vec![state_ty.clone(), nonzero_ecpoint_ty],
293 vec![OutputVarInfo {
294 ty: state_ty,
295 ref_info: OutputVarReferenceInfo::Deferred(DeferredOutputKind::Generic),
296 }],
297 SierraApChange::Known { new_vars_only: false },
298 ))
299 }
300}
301
302#[derive(Default)]
304pub struct EcStateFinalizeLibfunc {}
305impl NoGenericArgsGenericLibfunc for EcStateFinalizeLibfunc {
306 const STR_ID: &'static str = "ec_state_try_finalize_nz";
307
308 fn specialize_signature(
309 &self,
310 context: &dyn SignatureSpecializationContext,
311 ) -> Result<LibfuncSignature, SpecializationError> {
312 let ecpoint_ty = context.get_concrete_type(EcPointType::id(), &[])?;
313 let nonzero_ecpoint_ty = nonzero_ty(context, &ecpoint_ty)?;
314
315 Ok(LibfuncSignature {
316 param_signatures: vec![ParamSignature::new(
317 context.get_concrete_type(EcStateType::id(), &[])?,
318 )],
319 branch_signatures: vec![
320 BranchSignature {
322 vars: vec![OutputVarInfo {
323 ty: nonzero_ecpoint_ty,
324 ref_info: OutputVarReferenceInfo::NewTempVar { idx: 0 },
325 }],
326 ap_change: SierraApChange::Known { new_vars_only: false },
327 },
328 BranchSignature {
330 vars: vec![],
331 ap_change: SierraApChange::Known { new_vars_only: false },
332 },
333 ],
334 fallthrough: Some(0),
335 })
336 }
337}
338
339#[derive(Default)]
342pub struct EcStateAddMulLibfunc {}
343impl NoGenericArgsGenericLibfunc for EcStateAddMulLibfunc {
344 const STR_ID: &'static str = "ec_state_add_mul";
345
346 fn specialize_signature(
347 &self,
348 context: &dyn SignatureSpecializationContext,
349 ) -> Result<LibfuncSignature, SpecializationError> {
350 let ec_builtin_ty = context.get_concrete_type(EcOpType::id(), &[])?;
351 let ec_state_ty = context.get_concrete_type(EcStateType::id(), &[])?;
352 let ecpoint_ty = context.get_concrete_type(EcPointType::id(), &[])?;
353 let nonzero_ecpoint_ty = nonzero_ty(context, &ecpoint_ty)?;
354
355 Ok(LibfuncSignature::new_non_branch_ex(
356 vec![
357 ParamSignature::new(ec_builtin_ty.clone()).with_allow_add_const(),
358 ParamSignature::new(ec_state_ty.clone()),
359 ParamSignature::new(context.get_concrete_type(Felt252Type::id(), &[])?),
360 ParamSignature::new(nonzero_ecpoint_ty),
361 ],
362 vec![
363 OutputVarInfo::new_builtin(ec_builtin_ty, 0),
364 OutputVarInfo {
365 ty: ec_state_ty,
366 ref_info: OutputVarReferenceInfo::Deferred(DeferredOutputKind::Generic),
367 },
368 ],
369 SierraApChange::Known { new_vars_only: true },
370 ))
371 }
372}