@@ -868,6 +868,80 @@ impl EnvBackend for EnvInstance {
868868 <H as CryptoHash >:: hash ( enc_input, output)
869869 }
870870
871+ fn bn128_add ( & mut self , x1 : U256 , y1 : U256 , x2 : U256 , y2 : U256 ) -> ( U256 , U256 ) {
872+ const BN128_ADD : [ u8 ; 20 ] =
873+ hex_literal:: hex!( "0000000000000000000000000000000000000006" ) ;
874+
875+ let mut input = [ 0u8 ; 128 ] ;
876+ input[ ..32 ] . copy_from_slice ( & x1. to_big_endian ( ) ) ;
877+ input[ 32 ..64 ] . copy_from_slice ( & y1. to_big_endian ( ) ) ;
878+ input[ 64 ..96 ] . copy_from_slice ( & x2. to_big_endian ( ) ) ;
879+ input[ 96 ..128 ] . copy_from_slice ( & y2. to_big_endian ( ) ) ;
880+
881+ let mut output = [ 0u8 ; 64 ] ;
882+ let _ = ext:: call (
883+ CallFlags :: empty ( ) ,
884+ & BN128_ADD ,
885+ u64:: MAX , // `ref_time` to devote for execution. `u64::MAX` = all
886+ u64:: MAX , // `proof_size` to devote for execution. `u64::MAX` = all
887+ & [ u8:: MAX ; 32 ] , // No deposit limit.
888+ & U256 :: zero ( ) . to_little_endian ( ) , // Value transferred to the contract.
889+ & input[ ..] ,
890+ Some ( & mut & mut output[ ..] ) ,
891+ ) ;
892+ let x3 = U256 :: from_big_endian ( & output[ ..32 ] ) ;
893+ let y3 = U256 :: from_big_endian ( & output[ 32 ..64 ] ) ;
894+ ( x3, y3)
895+ }
896+
897+ fn bn128_mul ( & mut self , x1 : U256 , y1 : U256 , scalar : U256 ) -> ( U256 , U256 ) {
898+ const BN128_ADD : [ u8 ; 20 ] =
899+ hex_literal:: hex!( "0000000000000000000000000000000000000007" ) ;
900+
901+ let mut input = [ 0u8 ; 128 ] ;
902+ input[ ..32 ] . copy_from_slice ( & x1. to_big_endian ( ) ) ;
903+ input[ 32 ..64 ] . copy_from_slice ( & y1. to_big_endian ( ) ) ;
904+ input[ 64 ..96 ] . copy_from_slice ( & scalar. to_big_endian ( ) ) ;
905+
906+ let mut output = [ 0u8 ; 64 ] ;
907+ let _ = ext:: call (
908+ CallFlags :: empty ( ) ,
909+ & BN128_ADD ,
910+ u64:: MAX , // `ref_time` to devote for execution. `u64::MAX` = all
911+ u64:: MAX , // `proof_size` to devote for execution. `u64::MAX` = all
912+ & [ u8:: MAX ; 32 ] , // No deposit limit.
913+ & U256 :: zero ( ) . to_little_endian ( ) , // Value transferred to the contract.
914+ & input[ ..] ,
915+ Some ( & mut & mut output[ ..] ) ,
916+ ) ;
917+ let x2 = U256 :: from_big_endian ( & output[ ..32 ] ) ;
918+ let y2 = U256 :: from_big_endian ( & output[ 32 ..64 ] ) ;
919+ ( x2, y2)
920+ }
921+
922+ fn bn128_pairing ( & mut self , input : & [ u8 ] ) -> bool {
923+ const BN128_ADD : [ u8 ; 20 ] =
924+ hex_literal:: hex!( "0000000000000000000000000000000000000008" ) ;
925+
926+ let mut output = [ 0u8 ; 32 ] ;
927+ let _ = ext:: call (
928+ CallFlags :: empty ( ) ,
929+ & BN128_ADD ,
930+ u64:: MAX , // `ref_time` to devote for execution. `u64::MAX` = all
931+ u64:: MAX , // `proof_size` to devote for execution. `u64::MAX` = all
932+ & [ u8:: MAX ; 32 ] , // No deposit limit.
933+ & U256 :: zero ( ) . to_little_endian ( ) , // Value transferred to the contract.
934+ & input[ ..] ,
935+ Some ( & mut & mut output[ ..] ) ,
936+ ) ;
937+ if output[ 31 ] == 1 {
938+ debug_assert_eq ! ( & output[ ..31 ] , [ 0u8 ; 31 ] ) ;
939+ return true ;
940+ }
941+ debug_assert_eq ! ( & output[ ..32 ] , [ 0u8 ; 32 ] ) ;
942+ false
943+ }
944+
871945 fn ecdsa_recover (
872946 & mut self ,
873947 signature : & [ u8 ; 65 ] ,
0 commit comments