diff options
author | lloyd <[email protected]> | 2006-05-18 18:33:19 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2006-05-18 18:33:19 +0000 |
commit | a2c99d3270eb73ef2db5704fc54356c6b75096f8 (patch) | |
tree | ad3d6c4fcc8dd0f403f8105598943616246fe172 /src/jacobi.cpp |
Initial checkin1.5.6
Diffstat (limited to 'src/jacobi.cpp')
-rw-r--r-- | src/jacobi.cpp | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/src/jacobi.cpp b/src/jacobi.cpp new file mode 100644 index 000000000..4e8ab61f0 --- /dev/null +++ b/src/jacobi.cpp @@ -0,0 +1,51 @@ +/************************************************* +* Jacobi Function Source File * +* (C) 1999-2006 The Botan Project * +*************************************************/ + +#include <botan/numthry.h> + +namespace Botan { + +/************************************************* +* Calculate the Jacobi symbol * +*************************************************/ +s32bit jacobi(const BigInt& a, const BigInt& n) + { + if(a.is_negative()) + throw Invalid_Argument("jacobi: first argument must be non-negative"); + if(n.is_even() || n < 2) + throw Invalid_Argument("jacobi: second argument must be odd and > 1"); + + BigInt x = a, y = n; + s32bit J = 1; + + while(y > 1) + { + x %= y; + if(x > y / 2) + { + x = y - x; + if(y % 4 == 3) + J = -J; + } + if(x.is_zero()) + return 0; + + u32bit shifts = low_zero_bits(x); + x >>= shifts; + if(shifts % 2) + { + word y_mod_8 = y % 8; + if(y_mod_8 == 3 || y_mod_8 == 5) + J = -J; + } + + if(x % 4 == 3 && y % 4 == 3) + J = -J; + std::swap(x, y); + } + return J; + } + +} |