monotone

monotone Mtn Source Tree

Root/botan/reducer.cpp

1/*************************************************
2* Modular Reducer Source File *
3* (C) 1999-2007 The Botan Project *
4*************************************************/
5
6#include <botan/reducer.h>
7#include <botan/numthry.h>
8#include <botan/mp_core.h>
9
10namespace Botan {
11
12/*************************************************
13* Modular_Reducer Constructor *
14*************************************************/
15Modular_Reducer::Modular_Reducer(const BigInt& mod)
16 {
17 if(mod <= 0)
18 throw Invalid_Argument("Modular_Reducer: modulus must be positive");
19
20 modulus = mod;
21 mod_words = modulus.sig_words();
22
23 modulus_2 = Botan::square(modulus);
24 mod2_words = modulus_2.sig_words();
25
26 mu = BigInt(BigInt::Power2, 2 * MP_WORD_BITS * mod_words) / modulus;
27 mu_words = mu.sig_words();
28 }
29
30/*************************************************
31* Barrett Reduction *
32*************************************************/
33BigInt Modular_Reducer::reduce(const BigInt& x) const
34 {
35 if(mod_words == 0)
36 throw Invalid_State("Modular_Reducer: Never initalized");
37
38 BigInt t1 = x;
39 t1.set_sign(BigInt::Positive);
40
41 if(t1 < modulus)
42 {
43 if(x.is_negative() && t1.is_nonzero())
44 return modulus - t1;
45 return x;
46 }
47
48 if(t1 >= modulus_2)
49 return (x % modulus);
50
51 t1 >>= (MP_WORD_BITS * (mod_words - 1));
52 t1 *= mu;
53 t1 >>= (MP_WORD_BITS * (mod_words + 1));
54
55 t1 *= modulus;
56 t1.mask_bits(MP_WORD_BITS * (mod_words+1));
57
58 BigInt t2 = x;
59 t2.set_sign(BigInt::Positive);
60 t2.mask_bits(MP_WORD_BITS * (mod_words+1));
61
62 t1 = t2 - t1;
63
64 if(t1.is_negative())
65 {
66 BigInt b_to_k1(BigInt::Power2, MP_WORD_BITS * (mod_words+1));
67 t1 += b_to_k1;
68 }
69
70 while(t1 >= modulus)
71 t1 -= modulus;
72
73 if(x.is_negative() && t1.is_nonzero())
74 t1 = modulus - t1;
75
76 return t1;
77 }
78
79/*************************************************
80* Multiply, followed by a reduction *
81*************************************************/
82BigInt Modular_Reducer::multiply(const BigInt& x, const BigInt& y) const
83 {
84 return reduce(x * y);
85 }
86
87/*************************************************
88* Square, followed by a reduction *
89*************************************************/
90BigInt Modular_Reducer::square(const BigInt& x) const
91 {
92 return reduce(Botan::square(x));
93 }
94
95}

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status