Francois Berder / BigInt
Committer:
feb11
Date:
Thu Mar 06 11:28:18 2014 +0000
Revision:
14:5a1852dac7f7
Parent:
13:d0b4d7cfeb98
Child:
15:85a6bd4539eb
export function done

Who changed what in which revision?

UserRevisionLine numberNew contents of line
feb11 0:9d554894785b 1 #include "BigInt.h"
feb11 0:9d554894785b 2 #include <string.h>
feb11 0:9d554894785b 3 #include <stdio.h>
feb11 0:9d554894785b 4 #include <stdlib.h>
feb11 0:9d554894785b 5 #include <iostream>
feb11 0:9d554894785b 6 #include <climits>
feb11 9:3c191fa04f6e 7 #include <cassert>
feb11 10:116e201f7d89 8 #include <algorithm>
feb11 0:9d554894785b 9
feb11 0:9d554894785b 10 static uint32_t num(const uint32_t a)
feb11 0:9d554894785b 11 {
feb11 0:9d554894785b 12 return a/4 + (a%4 ? 1:0);
feb11 0:9d554894785b 13 }
feb11 10:116e201f7d89 14
feb11 10:116e201f7d89 15
feb11 0:9d554894785b 16 BigInt::BigInt():
feb11 0:9d554894785b 17 size(0),
feb11 0:9d554894785b 18 bits(0)
feb11 0:9d554894785b 19 {
feb11 0:9d554894785b 20 }
feb11 0:9d554894785b 21
feb11 2:1001793a090d 22 BigInt::BigInt(const uint32_t a)
feb11 2:1001793a090d 23 {
feb11 2:1001793a090d 24 if(a >> 24)
feb11 2:1001793a090d 25 size = 4;
feb11 2:1001793a090d 26 else if(a >> 16)
feb11 2:1001793a090d 27 size = 3;
feb11 2:1001793a090d 28 else if(a >> 8)
feb11 2:1001793a090d 29 size = 2;
feb11 2:1001793a090d 30 else
feb11 2:1001793a090d 31 size = 1;
feb11 2:1001793a090d 32 bits = new uint32_t[1];
feb11 2:1001793a090d 33 bits[0] = a;
feb11 2:1001793a090d 34 }
feb11 2:1001793a090d 35
feb11 0:9d554894785b 36 BigInt::BigInt(const BigInt &a):
feb11 0:9d554894785b 37 size(a.size)
feb11 0:9d554894785b 38 {
feb11 0:9d554894785b 39 uint32_t l = num(size);
feb11 0:9d554894785b 40 bits = new uint32_t[l];
feb11 0:9d554894785b 41 for(int i = 0; i < l; ++i)
feb11 0:9d554894785b 42 bits[i] = a.bits[i];
feb11 0:9d554894785b 43 }
feb11 0:9d554894785b 44
feb11 0:9d554894785b 45
feb11 0:9d554894785b 46 BigInt::~BigInt()
feb11 0:9d554894785b 47 {
feb11 10:116e201f7d89 48 if(size)
feb11 9:3c191fa04f6e 49 {
feb11 0:9d554894785b 50 delete[] bits;
feb11 9:3c191fa04f6e 51 }
feb11 0:9d554894785b 52 }
feb11 0:9d554894785b 53
feb11 0:9d554894785b 54 BigInt& BigInt::operator=(const BigInt& a)
feb11 0:9d554894785b 55 {
feb11 0:9d554894785b 56 size = a.size;
feb11 0:9d554894785b 57 uint32_t l = num(size);
feb11 0:9d554894785b 58 if(bits)
feb11 0:9d554894785b 59 delete[] bits;
feb11 0:9d554894785b 60 bits = new uint32_t[l];
feb11 0:9d554894785b 61 for(int i = 0; i < l; ++i)
feb11 0:9d554894785b 62 bits[i] = a.bits[i];
feb11 0:9d554894785b 63 return *this;
feb11 0:9d554894785b 64 }
feb11 0:9d554894785b 65
feb11 13:d0b4d7cfeb98 66 void BigInt::importData(uint8_t *data, uint32_t length)
feb11 0:9d554894785b 67 {
feb11 0:9d554894785b 68 size = length;
feb11 0:9d554894785b 69 size_t l = size/4;
feb11 0:9d554894785b 70 if(size % 4 != 0)
feb11 0:9d554894785b 71 l++;
feb11 0:9d554894785b 72 if(bits)
feb11 0:9d554894785b 73 delete[] bits;
feb11 0:9d554894785b 74 bits = new uint32_t[l];
feb11 0:9d554894785b 75 memset(bits, 0, sizeof(uint32_t)*l);
feb11 4:773aed3156c5 76 for(int i = length-1; i >=0; --i)
feb11 0:9d554894785b 77 bits[i/4] |= data[i] << ((i%4)*8);
feb11 0:9d554894785b 78 }
feb11 0:9d554894785b 79
feb11 13:d0b4d7cfeb98 80 void BigInt::exportData(uint8_t *data, uint32_t length)
feb11 13:d0b4d7cfeb98 81 {
feb11 13:d0b4d7cfeb98 82 assert(isValid() && data != 0);
feb11 13:d0b4d7cfeb98 83
feb11 14:5a1852dac7f7 84 if(length < size)
feb11 14:5a1852dac7f7 85 return;
feb11 14:5a1852dac7f7 86 uint32_t offset = length-size;
feb11 14:5a1852dac7f7 87 memset(data, 0, offset);
feb11 14:5a1852dac7f7 88 for(int i = size-1; i >= 0; --i)
feb11 14:5a1852dac7f7 89 data[offset+size-1-i] = bits[i/4] >> ((i%4)*8);
feb11 13:d0b4d7cfeb98 90 }
feb11 13:d0b4d7cfeb98 91
feb11 0:9d554894785b 92 BigInt operator+(const BigInt &a, const BigInt& b)
feb11 0:9d554894785b 93 {
feb11 9:3c191fa04f6e 94 assert(a.isValid() && b.isValid());
feb11 9:3c191fa04f6e 95
feb11 0:9d554894785b 96 BigInt result;
feb11 9:3c191fa04f6e 97
feb11 0:9d554894785b 98 result.size = a.size > b.size ? a.size : b.size;
feb11 0:9d554894785b 99 size_t l = result.size/4;
feb11 0:9d554894785b 100 if(result.size % 4 != 0)
feb11 0:9d554894785b 101 l++;
feb11 0:9d554894785b 102 result.bits = new uint32_t[l];
feb11 0:9d554894785b 103 memset(result.bits, 0, sizeof(uint32_t)*l);
feb11 0:9d554894785b 104 uint32_t al = num(a.size);
feb11 0:9d554894785b 105 uint32_t bl = num(b.size);
feb11 0:9d554894785b 106 uint32_t carry = 0;
feb11 0:9d554894785b 107 for(int i = 0; i < l; ++i)
feb11 0:9d554894785b 108 {
feb11 0:9d554894785b 109 uint32_t tmpA = 0, tmpB = 0;
feb11 0:9d554894785b 110 if(i < al)
feb11 0:9d554894785b 111 tmpA = a.bits[i];
feb11 0:9d554894785b 112 if(i < bl)
feb11 0:9d554894785b 113 tmpB = b.bits[i];
feb11 0:9d554894785b 114 result.bits[i] = tmpA + tmpB + carry;
feb11 10:116e201f7d89 115 carry = result.bits[i] < std::max(tmpA, tmpB);
feb11 0:9d554894785b 116 }
feb11 0:9d554894785b 117 if(carry)
feb11 0:9d554894785b 118 {
feb11 0:9d554894785b 119 result.size++;
feb11 0:9d554894785b 120 if(result.size > l*4)
feb11 0:9d554894785b 121 {
feb11 0:9d554894785b 122 l++;
feb11 0:9d554894785b 123 result.bits = (uint32_t*)realloc(result.bits, l * sizeof(uint32_t));
feb11 0:9d554894785b 124 result.bits[l-1] = 0x00000001;
feb11 0:9d554894785b 125 }
feb11 0:9d554894785b 126 else
feb11 0:9d554894785b 127 {
feb11 0:9d554894785b 128 result.bits[l-1] += 1 << (8 *((result.size-1)%4));
feb11 0:9d554894785b 129 }
feb11 0:9d554894785b 130 }
feb11 0:9d554894785b 131
feb11 0:9d554894785b 132 return result;
feb11 0:9d554894785b 133 }
feb11 0:9d554894785b 134
feb11 0:9d554894785b 135 BigInt& BigInt::operator+=(const BigInt &b)
feb11 0:9d554894785b 136 {
feb11 0:9d554894785b 137 return (*this = (*this) + b);
feb11 0:9d554894785b 138 }
feb11 0:9d554894785b 139
feb11 0:9d554894785b 140 BigInt& BigInt::operator++()
feb11 0:9d554894785b 141 {
feb11 3:3fa3ceb0c69d 142 return (*this += 1);
feb11 0:9d554894785b 143 }
feb11 0:9d554894785b 144
feb11 0:9d554894785b 145 BigInt BigInt::operator++(int)
feb11 0:9d554894785b 146 {
feb11 0:9d554894785b 147 BigInt t = *this;
feb11 3:3fa3ceb0c69d 148 *this += 1;
feb11 0:9d554894785b 149 return t;
feb11 0:9d554894785b 150 }
feb11 0:9d554894785b 151
feb11 0:9d554894785b 152 // a - b, if b >= a, returns 0
feb11 0:9d554894785b 153 // No negative number allowed
feb11 0:9d554894785b 154 BigInt operator-(const BigInt &a, const BigInt& b)
feb11 0:9d554894785b 155 {
feb11 9:3c191fa04f6e 156 assert(a.isValid() && b.isValid());
feb11 9:3c191fa04f6e 157
feb11 0:9d554894785b 158 BigInt result;
feb11 0:9d554894785b 159
feb11 0:9d554894785b 160 if(b >= a)
feb11 0:9d554894785b 161 {
feb11 3:3fa3ceb0c69d 162 return result = 0;
feb11 0:9d554894785b 163 }
feb11 0:9d554894785b 164 else
feb11 0:9d554894785b 165 {
feb11 0:9d554894785b 166 result.size = a.size;
feb11 0:9d554894785b 167 uint32_t l = num(a.size);
feb11 0:9d554894785b 168 result.bits = new uint32_t[l];
feb11 0:9d554894785b 169 memset(result.bits, 0, sizeof(uint32_t)*l);
feb11 0:9d554894785b 170 uint32_t bl = num(b.size);
feb11 0:9d554894785b 171 uint8_t borrow = 0;
feb11 0:9d554894785b 172 for(uint32_t i = 0; i < l; ++i)
feb11 0:9d554894785b 173 {
feb11 0:9d554894785b 174 uint32_t tmpA = a.bits[i], tmpB = 0;
feb11 0:9d554894785b 175 if(i < bl)
feb11 0:9d554894785b 176 tmpB = b.bits[i];
feb11 0:9d554894785b 177 if(borrow)
feb11 0:9d554894785b 178 {
feb11 0:9d554894785b 179 if(tmpA == 0)
feb11 0:9d554894785b 180 tmpA = ULONG_MAX;
feb11 0:9d554894785b 181 else
feb11 0:9d554894785b 182 --tmpA;
feb11 0:9d554894785b 183
feb11 0:9d554894785b 184 if(tmpA < tmpB)
feb11 0:9d554894785b 185 result.bits[i] = tmpA + 1 + (ULONG_MAX - tmpB);
feb11 0:9d554894785b 186 else
feb11 0:9d554894785b 187 result.bits[i] = tmpA - tmpB;
feb11 0:9d554894785b 188
feb11 0:9d554894785b 189 if(a.bits[i] != 0 && tmpA > tmpB)
feb11 0:9d554894785b 190 borrow = 0;
feb11 0:9d554894785b 191 }
feb11 0:9d554894785b 192 else
feb11 0:9d554894785b 193 {
feb11 0:9d554894785b 194 if(tmpA < tmpB)
feb11 0:9d554894785b 195 result.bits[i] = tmpA + 1 + (ULONG_MAX - tmpB);
feb11 0:9d554894785b 196 else
feb11 0:9d554894785b 197 result.bits[i] = tmpA - tmpB;
feb11 0:9d554894785b 198 borrow = tmpA < tmpB;
feb11 0:9d554894785b 199 }
feb11 0:9d554894785b 200 }
feb11 0:9d554894785b 201
feb11 9:3c191fa04f6e 202 result.trim();
feb11 0:9d554894785b 203
feb11 0:9d554894785b 204 return result;
feb11 0:9d554894785b 205 }
feb11 0:9d554894785b 206 }
feb11 0:9d554894785b 207
feb11 0:9d554894785b 208 BigInt& BigInt::operator-=(const BigInt &b)
feb11 0:9d554894785b 209 {
feb11 0:9d554894785b 210 return (*this = (*this) - b);
feb11 0:9d554894785b 211 }
feb11 0:9d554894785b 212
feb11 0:9d554894785b 213 BigInt& BigInt::operator--()
feb11 0:9d554894785b 214 {
feb11 3:3fa3ceb0c69d 215 return (*this -= 1);
feb11 0:9d554894785b 216 }
feb11 0:9d554894785b 217
feb11 0:9d554894785b 218 BigInt BigInt::operator--(int)
feb11 0:9d554894785b 219 {
feb11 0:9d554894785b 220 BigInt t = *this;
feb11 3:3fa3ceb0c69d 221 *this -= 1;
feb11 0:9d554894785b 222 return t;
feb11 0:9d554894785b 223 }
feb11 3:3fa3ceb0c69d 224
feb11 1:00f2c40d46ed 225 BigInt operator*(const BigInt &a, const BigInt& b)
feb11 1:00f2c40d46ed 226 {
feb11 9:3c191fa04f6e 227 assert(a.isValid() && b.isValid());
feb11 9:3c191fa04f6e 228
feb11 1:00f2c40d46ed 229 // if a == 0 or b == 0 then result = 0
feb11 1:00f2c40d46ed 230 if(!a || !b)
feb11 12:a436f15b58b6 231 return 0;
feb11 1:00f2c40d46ed 232
feb11 1:00f2c40d46ed 233 // if a == 1, then result = b
feb11 3:3fa3ceb0c69d 234 if(a == 1)
feb11 12:a436f15b58b6 235 return b;
feb11 1:00f2c40d46ed 236
feb11 1:00f2c40d46ed 237 // if b == 1, then result = a
feb11 3:3fa3ceb0c69d 238 if(b == 1)
feb11 12:a436f15b58b6 239 return a;
feb11 12:a436f15b58b6 240
feb11 12:a436f15b58b6 241 BigInt result;
feb11 4:773aed3156c5 242 result.size = a.size + b.size;
feb11 4:773aed3156c5 243 result.bits = new uint32_t[num(result.size)];
feb11 12:a436f15b58b6 244 memset(result.bits, 0, sizeof(uint32_t)*num(result.size));
feb11 11:2f16a220ebbb 245 for(int i = 0; i < num(a.size); ++i)
feb11 4:773aed3156c5 246 {
feb11 11:2f16a220ebbb 247 uint64_t carry = 0;
feb11 11:2f16a220ebbb 248 for(int j = 0; j < num(b.size); ++j)
feb11 11:2f16a220ebbb 249 {
feb11 11:2f16a220ebbb 250 uint64_t tmp = (uint64_t)a.bits[i] * (uint64_t)b.bits[j] + carry;
feb11 12:a436f15b58b6 251 uint32_t t = result.bits[i+j];
feb11 11:2f16a220ebbb 252 result.bits[i+j] += tmp;
feb11 12:a436f15b58b6 253 carry = tmp >> 32;
feb11 12:a436f15b58b6 254 if(t > result.bits[i+j])
feb11 12:a436f15b58b6 255 ++carry;
feb11 11:2f16a220ebbb 256 }
feb11 11:2f16a220ebbb 257 if(carry != 0)
feb11 11:2f16a220ebbb 258 result.bits[i+num(b.size)] += carry;
feb11 4:773aed3156c5 259 }
feb11 4:773aed3156c5 260
feb11 9:3c191fa04f6e 261 result.trim();
feb11 1:00f2c40d46ed 262
feb11 1:00f2c40d46ed 263 return result;
feb11 1:00f2c40d46ed 264 }
feb11 1:00f2c40d46ed 265
feb11 1:00f2c40d46ed 266 BigInt& BigInt::operator*=(const BigInt &b)
feb11 1:00f2c40d46ed 267 {
feb11 1:00f2c40d46ed 268 return (*this = (*this) * b);
feb11 1:00f2c40d46ed 269 }
feb11 1:00f2c40d46ed 270
feb11 10:116e201f7d89 271
feb11 11:2f16a220ebbb 272 BigInt operator/(const BigInt &a, const BigInt &b)
feb11 10:116e201f7d89 273 {
feb11 10:116e201f7d89 274 assert(a.isValid() && b.isValid() && b != 0);
feb11 10:116e201f7d89 275 if(b == 1)
feb11 10:116e201f7d89 276 return a;
feb11 10:116e201f7d89 277 if(a < b)
feb11 10:116e201f7d89 278 return 0;
feb11 10:116e201f7d89 279 if(a == b)
feb11 10:116e201f7d89 280 return 1;
feb11 11:2f16a220ebbb 281 BigInt u = a;
feb11 11:2f16a220ebbb 282 int m = a.numBits() - b.numBits();
feb11 10:116e201f7d89 283 BigInt q = 0;
feb11 12:a436f15b58b6 284 BigInt tmp = b;
feb11 12:a436f15b58b6 285 tmp <<= m;
feb11 10:116e201f7d89 286 for(int j = m; j >= 0; --j)
feb11 10:116e201f7d89 287 {
feb11 11:2f16a220ebbb 288 if(tmp <= u)
feb11 10:116e201f7d89 289 {
feb11 11:2f16a220ebbb 290 u -= tmp;
feb11 11:2f16a220ebbb 291 BigInt tmp2 = 1;
feb11 11:2f16a220ebbb 292 tmp2 <<= j;
feb11 12:a436f15b58b6 293 q += tmp2;
feb11 10:116e201f7d89 294 }
feb11 10:116e201f7d89 295 tmp >>= 1;
feb11 10:116e201f7d89 296 }
feb11 11:2f16a220ebbb 297 q.trim();
feb11 11:2f16a220ebbb 298 return q;
feb11 10:116e201f7d89 299 }
feb11 10:116e201f7d89 300
feb11 10:116e201f7d89 301 BigInt& BigInt::operator/=(const BigInt &b)
feb11 10:116e201f7d89 302 {
feb11 10:116e201f7d89 303 return (*this = (*this) / b);
feb11 10:116e201f7d89 304 }
feb11 10:116e201f7d89 305
feb11 1:00f2c40d46ed 306 BigInt operator>>(const BigInt &a, const uint32_t m)
feb11 1:00f2c40d46ed 307 {
feb11 9:3c191fa04f6e 308 assert(a.isValid());
feb11 9:3c191fa04f6e 309
feb11 12:a436f15b58b6 310 if(m == 0)
feb11 12:a436f15b58b6 311 return a;
feb11 12:a436f15b58b6 312 if(m/8 >= a.size)
feb11 12:a436f15b58b6 313 return 0;
feb11 12:a436f15b58b6 314
feb11 1:00f2c40d46ed 315 BigInt result;
feb11 1:00f2c40d46ed 316 result.size = a.size - m/8;
feb11 1:00f2c40d46ed 317 result.bits = new uint32_t[num(result.size)];
feb11 1:00f2c40d46ed 318 uint8_t s = m%32;
feb11 1:00f2c40d46ed 319 for(uint32_t i = 0; i < num(result.size); ++i)
feb11 1:00f2c40d46ed 320 {
feb11 1:00f2c40d46ed 321 if(m/32+i+1 < num(a.size))
feb11 1:00f2c40d46ed 322 result.bits[i] = (a.bits[m/32+i+1] << (32-s)) | (a.bits[m/32+i] >> s);
feb11 1:00f2c40d46ed 323 else
feb11 1:00f2c40d46ed 324 result.bits[i] = (a.bits[m/32+i] >> s);
feb11 1:00f2c40d46ed 325 }
feb11 1:00f2c40d46ed 326
feb11 10:116e201f7d89 327 result.trim();
feb11 10:116e201f7d89 328
feb11 1:00f2c40d46ed 329 return result;
feb11 1:00f2c40d46ed 330 }
feb11 1:00f2c40d46ed 331
feb11 1:00f2c40d46ed 332 BigInt& BigInt::operator>>=(const uint32_t m)
feb11 1:00f2c40d46ed 333 {
feb11 1:00f2c40d46ed 334 return *this = *this >> m;
feb11 1:00f2c40d46ed 335 }
feb11 1:00f2c40d46ed 336
feb11 1:00f2c40d46ed 337 BigInt operator<<(const BigInt &a, const uint32_t m)
feb11 1:00f2c40d46ed 338 {
feb11 9:3c191fa04f6e 339 assert(a.isValid());
feb11 9:3c191fa04f6e 340
feb11 1:00f2c40d46ed 341 BigInt result;
feb11 9:3c191fa04f6e 342
feb11 1:00f2c40d46ed 343 if(m == 0)
feb11 1:00f2c40d46ed 344 return result = a;
feb11 1:00f2c40d46ed 345
feb11 1:00f2c40d46ed 346 result.size = m/8 + a.size;
feb11 1:00f2c40d46ed 347 uint32_t h = a.bits[num(a.size)-1];
feb11 12:a436f15b58b6 348 if((m%32)%8 != 0)
feb11 1:00f2c40d46ed 349 ++result.size;
feb11 1:00f2c40d46ed 350 uint32_t l = num(result.size);
feb11 1:00f2c40d46ed 351 result.bits = new uint32_t[l];
feb11 1:00f2c40d46ed 352 memset(result.bits, 0, sizeof(uint32_t)*l);
feb11 1:00f2c40d46ed 353 uint32_t s = m % 32;
feb11 1:00f2c40d46ed 354 for(uint32_t i = 0; i < num(a.size); ++i)
feb11 1:00f2c40d46ed 355 {
feb11 1:00f2c40d46ed 356 if(i == 0)
feb11 1:00f2c40d46ed 357 result.bits[m/32+i] = a.bits[i] << s;
feb11 1:00f2c40d46ed 358 else
feb11 1:00f2c40d46ed 359 result.bits[m/32+i] = (a.bits[i] << s) | (a.bits[i-1] >> (32-s));
feb11 1:00f2c40d46ed 360 }
feb11 12:a436f15b58b6 361 if(a.bits[num(a.size)-1] && s != 0)
feb11 12:a436f15b58b6 362 result.bits[m/32+num(result.size)-1] |= a.bits[num(a.size)-1] >> (32-s);
feb11 1:00f2c40d46ed 363
feb11 12:a436f15b58b6 364 result.trim();
feb11 1:00f2c40d46ed 365
feb11 1:00f2c40d46ed 366 return result;
feb11 1:00f2c40d46ed 367 }
feb11 1:00f2c40d46ed 368
feb11 1:00f2c40d46ed 369 BigInt& BigInt::operator<<=(const uint32_t m)
feb11 1:00f2c40d46ed 370 {
feb11 1:00f2c40d46ed 371 return (*this = *this << m);
feb11 1:00f2c40d46ed 372 }
feb11 0:9d554894785b 373
feb11 5:beeb31f340a7 374 BigInt operator%(const BigInt &a, const BigInt &b)
feb11 5:beeb31f340a7 375 {
feb11 10:116e201f7d89 376 assert(a.isValid() && b.isValid() && b > 0);
feb11 12:a436f15b58b6 377 return a - (a/b)*b;
feb11 5:beeb31f340a7 378 }
feb11 5:beeb31f340a7 379
feb11 5:beeb31f340a7 380 BigInt& BigInt::operator%=(const BigInt &a)
feb11 5:beeb31f340a7 381 {
feb11 5:beeb31f340a7 382 return (*this = *this % a);
feb11 5:beeb31f340a7 383 }
feb11 5:beeb31f340a7 384
feb11 0:9d554894785b 385 bool operator==(const BigInt &a, const BigInt &b)
feb11 0:9d554894785b 386 {
feb11 9:3c191fa04f6e 387 assert(a.isValid() && b.isValid());
feb11 9:3c191fa04f6e 388
feb11 0:9d554894785b 389 if(a.size != b.size)
feb11 0:9d554894785b 390 return false;
feb11 0:9d554894785b 391
feb11 0:9d554894785b 392 uint32_t l = num(a.size);
feb11 0:9d554894785b 393 for(int i = 0; i < l; ++i)
feb11 0:9d554894785b 394 if(a.bits[i] != b.bits[i])
feb11 0:9d554894785b 395 return false;
feb11 0:9d554894785b 396 return true;
feb11 0:9d554894785b 397 }
feb11 0:9d554894785b 398
feb11 0:9d554894785b 399 bool operator!=(const BigInt &a, const BigInt &b)
feb11 0:9d554894785b 400 {
feb11 0:9d554894785b 401 return ! (a==b);
feb11 0:9d554894785b 402 }
feb11 0:9d554894785b 403
feb11 0:9d554894785b 404 bool operator<(const BigInt &a, const BigInt &b)
feb11 0:9d554894785b 405 {
feb11 9:3c191fa04f6e 406 assert(a.isValid() && b.isValid());
feb11 9:3c191fa04f6e 407
feb11 0:9d554894785b 408 if(a.size < b.size)
feb11 0:9d554894785b 409 return true;
feb11 0:9d554894785b 410 if(a.size > b.size)
feb11 0:9d554894785b 411 return false;
feb11 0:9d554894785b 412 uint32_t l = num(a.size);
feb11 0:9d554894785b 413 for(int i = l-1; i >= 0; --i)
feb11 12:a436f15b58b6 414 {
feb11 0:9d554894785b 415 if(a.bits[i] < b.bits[i])
feb11 0:9d554894785b 416 return true;
feb11 12:a436f15b58b6 417 else if(a.bits[i] > b.bits[i])
feb11 12:a436f15b58b6 418 return false;
feb11 12:a436f15b58b6 419 }
feb11 0:9d554894785b 420 return false;
feb11 0:9d554894785b 421 }
feb11 0:9d554894785b 422
feb11 0:9d554894785b 423 bool operator<=(const BigInt &a, const BigInt &b)
feb11 0:9d554894785b 424 {
feb11 9:3c191fa04f6e 425 return !(a > b);
feb11 0:9d554894785b 426 }
feb11 0:9d554894785b 427
feb11 0:9d554894785b 428 bool operator>(const BigInt &a, const BigInt &b)
feb11 0:9d554894785b 429 {
feb11 9:3c191fa04f6e 430 assert(a.isValid() && b.isValid());
feb11 9:3c191fa04f6e 431
feb11 0:9d554894785b 432 if(a.size > b.size)
feb11 0:9d554894785b 433 return true;
feb11 0:9d554894785b 434 if(a.size < b.size)
feb11 0:9d554894785b 435 return false;
feb11 0:9d554894785b 436 uint32_t l = num(a.size);
feb11 0:9d554894785b 437 for(int i = l-1; i >= 0; --i)
feb11 12:a436f15b58b6 438 {
feb11 0:9d554894785b 439 if(a.bits[i] > b.bits[i])
feb11 0:9d554894785b 440 return true;
feb11 12:a436f15b58b6 441 else if(a.bits[i] < b.bits[i])
feb11 12:a436f15b58b6 442 return false;
feb11 12:a436f15b58b6 443 }
feb11 0:9d554894785b 444 return false;
feb11 0:9d554894785b 445 }
feb11 0:9d554894785b 446
feb11 0:9d554894785b 447 bool operator>=(const BigInt &a, const BigInt &b)
feb11 0:9d554894785b 448 {
feb11 9:3c191fa04f6e 449 return !(a < b);
feb11 0:9d554894785b 450 }
feb11 0:9d554894785b 451
feb11 1:00f2c40d46ed 452 bool operator!(const BigInt &a)
feb11 0:9d554894785b 453 {
feb11 9:3c191fa04f6e 454 assert(a.isValid());
feb11 9:3c191fa04f6e 455
feb11 1:00f2c40d46ed 456 if(a.size != 1)
feb11 0:9d554894785b 457 return false;
feb11 1:00f2c40d46ed 458 return a.bits[0] == 0;
feb11 0:9d554894785b 459 }
feb11 0:9d554894785b 460
feb11 7:1aad58757705 461
feb11 7:1aad58757705 462 BigInt operator&(const BigInt &a, const BigInt &b)
feb11 7:1aad58757705 463 {
feb11 9:3c191fa04f6e 464 assert(a.isValid() && b.isValid());
feb11 9:3c191fa04f6e 465
feb11 7:1aad58757705 466 BigInt result;
feb11 7:1aad58757705 467
feb11 7:1aad58757705 468 result.size = a.size < b.size ? a.size : b.size;
feb11 7:1aad58757705 469 uint32_t l = num(result.size);
feb11 7:1aad58757705 470 result.bits = new uint32_t[l];
feb11 7:1aad58757705 471 memset(result.bits, 0, l);
feb11 7:1aad58757705 472
feb11 7:1aad58757705 473 for(uint32_t i = 0; i < l; ++i)
feb11 7:1aad58757705 474 result.bits[i] = a.bits[i] & b.bits[i];
feb11 7:1aad58757705 475
feb11 9:3c191fa04f6e 476 result.trim();
feb11 7:1aad58757705 477
feb11 7:1aad58757705 478 return result;
feb11 7:1aad58757705 479 }
feb11 7:1aad58757705 480
feb11 7:1aad58757705 481 BigInt& BigInt::operator&=(const BigInt &a)
feb11 7:1aad58757705 482 {
feb11 7:1aad58757705 483 return (*this = *this & a);
feb11 7:1aad58757705 484 }
feb11 7:1aad58757705 485
feb11 7:1aad58757705 486 BigInt operator|(const BigInt &a, const BigInt &b)
feb11 7:1aad58757705 487 {
feb11 9:3c191fa04f6e 488 assert(a.isValid() && b.isValid());
feb11 9:3c191fa04f6e 489
feb11 7:1aad58757705 490 BigInt result;
feb11 7:1aad58757705 491
feb11 7:1aad58757705 492 uint32_t na = num(a.size);
feb11 7:1aad58757705 493 uint32_t nb = num(b.size);
feb11 10:116e201f7d89 494 uint32_t l = std::max(na,nb);
feb11 10:116e201f7d89 495 result.size = std::max(a.size, b.size);
feb11 7:1aad58757705 496 result.bits = new uint32_t[l];
feb11 7:1aad58757705 497 memset(result.bits, 0, l);
feb11 7:1aad58757705 498
feb11 7:1aad58757705 499 for(uint32_t i = 0; i < l; ++i)
feb11 7:1aad58757705 500 {
feb11 7:1aad58757705 501 if(i < na && i < nb)
feb11 7:1aad58757705 502 result.bits[i] = a.bits[i] | b.bits[i];
feb11 7:1aad58757705 503 else if(i < na)
feb11 7:1aad58757705 504 result.bits[i] = a.bits[i];
feb11 7:1aad58757705 505 else
feb11 7:1aad58757705 506 result.bits[i] = b.bits[i];
feb11 7:1aad58757705 507 }
feb11 7:1aad58757705 508
feb11 7:1aad58757705 509 return result;
feb11 7:1aad58757705 510 }
feb11 7:1aad58757705 511
feb11 7:1aad58757705 512 BigInt& BigInt::operator|=(const BigInt &a)
feb11 7:1aad58757705 513 {
feb11 7:1aad58757705 514 return (*this = *this | a);
feb11 7:1aad58757705 515 }
feb11 8:2a361f1b41da 516
feb11 8:2a361f1b41da 517 BigInt operator^(const BigInt &a, const BigInt &b)
feb11 8:2a361f1b41da 518 {
feb11 9:3c191fa04f6e 519 assert(a.isValid() && b.isValid());
feb11 9:3c191fa04f6e 520
feb11 9:3c191fa04f6e 521
feb11 8:2a361f1b41da 522 BigInt result;
feb11 8:2a361f1b41da 523
feb11 8:2a361f1b41da 524 uint32_t na = num(a.size);
feb11 8:2a361f1b41da 525 uint32_t nb = num(b.size);
feb11 10:116e201f7d89 526 uint32_t l = std::max(na,nb);
feb11 10:116e201f7d89 527 result.size = std::max(a.size, b.size);
feb11 8:2a361f1b41da 528 result.bits = new uint32_t[l];
feb11 8:2a361f1b41da 529 memset(result.bits, 0, l);
feb11 7:1aad58757705 530
feb11 8:2a361f1b41da 531 for(uint32_t i = 0; i < l; ++i)
feb11 8:2a361f1b41da 532 {
feb11 8:2a361f1b41da 533 if(i < na && i < nb)
feb11 8:2a361f1b41da 534 result.bits[i] = a.bits[i] ^ b.bits[i];
feb11 8:2a361f1b41da 535 else if(i < na)
feb11 8:2a361f1b41da 536 result.bits[i] = a.bits[i];
feb11 8:2a361f1b41da 537 else
feb11 8:2a361f1b41da 538 result.bits[i] = b.bits[i];
feb11 8:2a361f1b41da 539 }
feb11 8:2a361f1b41da 540
feb11 9:3c191fa04f6e 541 result.trim();
feb11 9:3c191fa04f6e 542
feb11 8:2a361f1b41da 543 return result;
feb11 8:2a361f1b41da 544 }
feb11 8:2a361f1b41da 545
feb11 8:2a361f1b41da 546 BigInt& BigInt::operator^=(const BigInt &a)
feb11 8:2a361f1b41da 547 {
feb11 8:2a361f1b41da 548 return (*this = *this ^ a);
feb11 8:2a361f1b41da 549 }
feb11 9:3c191fa04f6e 550
feb11 10:116e201f7d89 551 BigInt montgomeryStep(const BigInt &a, const BigInt &b, const BigInt &m, uint32_t r)
feb11 10:116e201f7d89 552 {
feb11 10:116e201f7d89 553 BigInt result = 0;
feb11 10:116e201f7d89 554 BigInt tmp = a;
feb11 10:116e201f7d89 555 while(r > 0)
feb11 10:116e201f7d89 556 {
feb11 10:116e201f7d89 557 if(tmp.bits[0] & 0x01)
feb11 10:116e201f7d89 558 result += b;
feb11 10:116e201f7d89 559
feb11 10:116e201f7d89 560 if(result.bits[0] & 0x01)
feb11 10:116e201f7d89 561 result += m;
feb11 10:116e201f7d89 562
feb11 10:116e201f7d89 563 --r;
feb11 10:116e201f7d89 564 result >>= 1;
feb11 10:116e201f7d89 565 tmp >>= 1;
feb11 10:116e201f7d89 566 }
feb11 10:116e201f7d89 567 return result;
feb11 10:116e201f7d89 568 }
feb11 10:116e201f7d89 569
feb11 10:116e201f7d89 570 // Implementation using Montgomery algorithm
feb11 9:3c191fa04f6e 571 BigInt modPow(const BigInt &a, const BigInt &expn, const BigInt &modulus)
feb11 9:3c191fa04f6e 572 {
feb11 9:3c191fa04f6e 573 assert(a.isValid() && expn.isValid() && modulus.isValid());
feb11 9:3c191fa04f6e 574
feb11 10:116e201f7d89 575 // precompute R and R^2
feb11 10:116e201f7d89 576 uint32_t r = 8*modulus.size;
feb11 10:116e201f7d89 577
feb11 10:116e201f7d89 578 // convert a in montgomery world
feb11 11:2f16a220ebbb 579 BigInt tmp2 = 1;
feb11 13:d0b4d7cfeb98 580 tmp2 <<= r;
feb11 11:2f16a220ebbb 581 tmp2 *= a;
feb11 12:a436f15b58b6 582 BigInt montA = tmp2%modulus;
feb11 10:116e201f7d89 583 BigInt tmp = montA;
feb11 9:3c191fa04f6e 584 BigInt tmpE = expn;
feb11 10:116e201f7d89 585 while(tmpE > 1)
feb11 9:3c191fa04f6e 586 {
feb11 10:116e201f7d89 587 tmp = montgomeryStep(montA, tmp, modulus, r);
feb11 10:116e201f7d89 588 --tmpE;
feb11 9:3c191fa04f6e 589 }
feb11 9:3c191fa04f6e 590
feb11 10:116e201f7d89 591 // convert a to normal world
feb11 10:116e201f7d89 592 return montgomeryStep(tmp, 1, modulus, r);
feb11 9:3c191fa04f6e 593 }
feb11 9:3c191fa04f6e 594
feb11 9:3c191fa04f6e 595 bool BigInt::isValid() const
feb11 9:3c191fa04f6e 596 {
feb11 9:3c191fa04f6e 597 return size != 0 && bits != 0;
feb11 9:3c191fa04f6e 598 }
feb11 9:3c191fa04f6e 599
feb11 11:2f16a220ebbb 600 void BigInt::print() const
feb11 0:9d554894785b 601 {
feb11 11:2f16a220ebbb 602 assert(isValid());
feb11 11:2f16a220ebbb 603
feb11 0:9d554894785b 604 printf("size: %d bytes\n", size);
feb11 0:9d554894785b 605 uint32_t n = num(size);
feb11 0:9d554894785b 606 for(int i = n-1; i >= 0; --i)
feb11 0:9d554894785b 607 {
feb11 1:00f2c40d46ed 608 printf("%08x ", bits[i]);
feb11 0:9d554894785b 609 }
feb11 0:9d554894785b 610 printf("\n");
feb11 0:9d554894785b 611 }
feb11 9:3c191fa04f6e 612
feb11 9:3c191fa04f6e 613 void BigInt::trim()
feb11 9:3c191fa04f6e 614 {
feb11 9:3c191fa04f6e 615 uint8_t *tmp = (uint8_t*)bits;
feb11 9:3c191fa04f6e 616 uint32_t newSize = size;
feb11 9:3c191fa04f6e 617 while(tmp[newSize-1] == 0 && newSize > 0)
feb11 9:3c191fa04f6e 618 newSize--;
feb11 10:116e201f7d89 619 if(newSize == 0)
feb11 10:116e201f7d89 620 newSize = 1;
feb11 9:3c191fa04f6e 621 if(num(newSize) < num(size))
feb11 10:116e201f7d89 622 {
feb11 9:3c191fa04f6e 623 bits = (uint32_t*)realloc(bits, sizeof(uint32_t)*num(newSize));
feb11 10:116e201f7d89 624 }
feb11 9:3c191fa04f6e 625 size = newSize;
feb11 9:3c191fa04f6e 626 }
feb11 9:3c191fa04f6e 627
feb11 11:2f16a220ebbb 628 uint32_t BigInt::numBits() const
feb11 10:116e201f7d89 629 {
feb11 10:116e201f7d89 630 assert(isValid());
feb11 12:a436f15b58b6 631
feb11 10:116e201f7d89 632 uint32_t n = (size-1)*8;
feb11 11:2f16a220ebbb 633 uint8_t a = bits[num(size)-1] >> ((size-1)%4)*8;
feb11 10:116e201f7d89 634 uint8_t tmp2 = 8;
feb11 11:2f16a220ebbb 635 while(!(a & 0x80))
feb11 10:116e201f7d89 636 {
feb11 11:2f16a220ebbb 637 a <<= 1;
feb11 10:116e201f7d89 638 --tmp2;
feb11 10:116e201f7d89 639 }
feb11 10:116e201f7d89 640 n += tmp2;
feb11 10:116e201f7d89 641
feb11 10:116e201f7d89 642 return n;
feb11 10:116e201f7d89 643 }