aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/math/numbertheory/numthry.cpp26
1 files changed, 17 insertions, 9 deletions
diff --git a/src/math/numbertheory/numthry.cpp b/src/math/numbertheory/numthry.cpp
index 8018c1d2d..16fa8ca0c 100644
--- a/src/math/numbertheory/numthry.cpp
+++ b/src/math/numbertheory/numthry.cpp
@@ -1,6 +1,6 @@
/*
* Number Theory Functions
-* (C) 1999-2010 Jack Lloyd
+* (C) 1999-2011 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -10,6 +10,8 @@
#include <botan/internal/bit_ops.h>
#include <algorithm>
+#include <stdio.h>
+
namespace Botan {
namespace {
@@ -20,7 +22,7 @@ namespace {
class MillerRabin_Test
{
public:
- bool passes_test(const BigInt& nonce);
+ bool is_witness(const BigInt& nonce);
MillerRabin_Test(const BigInt& num);
private:
BigInt n, r, n_minus_1;
@@ -30,26 +32,32 @@ class MillerRabin_Test
};
/*
-* Miller-Rabin Test
+* Miller-Rabin Test, as described in Handbook of Applied Cryptography
+* section 4.24
*/
-bool MillerRabin_Test::passes_test(const BigInt& a)
+bool MillerRabin_Test::is_witness(const BigInt& a)
{
if(a < 2 || a >= n_minus_1)
throw Invalid_Argument("Bad size for nonce in Miller-Rabin test");
BigInt y = pow_mod(a);
if(y == 1 || y == n_minus_1)
- return true;
+ return false;
for(size_t i = 1; i != s; ++i)
{
y = reducer.square(y);
- if(y == 1)
- return false;
- if(y == n_minus_1)
+ if(y == 1) // found a non-trivial square root
return true;
+
+ if(y == n_minus_1) // -1, trivial square root, so give up
+ return false;
}
+
+ if(y != n_minus_1) // fails Fermat test
+ return true;
+
return false;
}
@@ -297,7 +305,7 @@ bool primality_test(const BigInt& n,
while(nonce < 2 || nonce >= (n-1))
nonce.randomize(rng, NONCE_BITS);
- if(!mr.passes_test(nonce))
+ if(mr.is_witness(nonce))
return false;
}
return true;