monotone

monotone Mtn Source Tree

Root/botan/big_ops2.cpp

1/*************************************************
2* BigInt Assignment Operators Source File *
3* (C) 1999-2005 The Botan Project *
4*************************************************/
5
6#include <botan/bigint.h>
7#include <botan/numthry.h>
8#include <botan/mp_core.h>
9#include <botan/bit_ops.h>
10
11namespace Botan {
12
13/*************************************************
14* Addition Operator *
15*************************************************/
16BigInt& BigInt::operator+=(const BigInt& n)
17 {
18 if((sign() == n.sign()))
19 {
20 const u32bit reg_size = std::max(sig_words(), n.sig_words()) + 1;
21 grow_to(reg_size);
22 bigint_add2(get_reg(), reg_size-1, n.data(), n.sig_words());
23 }
24 else
25 (*this) = (*this) + n;
26 return (*this);
27 }
28
29/*************************************************
30* Subtraction Operator *
31*************************************************/
32BigInt& BigInt::operator-=(const BigInt& n)
33 {
34 s32bit relative_size = bigint_cmp(data(), sig_words(),
35 n.data(), n.sig_words());
36
37 if(relative_size == 0)
38 {
39 if(sign() == n.sign())
40 (*this) = 0;
41 else
42 (*this) <<= 1;
43 return (*this);
44 }
45
46 const u32bit reg_size = std::max(sig_words(), n.sig_words()) + 1;
47 grow_to(reg_size);
48
49 if(relative_size == -1)
50 {
51 if(sign() == n.sign())
52 (*this) = (*this) - n;
53 else
54 bigint_add2(get_reg(), reg_size-1, n.data(), n.sig_words());
55 set_sign(n.reverse_sign());
56 }
57 if(relative_size == 1)
58 {
59 if(sign() == n.sign())
60 bigint_sub2(get_reg(), sig_words(), n.data(), n.sig_words());
61 else
62 bigint_add2(get_reg(), reg_size-1, n.data(), n.sig_words());
63 }
64 return (*this);
65 }
66
67/*************************************************
68* Multiplication Operator *
69*************************************************/
70BigInt& BigInt::operator*=(const BigInt& n)
71 {
72 if(is_zero()) return (*this);
73 if(n.is_zero()) { (*this) = 0; return (*this); }
74
75 if(sign() != n.sign())
76 set_sign(Negative);
77 else
78 set_sign(Positive);
79
80 const u32bit words = sig_words();
81 const u32bit n_words = n.sig_words();
82
83 if(words == 1 || n_words == 1)
84 {
85 grow_to(words + n_words);
86 if(n_words == 1)
87 bigint_linmul2(get_reg(), words, n.word_at(0));
88 else
89 bigint_linmul3(get_reg(), n.data(), n_words, word_at(0));
90 return (*this);
91 }
92
93 BigInt z(sign(), size() + n.size());
94 bigint_mul3(z.get_reg(), z.size(),
95 data(), size(), words,
96 n.data(), n.size(), n_words);
97 (*this) = z;
98 return (*this);
99 }
100
101/*************************************************
102* Division Operator *
103*************************************************/
104BigInt& BigInt::operator/=(const BigInt& n)
105 {
106 if(n.sig_words() == 1 && power_of_2(n.word_at(0)))
107 (*this) >>= (n.bits() - 1);
108 else
109 (*this) = (*this) / n;
110 return (*this);
111 }
112
113/*************************************************
114* Modulo Operator *
115*************************************************/
116BigInt& BigInt::operator%=(const BigInt& mod)
117 {
118 return (*this = (*this) % mod);
119 }
120
121/*************************************************
122* Modulo Operator *
123*************************************************/
124word BigInt::operator%=(word mod)
125 {
126 if(mod == 0)
127 throw BigInt::DivideByZero();
128
129 if(power_of_2(mod))
130 {
131 word result = (word_at(0) & (mod - 1));
132 clear();
133 reg.grow_to(2);
134 reg[0] = result;
135 return result;
136 }
137
138 word remainder = 0;
139 u32bit size = sig_words();
140
141 for(u32bit j = size; j > 0; j--)
142 remainder = bigint_modop(remainder, word_at(j-1), mod);
143 clear();
144 reg.grow_to(2);
145 reg[0] = remainder;
146 return word_at(0);
147 }
148
149/*************************************************
150* Left Shift Operator *
151*************************************************/
152BigInt& BigInt::operator<<=(u32bit shift)
153 {
154 if(shift == 0) return (*this);
155 const u32bit shift_words = shift / MP_WORD_BITS,
156 shift_bits = shift % MP_WORD_BITS;
157
158 grow_to(sig_words() + shift_words + (shift_bits ? 1 : 0));
159 bigint_shl1(get_reg(), sig_words(), shift_words, shift_bits);
160 return (*this);
161 }
162
163/*************************************************
164* Right Shift Operator *
165*************************************************/
166BigInt& BigInt::operator>>=(u32bit shift)
167 {
168 if(shift == 0) return (*this);
169
170 if(bits() <= shift)
171 {
172 (*this) = 0;
173 return (*this);
174 }
175
176 const u32bit shift_words = shift / MP_WORD_BITS,
177 shift_bits = shift % MP_WORD_BITS;
178 bigint_shr1(get_reg(), sig_words(), shift_words, shift_bits);
179 return (*this);
180 }
181
182}

Archive Download this file

Branches

Tags

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