11use crate :: {
22 crypto:: bn254:: { BN254_G1_SERIALIZED_SIZE , BN254_G2_SERIALIZED_SIZE } ,
33 xdr:: { ScErrorCode , ScErrorType } ,
4- BytesObject , Env , EnvBase , ErrorHandler , Host , HostError , U256Val , U32Val , Compare , { ConversionError , TryFromVal , U256 }
4+ BytesObject , Compare , Env , EnvBase , ErrorHandler , Host , HostError , U256Val , U32Val ,
5+ { ConversionError , TryFromVal , U256 } ,
56} ;
67use ark_bn254:: { Fq , Fq2 , Fr , G1Affine , G2Affine } ;
78use ark_ec:: { AffineRepr , CurveGroup } ;
8- use std:: { ops:: Add , cmp:: Ordering } ;
99use ark_ff:: { BigInteger , PrimeField , UniformRand } ;
1010use ark_serialize:: CanonicalSerialize ;
1111use core:: panic;
1212use rand:: { rngs:: StdRng , SeedableRng } ;
13+ use std:: { cmp:: Ordering , ops:: Add } ;
1314
1415const MODULUS : & str = "0x2523648240000001BA344D80000000086121000000000013A700000000000013" ;
1516
@@ -119,9 +120,7 @@ fn sample_g2_out_of_range(host: &Host, rng: &mut StdRng) -> Result<BytesObject,
119120}
120121
121122fn neg_g2 ( bo : BytesObject , host : & Host ) -> Result < BytesObject , HostError > {
122- let g2 = host. bn254_g2_affine_deserialize (
123- bo,
124- ) ?;
123+ let g2 = host. bn254_g2_affine_deserialize ( bo) ?;
125124 host. bn254_g2_affine_serialize_uncompressed ( & -g2)
126125}
127126
@@ -571,9 +570,7 @@ fn test_serialization_roundtrip() -> Result<(), HostError> {
571570 {
572571 let g2_roundtrip_check = |g2 : & G2Affine | -> Result < bool , HostError > {
573572 let bo = host. bn254_g2_affine_serialize_uncompressed ( & g2) ?;
574- let g2_back = host. bn254_g2_affine_deserialize (
575- bo,
576- ) ?;
573+ let g2_back = host. bn254_g2_affine_deserialize ( bo) ?;
577574 Ok ( g2. eq ( & g2_back) )
578575 } ;
579576 assert ! ( g2_roundtrip_check( & G2Affine :: zero( ) ) ?) ;
@@ -790,4 +787,81 @@ fn g1_vectors() -> Result<(), HostError> {
790787 }
791788
792789 Ok ( ( ) )
793- }
790+ }
791+
792+ // From https://www.evm.codes/precompiled
793+ #[ test]
794+ fn g1_add_mul_hardcoded ( ) -> Result < ( ) , HostError > {
795+ let host = observe_host ! ( Host :: test_host( ) ) ;
796+ host. enable_debug ( ) ?;
797+
798+ let expected_sum = host. test_bin_obj ( & hex:: decode ( "030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd315ed738c0e0a7c92e7845f96b2ae9c0a68a6a449e3538fc7ff3ebf7a5a18a2c4" ) . unwrap ( ) ) ?;
799+
800+ let g_1_2 = "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002" ;
801+
802+ let bytes = hex:: decode ( g_1_2) . unwrap ( ) ;
803+ let g1_bytes = host. test_bin_obj ( & bytes) ?;
804+
805+ // Test g1_add: g1_bytes + g1_bytes
806+ let res_add = host. bn254_g1_add ( g1_bytes, g1_bytes) ?;
807+
808+ assert_eq ! (
809+ ( * host) . compare( & res_add. to_val( ) , & expected_sum. to_val( ) ) ?,
810+ core:: cmp:: Ordering :: Equal
811+ ) ;
812+
813+ // Test g1_mul: g1_bytes * 2
814+ let scalar_2 = U256Val :: from_u32 ( 2 ) ;
815+ let res_mul = host. bn254_g1_mul ( g1_bytes, scalar_2) ?;
816+
817+ assert_eq ! (
818+ ( * host) . compare( & res_mul. to_val( ) , & expected_sum. to_val( ) ) ?,
819+ core:: cmp:: Ordering :: Equal
820+ ) ;
821+
822+ Ok ( ( ) )
823+ }
824+
825+ // From https://www.evm.codes/precompiled
826+ #[ test]
827+ fn g1_pairing_hardcoded ( ) -> Result < ( ) , HostError > {
828+ let host = observe_host ! ( Host :: test_host( ) ) ;
829+ host. enable_debug ( ) ?;
830+
831+ // From Solidity pairing example
832+ // First pairing: e(G1_1, G2_1)
833+ let g1_1_x = "2cf44499d5d27bb186308b7af7af02ac5bc9eeb6a3d147c186b21fb1b76e18da" ;
834+ let g1_1_y = "2c0f001f52110ccfe69108924926e45f0b0c868df0e7bde1fe16d3242dc715f6" ;
835+ let g1_1_bytes = hex:: decode ( format ! ( "{}{}" , g1_1_x, g1_1_y) ) . unwrap ( ) ;
836+ let g1_1 = host. test_bin_obj ( & g1_1_bytes) ?;
837+
838+ let g2_1_x1 = "1fb19bb476f6b9e44e2a32234da8212f61cd63919354bc06aef31e3cfaff3ebc" ;
839+ let g2_1_x0 = "22606845ff186793914e03e21df544c34ffe2f2f3504de8a79d9159eca2d98d9" ;
840+ let g2_1_y1 = "2bd368e28381e8eccb5fa81fc26cf3f048eea9abfdd85d7ed3ab3698d63e4f90" ;
841+ let g2_1_y0 = "2fe02e47887507adf0ff1743cbac6ba291e66f59be6bd763950bb16041a0a85e" ;
842+ let g2_1_bytes = hex:: decode ( format ! ( "{}{}{}{}" , g2_1_x1, g2_1_x0, g2_1_y1, g2_1_y0) ) . unwrap ( ) ;
843+ let g2_1 = host. test_bin_obj ( & g2_1_bytes) ?;
844+
845+ // Second pairing: e(G1_2, G2_2)
846+ let g1_2_x = "0000000000000000000000000000000000000000000000000000000000000001" ;
847+ let g1_2_y = "30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45" ;
848+ let g1_2_bytes = hex:: decode ( format ! ( "{}{}" , g1_2_x, g1_2_y) ) . unwrap ( ) ;
849+ let g1_2 = host. test_bin_obj ( & g1_2_bytes) ?;
850+
851+ let g2_2_x1 = "1971ff0471b09fa93caaf13cbf443c1aede09cc4328f5a62aad45f40ec133eb4" ;
852+ let g2_2_x0 = "091058a3141822985733cbdddfed0fd8d6c104e9e9eff40bf5abfef9ab163bc7" ;
853+ let g2_2_y1 = "2a23af9a5ce2ba2796c1f4e453a370eb0af8c212d9dc9acd8fc02c2e907baea2" ;
854+ let g2_2_y0 = "23a8eb0b0996252cb548a4487da97b02422ebc0e834613f954de6c7e0afdc1fc" ;
855+ let g2_2_bytes = hex:: decode ( format ! ( "{}{}{}{}" , g2_2_x1, g2_2_x0, g2_2_y1, g2_2_y0) ) . unwrap ( ) ;
856+ let g2_2 = host. test_bin_obj ( & g2_2_bytes) ?;
857+
858+ // Test multi pairing check: e(G1_1, G2_1) * e(G1_2, G2_2) == 1
859+ host. budget_ref ( ) . reset_default ( ) ?;
860+ let g1_vec = host. vec_new_from_slice ( & [ g1_1. to_val ( ) , g1_2. to_val ( ) ] ) ?;
861+ let g2_vec = host. vec_new_from_slice ( & [ g2_1. to_val ( ) , g2_2. to_val ( ) ] ) ?;
862+ let res = host. bn254_multi_pairing_check ( g1_vec, g2_vec) ?;
863+
864+ assert ! ( res. as_val( ) . is_true( ) ) ;
865+
866+ Ok ( ( ) )
867+ }
0 commit comments