/src/botan/src/lib/math/numbertheory/jacobi.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Jacobi Function |
3 | | * (C) 1999-2007 Jack Lloyd |
4 | | * |
5 | | * Botan is released under the Simplified BSD License (see license.txt) |
6 | | */ |
7 | | |
8 | | #include <botan/numthry.h> |
9 | | |
10 | | namespace Botan { |
11 | | |
12 | | /* |
13 | | * Calculate the Jacobi symbol |
14 | | */ |
15 | | int32_t jacobi(const BigInt& a, const BigInt& n) |
16 | 37.0k | { |
17 | 37.0k | if(n.is_even() || n < 2) |
18 | 0 | throw Invalid_Argument("jacobi: second argument must be odd and > 1"); |
19 | 37.0k | |
20 | 37.0k | BigInt x = a % n; |
21 | 37.0k | BigInt y = n; |
22 | 37.0k | int32_t J = 1; |
23 | 37.0k | |
24 | 2.62M | while(y > 1) |
25 | 2.58M | { |
26 | 2.58M | x %= y; |
27 | 2.58M | if(x > y / 2) |
28 | 1.20M | { |
29 | 1.20M | x = y - x; |
30 | 1.20M | if(y % 4 == 3) |
31 | 590k | J = -J; |
32 | 1.20M | } |
33 | 2.58M | if(x.is_zero()) |
34 | 0 | return 0; |
35 | 2.58M | |
36 | 2.58M | size_t shifts = low_zero_bits(x); |
37 | 2.58M | x >>= shifts; |
38 | 2.58M | if(shifts % 2) |
39 | 828k | { |
40 | 828k | word y_mod_8 = y % 8; |
41 | 828k | if(y_mod_8 == 3 || y_mod_8 == 5) |
42 | 418k | J = -J; |
43 | 828k | } |
44 | 2.58M | |
45 | 2.58M | if(x % 4 == 3 && y % 4 == 3) |
46 | 612k | J = -J; |
47 | 2.58M | std::swap(x, y); |
48 | 2.58M | } |
49 | 37.0k | return J; |
50 | 37.0k | } |
51 | | |
52 | | } |