@@ -96,6 +96,16 @@ static void secp256k1_num_shift(secp256k1_num *r, int bits) {
9696 r -> data [i ] = 0 ;
9797}
9898
99+ SECP256K1_INLINE static int secp256k1_num_is_one (const secp256k1_num * a ) {
100+ int i ;
101+ if (a -> data [0 ] != 1 )
102+ return 0 ;
103+ for (i = 1 ; i < NUM_N_WORDS - 1 ; ++ i )
104+ if (a -> data [i ] != 0 )
105+ return 0 ;
106+ return 1 ;
107+ }
108+
99109SECP256K1_INLINE static int secp256k1_num_is_zero (const secp256k1_num * a ) {
100110 int i ;
101111 for (i = 0 ; i < NUM_N_WORDS - 1 ; ++ i )
@@ -591,4 +601,80 @@ static void secp256k1_num_mod_inverse(secp256k1_num *rr, const secp256k1_num *a,
591601}
592602/* end mod inverse */
593603
604+ /* start jacobi symbol */
605+ /* Compute a number modulo some power of 2 */
606+ SECP256K1_INLINE static int secp256k1_num_mod_2 (const secp256k1_num * a , int m ) {
607+ VERIFY_CHECK (m > 0 );
608+ VERIFY_CHECK ((m & (m - 1 )) == 0 ); /* check that m is a power of 2 */
609+ /* Since our words are powers of 2 we only need to mod the lowest digit */
610+ return a -> data [0 ] % m ;
611+ }
612+
613+ static int secp256k1_num_jacobi_1 (secp256k1_num_word a , secp256k1_num_word b ) {
614+ int ret = 1 ;
615+ secp256k1_num_word t ;
616+ /* Iterate, left-multiplying it by [[0 1] [1 -w]] as many times as we can. */
617+ while (1 ) {
618+ a %= b ;
619+ if (a == 0 )
620+ return 0 ;
621+ if (a % 2 == 0 ) {
622+ int shift = NUM_WORD_CTZ (a );
623+ a >>= shift ;
624+ if ((b % 8 == 3 || b % 8 == 5 ) && shift % 2 == 1 )
625+ ret *= -1 ;
626+ }
627+ if (a == 1 )
628+ break ;
629+ if (b % 4 == 3 && a % 4 == 3 )
630+ ret *= -1 ;
631+ t = a ; a = b ; b = t ;
632+ }
633+ return ret ;
634+ }
635+
636+ /* Compute the Jacobian symbol (a|b) assuming b is an odd prime */
637+ static int secp256k1_num_jacobi (const secp256k1_num * a , const secp256k1_num * b ) {
638+ secp256k1_num top = * a , bot = * b , scratch ;
639+ secp256k1_num_word x , y ;
640+ int index [2 ];
641+ int ret = 1 ;
642+
643+ while (1 ) {
644+ int mod8 = secp256k1_num_mod_2 (& bot , 8 );
645+ secp256k1_num_leading_digit (& x , & index [0 ], & top );
646+ secp256k1_num_leading_digit (& y , & index [1 ], & bot );
647+
648+ if (index [0 ] == 0 && index [1 ] == 0 )
649+ return ret * secp256k1_num_jacobi_1 (x , y );
650+
651+ /* Algorithm from https://en.wikipedia.org/wiki/Jacobi_symbol#Calculating_the_Jacobi_symbol */
652+ secp256k1_num_div_mod (& scratch , & top , & top , & bot ); /* top <- top mod bottom */
653+
654+ /* are we done? */
655+ if (secp256k1_num_is_zero (& top ))
656+ return 0 ;
657+
658+ /* cast out powers of two from the "numerator" */
659+ while (secp256k1_num_mod_2 (& top , 2 ) == 0 ) {
660+ int shift = NUM_WORD_CTZ (top .data [0 ]);
661+ secp256k1_num_shift (& top , shift );
662+ if ((mod8 == 3 || mod8 == 5 ) && shift % 2 == 1 )
663+ ret *= -1 ;
664+ }
665+
666+ /* are we done? */
667+ if (secp256k1_num_is_one (& top ))
668+ return ret ;
669+ /* if not, iterate */
670+ if (mod8 % 4 == 3 && secp256k1_num_mod_2 (& top , 4 ) == 3 )
671+ ret *= -1 ;
672+
673+ scratch = top ;
674+ top = bot ;
675+ bot = scratch ;
676+ }
677+ }
678+ /* end jacobi symbol */
679+
594680#endif
0 commit comments