BigUnsigned CryptoScheme::genCoprime(const BigUnsigned& n) { BigUnsigned gen = random(n.bitLength()); while(gcd(gen, n) != 1) { gen = random(n.bitLength()); } return gen; }
BigUnsigned operator+(const BigUnsigned& one) const { BigUnsigned res; for (int i = 0, x = 0; i < max(len, one.len) + 1; i++) { int tmp = d[i] + one.d[i] + x; res.d[res.len++] = tmp % 10; x = tmp / 10; } res.Clean(); return res; }
BigUnsigned gcd(BigUnsigned a, BigUnsigned b) { BigUnsigned trash; // Neat in-place alternating technique. for (;;) { if (b.isZero()) return a; a.divideWithRemainder(b, trash); if (a.isZero()) return b; b.divideWithRemainder(a, trash); } }
BigUnsigned operator*(const BigUnsigned& one) { BigUnsigned res; res.len = len + one.len; for(int i = 0; i < len; i++) for(int j = 0; j < one.len; j++) res.d[i + j] += d[i] * one.d[j]; for(int i = 0; i < res.len - 1; i++) { res.d[i + 1] += res.d[i] / 10; res.d[i] %= 10; } res.Clean(); return res; }
BigUnsignedInABase::BigUnsignedInABase(const BigUnsigned &x, Base base) { // Check the base if (base < 2) throw "BigUnsignedInABase(BigUnsigned, Base): The base must be at least 2"; this->base = base; // Get an upper bound on how much space we need int maxBitLenOfX = x.getLength() * BigUnsigned::N; int minBitsPerDigit = bitLen(base) - 1; int maxDigitLenOfX = ceilingDiv(maxBitLenOfX, minBitsPerDigit); len = maxDigitLenOfX; // Another change to comply with `staying in bounds'. allocate(len); // Get the space BigUnsigned x2(x), buBase(base); Index digitNum = 0; while (!x2.isZero()) { // Get last digit. This is like `lastDigit = x2 % buBase, x2 /= buBase'. BigUnsigned lastDigit(x2); lastDigit.divideWithRemainder(buBase, x2); // Save the digit. blk[digitNum] = lastDigit.toUnsignedShort(); // Move on. We can't run out of room: we figured it out above. digitNum++; } // Save the actual length. len = digitNum; }
bool CryptoScheme::isProbablyPrime(const BigUnsigned& n) { if (n%2 == 0 || n==1) return n==2; for (int i = 0; i < 30; i++) { BigUnsigned a = random(n.bitLength()-1); if (modexp(a, n-1, n) != 1) return false; } return true; }
BigUnsigned modexp(const BigInteger &base, const BigUnsigned &exponent, const BigUnsigned &modulus) { BigUnsigned ans = 1, base2 = (base % modulus).getMagnitude(); BigUnsigned::Index i = exponent.bitLength(); // For each bit of the exponent, most to least significant... while (i > 0) { i--; // Square. ans *= ans; ans %= modulus; // And multiply if the bit is a 1. if (exponent.getBit(i)) { ans *= base2; ans %= modulus; } } return ans; }