@@ -46,7 +46,8 @@ enum RuntimeBinding {
4646 DictDup ,
4747 GetCostsBuiltin ,
4848 DebugPrint ,
49- ExtendedEuclideanAlgorithm ,
49+ Felt252ExtendedEuclideanAlgorithm ,
50+ CircuitExtendedEuclideanAlgorithm ,
5051 CircuitArithOperation ,
5152 #[ cfg( feature = "with-cheatcode" ) ]
5253 VtableCheatcode ,
@@ -72,8 +73,11 @@ impl RuntimeBinding {
7273 RuntimeBinding :: DictDrop => "cairo_native__dict_drop" ,
7374 RuntimeBinding :: DictDup => "cairo_native__dict_dup" ,
7475 RuntimeBinding :: GetCostsBuiltin => "cairo_native__get_costs_builtin" ,
75- RuntimeBinding :: ExtendedEuclideanAlgorithm => {
76- "cairo_native__extended_euclidean_algorithm"
76+ RuntimeBinding :: Felt252ExtendedEuclideanAlgorithm => {
77+ "cairo_native__felt252_extended_euclidean_algorithm"
78+ }
79+ RuntimeBinding :: CircuitExtendedEuclideanAlgorithm => {
80+ "cairo_native__circuit_extended_euclidean_algorithm"
7781 }
7882 RuntimeBinding :: CircuitArithOperation => "cairo_native__circuit_arith_operation" ,
7983 #[ cfg( feature = "with-cheatcode" ) ]
@@ -124,7 +128,8 @@ impl RuntimeBinding {
124128 RuntimeBinding :: GetCostsBuiltin => {
125129 crate :: runtime:: cairo_native__get_costs_builtin as * const ( )
126130 }
127- RuntimeBinding :: ExtendedEuclideanAlgorithm => return None ,
131+ RuntimeBinding :: Felt252ExtendedEuclideanAlgorithm
132+ | RuntimeBinding :: CircuitExtendedEuclideanAlgorithm => return None ,
128133 RuntimeBinding :: CircuitArithOperation => return None ,
129134 #[ cfg( feature = "with-cheatcode" ) ]
130135 RuntimeBinding :: VtableCheatcode => {
@@ -202,23 +207,66 @@ impl RuntimeBindingsMeta {
202207 /// After checking, calls the MLIR function with arguments `a` and `b` which are the initial remainders
203208 /// used in the algorithm and returns a `Value` containing a struct where the first element is the
204209 /// greatest common divisor of `a` and `b` and the second element is the bezout coefficient x.
205- pub fn extended_euclidean_algorithm < ' c , ' a > (
210+ ///
211+ /// This implementation is only for felt252, which uses u252 integers.
212+ pub fn felt252_extended_euclidean_algorithm < ' c , ' a > (
213+ & mut self ,
214+ context : & ' c Context ,
215+ module : & Module ,
216+ block : & ' a Block < ' c > ,
217+ location : Location < ' c > ,
218+ a : Value < ' c , ' _ > ,
219+ b : Value < ' c , ' _ > ,
220+ ) -> Result < Value < ' c , ' a > >
221+ where
222+ ' c : ' a ,
223+ {
224+ let integer_type = IntegerType :: new ( context, 512 ) . into ( ) ;
225+ let func_symbol = RuntimeBinding :: Felt252ExtendedEuclideanAlgorithm . symbol ( ) ;
226+ if self
227+ . active_map
228+ . insert ( RuntimeBinding :: Felt252ExtendedEuclideanAlgorithm )
229+ {
230+ build_egcd_function ( module, context, location, func_symbol, integer_type) ?;
231+ }
232+ // The struct returned by the function that contains both of the results
233+ let return_type = llvm:: r#type:: r#struct ( context, & [ integer_type, integer_type] , false ) ;
234+ Ok ( block
235+ . append_operation (
236+ OperationBuilder :: new ( "llvm.call" , location)
237+ . add_attributes ( & [ (
238+ Identifier :: new ( context, "callee" ) ,
239+ FlatSymbolRefAttribute :: new ( context, func_symbol) . into ( ) ,
240+ ) ] )
241+ . add_operands ( & [ a, b] )
242+ . add_results ( & [ return_type] )
243+ . build ( ) ?,
244+ )
245+ . result ( 0 ) ?
246+ . into ( ) )
247+ }
248+
249+ /// Similar to [felt252_extended_euclidean_algorithm](Self::felt252_extended_euclidean_algorithm).
250+ ///
251+ /// The difference with the other is that this function is meant to be used
252+ /// with circuits, which use u384 integers.
253+ pub fn circuit_extended_euclidean_algorithm < ' c , ' a > (
206254 & mut self ,
207255 context : & ' c Context ,
208256 module : & Module ,
209257 block : & ' a Block < ' c > ,
210258 location : Location < ' c > ,
211259 a : Value < ' c , ' _ > ,
212260 b : Value < ' c , ' _ > ,
213- integer_type : Type < ' c >
214261 ) -> Result < Value < ' c , ' a > >
215262 where
216263 ' c : ' a ,
217264 {
218- let func_symbol = RuntimeBinding :: ExtendedEuclideanAlgorithm . symbol ( ) ;
265+ let integer_type = IntegerType :: new ( context, 512 ) . into ( ) ;
266+ let func_symbol = RuntimeBinding :: CircuitExtendedEuclideanAlgorithm . symbol ( ) ;
219267 if self
220268 . active_map
221- . insert ( RuntimeBinding :: ExtendedEuclideanAlgorithm )
269+ . insert ( RuntimeBinding :: CircuitExtendedEuclideanAlgorithm )
222270 {
223271 build_egcd_function ( module, context, location, func_symbol, integer_type) ?;
224272 }
0 commit comments