@@ -473,6 +473,8 @@ void test_num_negate(void) {
473473}
474474
475475void test_num_add_sub (void ) {
476+ int i ;
477+ secp256k1_scalar s ;
476478 secp256k1_num n1 ;
477479 secp256k1_num n2 ;
478480 secp256k1_num n1p2 , n2p1 , n1m2 , n2m1 ;
@@ -498,13 +500,119 @@ void test_num_add_sub(void) {
498500 CHECK (!secp256k1_num_eq (& n2p1 , & n1 ));
499501 secp256k1_num_sub (& n2p1 , & n2p1 , & n2 ); /* n2p1 = R2 + R1 - R2 = R1 */
500502 CHECK (secp256k1_num_eq (& n2p1 , & n1 ));
503+
504+ /* check is_one */
505+ secp256k1_scalar_set_int (& s , 1 );
506+ secp256k1_scalar_get_num (& n1 , & s );
507+ CHECK (secp256k1_num_is_one (& n1 ));
508+ /* check that 2^n + 1 is never 1 */
509+ secp256k1_scalar_get_num (& n2 , & s );
510+ for (i = 0 ; i < 250 ; ++ i ) {
511+ secp256k1_num_add (& n1 , & n1 , & n1 ); /* n1 *= 2 */
512+ secp256k1_num_add (& n1p2 , & n1 , & n2 ); /* n1p2 = n1 + 1 */
513+ CHECK (!secp256k1_num_is_one (& n1p2 ));
514+ }
515+ }
516+
517+ void test_num_mod (void ) {
518+ int i ;
519+ secp256k1_scalar s ;
520+ secp256k1_num order , n ;
521+
522+ /* check that 0 mod anything is 0 */
523+ random_scalar_order_test (& s );
524+ secp256k1_scalar_get_num (& order , & s );
525+ secp256k1_scalar_set_int (& s , 0 );
526+ secp256k1_scalar_get_num (& n , & s );
527+ secp256k1_num_mod (& n , & order );
528+ CHECK (secp256k1_num_is_zero (& n ));
529+
530+ /* check that anything mod 1 is 0 */
531+ secp256k1_scalar_set_int (& s , 1 );
532+ secp256k1_scalar_get_num (& order , & s );
533+ secp256k1_scalar_get_num (& n , & s );
534+ secp256k1_num_mod (& n , & order );
535+ CHECK (secp256k1_num_is_zero (& n ));
536+
537+ /* check that increasing the number past 2^256 does not break this */
538+ random_scalar_order_test (& s );
539+ secp256k1_scalar_get_num (& n , & s );
540+ /* multiply by 2^8, which'll test this case with high probability */
541+ for (i = 0 ; i < 8 ; ++ i ) {
542+ secp256k1_num_add (& n , & n , & n );
543+ }
544+ secp256k1_num_mod (& n , & order );
545+ CHECK (secp256k1_num_is_zero (& n ));
546+ }
547+
548+ void test_num_jacobi (void ) {
549+ secp256k1_scalar sqr ;
550+ secp256k1_scalar small ;
551+ secp256k1_scalar five ; /* five is not a quadratic residue */
552+ secp256k1_num order , n ;
553+ int i ;
554+ /* squares mod 5 are 1, 4 */
555+ const int jacobi5 [10 ] = { 0 , 1 , -1 , -1 , 1 , 0 , 1 , -1 , -1 , 1 };
556+
557+ /* check some small values with 5 as the order */
558+ secp256k1_scalar_set_int (& five , 5 );
559+ secp256k1_scalar_get_num (& order , & five );
560+ for (i = 0 ; i < 10 ; ++ i ) {
561+ secp256k1_scalar_set_int (& small , i );
562+ secp256k1_scalar_get_num (& n , & small );
563+ CHECK (secp256k1_num_jacobi (& n , & order ) == jacobi5 [i ]);
564+ }
565+
566+ /** test large values with 5 as group order */
567+ secp256k1_scalar_get_num (& order , & five );
568+ /* we first need a scalar which is not a multiple of 5 */
569+ do {
570+ secp256k1_num fiven ;
571+ random_scalar_order_test (& sqr );
572+ secp256k1_scalar_get_num (& fiven , & five );
573+ secp256k1_scalar_get_num (& n , & sqr );
574+ secp256k1_num_mod (& n , & fiven );
575+ } while (secp256k1_num_is_zero (& n ));
576+ /* next force it to be a residue. 2 is a nonresidue mod 5 so we can
577+ * just multiply by two, i.e. add the number to itself */
578+ if (secp256k1_num_jacobi (& n , & order ) == -1 ) {
579+ secp256k1_num_add (& n , & n , & n );
580+ }
581+
582+ /* test residue */
583+ CHECK (secp256k1_num_jacobi (& n , & order ) == 1 );
584+ /* test nonresidue */
585+ secp256k1_num_add (& n , & n , & n );
586+ CHECK (secp256k1_num_jacobi (& n , & order ) == -1 );
587+
588+ /** test with secp group order as order */
589+ secp256k1_scalar_order_get_num (& order );
590+ random_scalar_order_test (& sqr );
591+ secp256k1_scalar_sqr (& sqr , & sqr );
592+ /* test residue */
593+ secp256k1_scalar_get_num (& n , & sqr );
594+ CHECK (secp256k1_num_jacobi (& n , & order ) == 1 );
595+ /* test nonresidue */
596+ secp256k1_scalar_mul (& sqr , & sqr , & five );
597+ secp256k1_scalar_get_num (& n , & sqr );
598+ CHECK (secp256k1_num_jacobi (& n , & order ) == -1 );
599+ /* test multiple of the order*/
600+ CHECK (secp256k1_num_jacobi (& order , & order ) == 0 );
601+
602+ /* check one less than the order */
603+ secp256k1_scalar_set_int (& small , 1 );
604+ secp256k1_scalar_get_num (& n , & small );
605+ secp256k1_num_sub (& n , & order , & n );
606+ CHECK (secp256k1_num_jacobi (& n , & order ) == 1 ); /* sage confirms this is 1 */
501607}
502608
503609void run_num_smalltests (void ) {
504610 int i ;
505611 for (i = 0 ; i < 100 * count ; i ++ ) {
506612 test_num_negate ();
507613 test_num_add_sub ();
614+ test_num_mod ();
615+ test_num_jacobi ();
508616 }
509617}
510618#endif
@@ -689,6 +797,10 @@ void scalar_test(void) {
689797 secp256k1_scalar_inverse (& inv , & inv );
690798 /* Inverting one must result in one. */
691799 CHECK (secp256k1_scalar_is_one (& inv ));
800+ #ifndef USE_NUM_NONE
801+ secp256k1_scalar_get_num (& invnum , & inv );
802+ CHECK (secp256k1_num_is_one (& invnum ));
803+ #endif
692804 }
693805 }
694806
@@ -2067,9 +2179,10 @@ void run_ec_combine(void) {
20672179void test_group_decompress (const secp256k1_fe * x ) {
20682180 /* The input itself, normalized. */
20692181 secp256k1_fe fex = * x ;
2070- secp256k1_fe tmp ;
2182+ secp256k1_fe fez ;
20712183 /* Results of set_xquad_var, set_xo_var(..., 0), set_xo_var(..., 1). */
20722184 secp256k1_ge ge_quad , ge_even , ge_odd ;
2185+ secp256k1_gej gej_quad ;
20732186 /* Return values of the above calls. */
20742187 int res_quad , res_even , res_odd ;
20752188
@@ -2101,13 +2214,29 @@ void test_group_decompress(const secp256k1_fe* x) {
21012214 CHECK (secp256k1_fe_equal_var (& ge_odd .x , x ));
21022215
21032216 /* Check that the Y coordinate result in ge_quad is a square. */
2104- CHECK (secp256k1_fe_sqrt_var (& tmp , & ge_quad .y ));
2105- secp256k1_fe_sqr (& tmp , & tmp );
2106- CHECK (secp256k1_fe_equal_var (& tmp , & ge_quad .y ));
2217+ CHECK (secp256k1_fe_is_quad_var (& ge_quad .y ));
21072218
21082219 /* Check odd/even Y in ge_odd, ge_even. */
21092220 CHECK (secp256k1_fe_is_odd (& ge_odd .y ));
21102221 CHECK (!secp256k1_fe_is_odd (& ge_even .y ));
2222+
2223+ /* Check secp256k1_gej_has_quad_y_var. */
2224+ secp256k1_gej_set_ge (& gej_quad , & ge_quad );
2225+ CHECK (secp256k1_gej_has_quad_y_var (& gej_quad ));
2226+ do {
2227+ random_fe_test (& fez );
2228+ } while (secp256k1_fe_is_zero (& fez ));
2229+ secp256k1_gej_rescale (& gej_quad , & fez );
2230+ CHECK (secp256k1_gej_has_quad_y_var (& gej_quad ));
2231+ secp256k1_gej_neg (& gej_quad , & gej_quad );
2232+ CHECK (!secp256k1_gej_has_quad_y_var (& gej_quad ));
2233+ do {
2234+ random_fe_test (& fez );
2235+ } while (secp256k1_fe_is_zero (& fez ));
2236+ secp256k1_gej_rescale (& gej_quad , & fez );
2237+ CHECK (!secp256k1_gej_has_quad_y_var (& gej_quad ));
2238+ secp256k1_gej_neg (& gej_quad , & gej_quad );
2239+ CHECK (secp256k1_gej_has_quad_y_var (& gej_quad ));
21112240 }
21122241}
21132242
0 commit comments