@@ -591,384 +591,10 @@ macro_rules! test_field {
591591#[ doc( hidden) ]
592592macro_rules! __test_small_field {
593593 ( $field: ty) => {
594- #[ test]
595- pub fn test_frobenius( ) {
596- use ark_ff:: Field ;
597- use ark_std:: UniformRand ;
598- let mut rng = ark_std:: test_rng( ) ;
599- let characteristic = <$field>:: characteristic( ) ;
600- let max_power = ( <$field>:: extension_degree( ) + 1 ) as usize ;
601-
602- for _ in 0 ..ITERATIONS {
603- let a = <$field>:: rand( & mut rng) ;
604-
605- let mut a_0 = a;
606- a_0. frobenius_map_in_place( 0 ) ;
607- assert_eq!( a, a_0) ;
608- assert_eq!( a, a. frobenius_map( 0 ) ) ;
609-
610- let mut a_q = a. pow( & characteristic) ;
611- for power in 1 ..max_power {
612- assert_eq!( a_q, a. frobenius_map( power) ) ;
613-
614- let mut a_qi = a;
615- a_qi. frobenius_map_in_place( power) ;
616- assert_eq!( a_qi, a_q, "failed on power {}" , power) ;
617-
618- a_q = a_q. pow( & characteristic) ;
619- }
620- }
621- }
622-
623- #[ test]
624- fn test_serialization( ) {
625- use ark_serialize:: * ;
626- use ark_std:: UniformRand ;
627- for compress in [ Compress :: Yes , Compress :: No ] {
628- for validate in [ Validate :: Yes , Validate :: No ] {
629- let buf_size = <$field>:: zero( ) . serialized_size( compress) ;
630-
631- let buffer_size =
632- buffer_bit_byte_size( <$field as Field >:: BasePrimeField :: MODULUS_BIT_SIZE as usize ) . 1 *
633- ( <$field>:: extension_degree( ) as usize ) ;
634- assert_eq!( buffer_size, buf_size) ;
635-
636- let mut rng = ark_std:: test_rng( ) ;
637-
638- for _ in 0 ..ITERATIONS {
639- let a = <$field>:: rand( & mut rng) ;
640- {
641- let mut serialized = vec![ 0u8 ; buf_size] ;
642- let mut cursor = Cursor :: new( & mut serialized[ ..] ) ;
643- a. serialize_with_mode( & mut cursor, compress) . unwrap( ) ;
644-
645- let mut cursor = Cursor :: new( & serialized[ ..] ) ;
646- let b = <$field>:: deserialize_with_mode( & mut cursor, compress, validate) . unwrap( ) ;
647- assert_eq!( a, b) ;
648- }
649-
650- {
651- let mut serialized = vec![ 0 ; buf_size] ;
652- let result = matches!(
653- a. serialize_with_flags( & mut & mut serialized[ ..] , $crate:: fields:: DummyFlags ) . unwrap_err( ) ,
654- SerializationError :: NotEnoughSpace
655- ) ;
656- assert!( result) ;
657-
658- let result = matches!(
659- <$field>:: deserialize_with_flags:: <_, $crate:: fields:: DummyFlags >( & mut & serialized[ ..] ) . unwrap_err( ) ,
660- SerializationError :: NotEnoughSpace ,
661- ) ;
662- assert!( result) ;
663-
664- {
665- let mut serialized = vec![ 0 ; buf_size - 1 ] ;
666- let mut cursor = Cursor :: new( & mut serialized[ ..] ) ;
667- a. serialize_with_mode( & mut cursor, compress) . unwrap_err( ) ;
668-
669- let mut cursor = Cursor :: new( & serialized[ ..] ) ;
670- <$field>:: deserialize_with_mode( & mut cursor, compress, validate) . unwrap_err( ) ;
671- }
672- }
673- }
674- }
675- }
676-
677- }
678-
679- #[ test]
680- fn test_add_properties( ) {
681- use ark_ff:: AdditiveGroup ;
682- use ark_std:: UniformRand ;
683-
684- let mut rng = test_rng( ) ;
685- let zero = <$field>:: zero( ) ;
686- assert_eq!( -zero, zero) ;
687- assert!( zero. is_zero( ) ) ;
688- assert!( <$field>:: ZERO . is_zero( ) ) ;
689- assert_eq!( <$field>:: ZERO , zero) ;
690-
691- for _ in 0 ..( ITERATIONS * ITERATIONS ) {
692- // Generate small values that are guaranteed to be within the modulus
693- // Using u16 range ensures compatibility with small fields like M31
694- let a = <$field>:: rand( & mut rng) ;
695- let b = <$field>:: rand( & mut rng) ;
696- let c = <$field>:: rand( & mut rng) ;
697- assert_eq!( ( a + b) + c, a + ( b + c) ) ;
698-
699- // Commutativity
700- assert_eq!( a + b, b + a) ;
701-
702- // Identity
703- assert_eq!( zero + a, a) ;
704- assert_eq!( zero + b, b) ;
705- assert_eq!( zero + c, c) ;
706-
707- // Negation
708- assert_eq!( -a + a, zero) ;
709- assert_eq!( -b + b, zero) ;
710- assert_eq!( -c + c, zero) ;
711- assert_eq!( -zero, zero) ;
712-
713- // Associativity and commutativity simultaneously
714- let t0 = ( a + & b) + & c; // (a + b) + c
715- let t1 = ( a + & c) + & b; // (a + c) + b
716- let t2 = ( b + & c) + & a; // (b + c) + a
717-
718- assert_eq!( t0, t1) ;
719- assert_eq!( t1, t2) ;
720-
721- // Doubling
722- assert_eq!( a. double( ) , a + a) ;
723- assert_eq!( b. double( ) , b + b) ;
724- assert_eq!( c. double( ) , c + c) ;
725- }
726- }
727-
728- #[ test]
729- fn test_sub_properties( ) {
730- use ark_std:: UniformRand ;
731- let mut rng = test_rng( ) ;
732- let zero = <$field>:: zero( ) ;
733-
734- for _ in 0 ..( ITERATIONS * ITERATIONS ) {
735- // Anti-commutativity
736- let a = <$field>:: rand( & mut rng) ;
737- let b = <$field>:: rand( & mut rng) ;
738- assert!( ( ( a - b) + ( b - a) ) . is_zero( ) ) ;
739-
740- // Identity
741- assert_eq!( zero - a, -a) ;
742- assert_eq!( zero - b, -b) ;
743-
744- assert_eq!( a - zero, a) ;
745- assert_eq!( b - zero, b) ;
746- }
747- }
748-
749- #[ test]
750- fn test_mul_properties( ) {
751- use ark_std:: UniformRand ;
752- let mut rng = test_rng( ) ;
753- let zero = <$field>:: zero( ) ;
754- let one = <$field>:: one( ) ;
755- let minus_one = <$field>:: NEG_ONE ;
756- assert_eq!( one. inverse( ) . unwrap( ) , one, "One inverse failed" ) ;
757- assert!( one. is_one( ) , "One is not one" ) ;
758-
759- assert!( <$field>:: ONE . is_one( ) , "One constant is not one" ) ;
760- assert_eq!( <$field>:: ONE , one, "One constant is incorrect" ) ;
761- assert_eq!( <$field>:: NEG_ONE , -one, "NEG_ONE constant is incorrect" ) ;
762- assert_eq!( <$field>:: ONE + <$field>:: NEG_ONE , zero, "1 + -1 neq 0" ) ;
763-
764- for _ in 0 ..ITERATIONS {
765- // Associativity
766- let a = <$field>:: rand( & mut rng) ;
767- let b = <$field>:: rand( & mut rng) ;
768- let c = <$field>:: rand( & mut rng) ;
769- assert_eq!( ( a * b) * c, a * ( b * c) , "Associativity failed" ) ;
770-
771- // Commutativity
772- assert_eq!( a * b, b * a, "Commutativity failed" ) ;
773-
774- // Identity
775- assert_eq!( one * a, a, "Identity mul failed" ) ;
776- assert_eq!( one * b, b, "Identity mul failed" ) ;
777- assert_eq!( one * c, c, "Identity mul failed" ) ;
778- assert_eq!( minus_one * c, -c, "NEG_ONE mul failed" ) ;
779-
780- assert_eq!( zero * a, zero, "Mul by zero failed" ) ;
781- assert_eq!( zero * b, zero, "Mul by zero failed" ) ;
782- assert_eq!( zero * c, zero, "Mul by zero failed" ) ;
783-
784- // Inverses
785- assert_eq!( a * a. inverse( ) . unwrap( ) , one, "Mul by inverse failed" ) ;
786- assert_eq!( b * b. inverse( ) . unwrap( ) , one, "Mul by inverse failed" ) ;
787- assert_eq!( c * c. inverse( ) . unwrap( ) , one, "Mul by inverse failed" ) ;
788-
789- // Associativity and commutativity simultaneously
790- let t0 = ( a * b) * c;
791- let t1 = ( a * c) * b;
792- let t2 = ( b * c) * a;
793- assert_eq!( t0, t1, "Associativity + commutativity failed" ) ;
794- assert_eq!( t1, t2, "Associativity + commutativity failed" ) ;
795-
796- // Squaring
797- assert_eq!( a * a, a. square( ) , "Squaring failed" ) ;
798- assert_eq!( b * b, b. square( ) , "Squaring failed" ) ;
799- assert_eq!( c * c, c. square( ) , "Squaring failed" ) ;
800-
801- // Distributivity
802- assert_eq!( a * ( b + c) , a * b + a * c, "Distributivity failed" ) ;
803- assert_eq!( b * ( a + c) , b * a + b * c, "Distributivity failed" ) ;
804- assert_eq!( c * ( a + b) , c * a + c * b, "Distributivity failed" ) ;
805- assert_eq!(
806- ( a + b) . square( ) ,
807- a. square( ) + b. square( ) + a * ark_ff:: AdditiveGroup :: double( & b) ,
808- "Distributivity for square failed"
809- ) ;
810- assert_eq!(
811- ( b + c) . square( ) ,
812- c. square( ) + b. square( ) + c * ark_ff:: AdditiveGroup :: double( & b) ,
813- "Distributivity for square failed"
814- ) ;
815- assert_eq!(
816- ( c + a) . square( ) ,
817- a. square( ) + c. square( ) + a * ark_ff:: AdditiveGroup :: double( & c) ,
818- "Distributivity for square failed"
819- ) ;
820- }
821- }
822-
823- #[ test]
824- fn test_pow( ) {
825- use ark_std:: UniformRand ;
826- let mut rng = test_rng( ) ;
827- for _ in 0 ..( ITERATIONS / 10 ) {
828- for i in 0 ..20 {
829- // Exponentiate by various small numbers and ensure it is
830- // consistent with repeated multiplication.
831- let a = <$field>:: rand( & mut rng) ;
832- let target = a. pow( & [ i] ) ;
833- let mut c = <$field>:: one( ) ;
834- for _ in 0 ..i {
835- c *= a;
836- }
837- assert_eq!( c, target) ;
838- }
839- let a = <$field>:: rand( & mut rng) ;
840-
841- // Exponentiating by the modulus should have no effect;
842- let mut result = a;
843- for i in 0 ..<$field>:: extension_degree( ) {
844- result = result. pow( <$field>:: characteristic( ) )
845- }
846- assert_eq!( a, result) ;
847-
848- // Commutativity
849- let e1: [ u64 ; 10 ] = rng. gen ( ) ;
850- let e2: [ u64 ; 10 ] = rng. gen ( ) ;
851- assert_eq!( a. pow( & e1) . pow( & e2) , a. pow( & e2) . pow( & e1) ) ;
852-
853- // Distributivity
854- let e3: [ u64 ; 10 ] = rng. gen ( ) ;
855- let a_to_e1 = a. pow( e1) ;
856- let a_to_e2 = a. pow( e2) ;
857- let a_to_e1_plus_e2 = a. pow( e1) * a. pow( e2) ;
858- assert_eq!(
859- a_to_e1_plus_e2. pow( & e3) ,
860- a_to_e1. pow( & e3) * a_to_e2. pow( & e3)
861- ) ;
862- }
863- }
864-
865- #[ test]
866- fn test_sum_of_products_tests( ) {
867- use ark_std:: { rand:: Rng , UniformRand } ;
868- let rng = & mut test_rng( ) ;
869-
870- for _ in 0 ..ITERATIONS {
871- $crate:: fields:: sum_of_products_test_helper:: <$field, 1 >( rng) ;
872- $crate:: fields:: sum_of_products_test_helper:: <$field, 2 >( rng) ;
873- $crate:: fields:: sum_of_products_test_helper:: <$field, 3 >( rng) ;
874- $crate:: fields:: sum_of_products_test_helper:: <$field, 4 >( rng) ;
875- $crate:: fields:: sum_of_products_test_helper:: <$field, 5 >( rng) ;
876- $crate:: fields:: sum_of_products_test_helper:: <$field, 6 >( rng) ;
877- $crate:: fields:: sum_of_products_test_helper:: <$field, 7 >( rng) ;
878- $crate:: fields:: sum_of_products_test_helper:: <$field, 8 >( rng) ;
879- $crate:: fields:: sum_of_products_test_helper:: <$field, 9 >( rng) ;
880- $crate:: fields:: sum_of_products_test_helper:: <$field, 10 >( rng) ;
881- }
882- }
883-
884- #[ test]
885- fn test_sqrt( ) {
886- if <$field>:: SQRT_PRECOMP . is_some( ) {
887- use ark_std:: UniformRand ;
888- let rng = & mut test_rng( ) ;
889-
890- assert!( <$field>:: zero( ) . sqrt( ) . unwrap( ) . is_zero( ) ) ;
891-
892- for _ in 0 ..ITERATIONS {
893- // Ensure sqrt(a^2) = a or -a
894- let a = <$field>:: rand( rng) ;
895- let b = a. square( ) ;
896- let sqrt = b. sqrt( ) . unwrap( ) ;
897- assert!( a == sqrt || -a == sqrt) ;
898-
899- if let Some ( mut b) = a. sqrt( ) {
900- b. square_in_place( ) ;
901- assert_eq!( a, b) ;
902- }
903-
904- let a = <$field>:: rand( rng) ;
905- let b = a. square( ) ;
906- assert_eq!( b. legendre( ) , LegendreSymbol :: QuadraticResidue ) ;
907- }
908- }
909- }
910-
911- #[ test]
912- fn test_mul_by_base_field_elem( ) {
913- use ark_std:: UniformRand ;
914- let rng = & mut test_rng( ) ;
915-
916- for _ in 0 ..ITERATIONS {
917- let a = vec![
918- <<$field as Field >:: BasePrimeField >:: rand( rng) ;
919- <$field>:: extension_degree( ) as usize
920- ] ;
921- let b = <<$field as Field >:: BasePrimeField >:: rand( rng) ;
922-
923- let mut a = <$field>:: from_base_prime_field_elems( a) . unwrap( ) ;
924- let computed = a. mul_by_base_prime_field( & b) ;
925-
926- let embedded_b = <$field as Field >:: from_base_prime_field( b) ;
927-
928- let naive = a * embedded_b;
929-
930- assert_eq!( computed, naive) ;
931- }
932- }
933- #[ test]
934- fn test_fft( ) {
935- use ark_ff:: FftField ;
936- use $crate:: num_bigint:: BigUint ;
937-
938- let two_pow_2_adicity = BigUint :: from( 1_u8 ) << <$field>:: TWO_ADICITY as u32 ;
939- assert_eq!(
940- <$field>:: TWO_ADIC_ROOT_OF_UNITY . pow( two_pow_2_adicity. to_u64_digits( ) ) ,
941- <$field>:: one( )
942- ) ;
943-
944- if let Some ( small_subgroup_base) = <$field>:: SMALL_SUBGROUP_BASE {
945- let small_subgroup_base_adicity = <$field>:: SMALL_SUBGROUP_BASE_ADICITY . unwrap( ) ;
946- let large_subgroup_root_of_unity = <$field>:: LARGE_SUBGROUP_ROOT_OF_UNITY . unwrap( ) ;
947- let pow = <$field>:: from( two_pow_2_adicity)
948- * <$field>:: from( small_subgroup_base as u64 )
949- . pow( [ small_subgroup_base_adicity as u64 ] ) ;
950- assert_eq!(
951- large_subgroup_root_of_unity. pow( pow. into_bigint( ) ) ,
952- <$field>:: one( )
953- ) ;
954-
955- for i in 0 ..=<$field>:: TWO_ADICITY {
956- for j in 0 ..=small_subgroup_base_adicity {
957- let size = ( 1u64 << i) * ( small_subgroup_base as u64 ) . pow( j) ;
958- let root = <$field>:: get_root_of_unity( size as u64 ) . unwrap( ) ;
959- assert_eq!( root. pow( [ size as u64 ] ) , <$field>:: one( ) ) ;
960- }
961- }
962- } else {
963- for i in 0 ..=<$field>:: TWO_ADICITY {
964- let size = BigUint :: from( 1_u8 ) << i;
965- let root = <$field>:: get_root_of_unity_big_int( size. clone( ) ) . unwrap( ) ;
966- assert_eq!( root. pow( size. to_u64_digits( ) ) , <$field>:: one( ) ) ;
967- }
968- }
969- }
970-
594+ // Common field tests plus FFT tests
595+ $crate:: __test_field!( $field; fft) ;
971596
597+ // Constants test for prime field as above
972598 #[ test]
973599 fn test_constants( ) {
974600 use ark_ff:: { FpConfig , BigInteger , SqrtPrecomputation } ;
0 commit comments