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![
107 OutputVarInfo::new_builtin(range_check_type, 0),
108 OutputVarInfo {
109 ty: context.get_concrete_type(Uint128Type::id(), &[])?,
110 ref_info: OutputVarReferenceInfo::SimpleDerefs,
111 },
112 ],
113 SierraApChange::Known { new_vars_only: false },
114 ))
115 }
116}
117
118#[derive(Default)]
123pub struct Uint256InvModNLibfunc;
124impl NoGenericArgsGenericLibfunc for Uint256InvModNLibfunc {
125 const STR_ID: &'static str = "u256_guarantee_inv_mod_n";
126
127 fn specialize_signature(
128 &self,
129 context: &dyn SignatureSpecializationContext,
130 ) -> Result<LibfuncSignature, SpecializationError> {
131 let u256_ty = get_u256_type(context)?;
132 let nz_ty = nonzero_ty(context, &u256_ty)?;
133 let range_check_type = context.get_concrete_type(RangeCheckType::id(), &[])?;
134 let rc_output = OutputVarInfo::new_builtin(range_check_type.clone(), 0);
135 let guarantee_output = OutputVarInfo {
136 ty: context.get_concrete_type(U128MulGuaranteeType::id(), &[])?,
137 ref_info: OutputVarReferenceInfo::SimpleDerefs,
138 };
139 Ok(LibfuncSignature {
140 param_signatures: vec![
141 ParamSignature::new(range_check_type).with_allow_add_const(),
143 ParamSignature::new(u256_ty),
145 ParamSignature::new(nz_ty.clone()),
147 ],
148 branch_signatures: vec![
149 BranchSignature {
151 vars: vec![
152 rc_output.clone(),
153 OutputVarInfo { ty: nz_ty, ref_info: OutputVarReferenceInfo::SimpleDerefs },
154 guarantee_output.clone(),
155 guarantee_output.clone(),
156 guarantee_output.clone(),
157 guarantee_output.clone(),
158 guarantee_output.clone(),
159 guarantee_output.clone(),
160 guarantee_output.clone(),
161 guarantee_output.clone(),
162 ],
163 ap_change: SierraApChange::Known { new_vars_only: false },
164 },
165 BranchSignature {
167 vars: vec![rc_output, guarantee_output.clone(), guarantee_output],
168 ap_change: SierraApChange::Known { new_vars_only: false },
169 },
170 ],
171 fallthrough: Some(0),
172 })
173 }
174}