cairo_lang_sierra/extensions/modules/int/
unsigned256.rs1use super::unsigned128::{U128MulGuaranteeType, Uint128Type};
2use crate::define_libfunc_hierarchy;
3use crate::extensions::lib_func::{
4 BranchSignature, LibfuncSignature, OutputVarInfo, ParamSignature, SierraApChange,
5 SignatureSpecializationContext,
6};
7use crate::extensions::modules::get_u256_type;
8use crate::extensions::non_zero::nonzero_ty;
9use crate::extensions::range_check::RangeCheckType;
10use crate::extensions::{
11 NamedType, NoGenericArgsGenericLibfunc, OutputVarReferenceInfo, SpecializationError,
12};
13
14define_libfunc_hierarchy! {
15 pub enum Uint256Libfunc {
16 IsZero(Uint256IsZeroLibfunc),
17 Divmod(Uint256DivmodLibfunc),
18 SquareRoot(Uint256SquareRootLibfunc),
19 InvModN(Uint256InvModNLibfunc),
20 }, Uint256Concrete
21}
22
23#[derive(Default)]
25pub struct Uint256IsZeroLibfunc;
26impl NoGenericArgsGenericLibfunc for Uint256IsZeroLibfunc {
27 const STR_ID: &'static str = "u256_is_zero";
28
29 fn specialize_signature(
30 &self,
31 context: &dyn SignatureSpecializationContext,
32 ) -> Result<LibfuncSignature, SpecializationError> {
33 let u256_ty = get_u256_type(context)?;
34 Ok(LibfuncSignature {
35 param_signatures: vec![ParamSignature::new(u256_ty.clone())],
36 branch_signatures: vec![
37 BranchSignature {
39 vars: vec![],
40 ap_change: SierraApChange::Known { new_vars_only: true },
41 },
42 BranchSignature {
44 vars: vec![OutputVarInfo {
45 ty: nonzero_ty(context, &u256_ty)?,
46 ref_info: OutputVarReferenceInfo::SameAsParam { param_idx: 0 },
47 }],
48 ap_change: SierraApChange::Known { new_vars_only: true },
49 },
50 ],
51 fallthrough: Some(0),
52 })
53 }
54}
55
56#[derive(Default)]
58pub struct Uint256DivmodLibfunc;
59impl NoGenericArgsGenericLibfunc for Uint256DivmodLibfunc {
60 const STR_ID: &'static str = "u256_safe_divmod";
61
62 fn specialize_signature(
63 &self,
64 context: &dyn SignatureSpecializationContext,
65 ) -> Result<LibfuncSignature, SpecializationError> {
66 let u256_type = get_u256_type(context)?;
67 let range_check_type = context.get_concrete_type(RangeCheckType::id(), &[])?;
68 let simple_deref_u256_output_info =
69 OutputVarInfo { ty: u256_type.clone(), ref_info: OutputVarReferenceInfo::SimpleDerefs };
70 Ok(LibfuncSignature::new_non_branch_ex(
71 vec![
72 ParamSignature::new(range_check_type.clone()).with_allow_add_const(),
73 ParamSignature::new(u256_type.clone()),
74 ParamSignature::new(nonzero_ty(context, &u256_type)?),
75 ],
76 vec![
77 OutputVarInfo::new_builtin(range_check_type, 0),
78 simple_deref_u256_output_info.clone(),
79 simple_deref_u256_output_info,
80 OutputVarInfo {
81 ty: context.get_concrete_type(U128MulGuaranteeType::id(), &[])?,
82 ref_info: OutputVarReferenceInfo::SimpleDerefs,
83 },
84 ],
85 SierraApChange::Known { new_vars_only: false },
86 ))
87 }
88}
89
90#[derive(Default)]
92pub struct Uint256SquareRootLibfunc;
93impl NoGenericArgsGenericLibfunc for Uint256SquareRootLibfunc {
94 const STR_ID: &'static str = "u256_sqrt";
95
96 fn specialize_signature(
97 &self,
98 context: &dyn SignatureSpecializationContext,
99 ) -> Result<LibfuncSignature, SpecializationError> {
100 let range_check_type = context.get_concrete_type(RangeCheckType::id(), &[])?;
101 Ok(LibfuncSignature::new_non_branch_ex(
102 vec![
103 ParamSignature::new(range_check_type.clone()).with_allow_add_const(),
104 ParamSignature::new(get_u256_type(context)?),
105 ],
106 vec![OutputVarInfo::new_builtin(range_check_type, 0), OutputVarInfo {
107 ty: context.get_concrete_type(Uint128Type::id(), &[])?,
108 ref_info: OutputVarReferenceInfo::SimpleDerefs,
109 }],
110 SierraApChange::Known { new_vars_only: false },
111 ))
112 }
113}
114
115#[derive(Default)]
120pub struct Uint256InvModNLibfunc;
121impl NoGenericArgsGenericLibfunc for Uint256InvModNLibfunc {
122 const STR_ID: &'static str = "u256_guarantee_inv_mod_n";
123
124 fn specialize_signature(
125 &self,
126 context: &dyn SignatureSpecializationContext,
127 ) -> Result<LibfuncSignature, SpecializationError> {
128 let u256_ty = get_u256_type(context)?;
129 let nz_ty = nonzero_ty(context, &u256_ty)?;
130 let range_check_type = context.get_concrete_type(RangeCheckType::id(), &[])?;
131 let rc_output = OutputVarInfo::new_builtin(range_check_type.clone(), 0);
132 let guarantee_output = OutputVarInfo {
133 ty: context.get_concrete_type(U128MulGuaranteeType::id(), &[])?,
134 ref_info: OutputVarReferenceInfo::SimpleDerefs,
135 };
136 Ok(LibfuncSignature {
137 param_signatures: vec![
138 ParamSignature::new(range_check_type).with_allow_add_const(),
140 ParamSignature::new(u256_ty),
142 ParamSignature::new(nz_ty.clone()),
144 ],
145 branch_signatures: vec![
146 BranchSignature {
148 vars: vec![
149 rc_output.clone(),
150 OutputVarInfo { ty: nz_ty, ref_info: OutputVarReferenceInfo::SimpleDerefs },
151 guarantee_output.clone(),
152 guarantee_output.clone(),
153 guarantee_output.clone(),
154 guarantee_output.clone(),
155 guarantee_output.clone(),
156 guarantee_output.clone(),
157 guarantee_output.clone(),
158 guarantee_output.clone(),
159 ],
160 ap_change: SierraApChange::Known { new_vars_only: false },
161 },
162 BranchSignature {
164 vars: vec![rc_output, guarantee_output.clone(), guarantee_output],
165 ap_change: SierraApChange::Known { new_vars_only: false },
166 },
167 ],
168 fallthrough: Some(0),
169 })
170 }
171}