1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
|
/*************************************************
* Barrett Reducer Source File *
* (C) 1999-2005 The Botan Project *
*************************************************/
#include <botan/barrett.h>
#include <botan/numthry.h>
#include <botan/mp_core.h>
#include <botan/bit_ops.h>
namespace Botan {
/*************************************************
* Precompute values *
*************************************************/
BarrettReducer::BarrettReducer(const BigInt& mod) : ModularReducer(mod)
{
k = modulus.sig_words();
mu.set_bit(MP_WORD_BITS * 2 * k);
mu /= modulus;
max_bits = MP_WORD_BITS * 2 * k;
if(mu.size() > 8 && !power_of_2(mu.size()))
mu.grow_reg((1 << high_bit(mu.size())) - mu.size());
}
/*************************************************
* Barrett Reduction *
*************************************************/
BigInt BarrettReducer::reduce(const BigInt& x) const
{
if(x.is_positive() && x < modulus)
return x;
if(x.bits() > max_bits)
return (x % modulus);
t1 = x;
t1.set_sign(BigInt::Positive);
t1 >>= (MP_WORD_BITS * (k - 1));
t1 *= mu;
t1 >>= (MP_WORD_BITS * (k + 1));
t1 *= modulus;
t1.mask_bits(MP_WORD_BITS * (k+1));
t2 = x;
t2.set_sign(BigInt::Positive);
t2.mask_bits(MP_WORD_BITS * (k+1));
t2 -= t1;
if(t2.is_negative())
{
BigInt b_to_k1(BigInt::Power2, MP_WORD_BITS * (k+1));
t2 += b_to_k1;
}
while(t2 >= modulus)
t2 -= modulus;
if(x.is_negative() && t2.is_nonzero())
t2 = modulus - t2;
return t2;
}
}
|