int main(){ int t, n, i, j=1, p, q, x1 ,x2; sieve(); primes[0]=2; for(i=3; i<MAXSIEVE; i+=2)if(isPrime(i))primes[j++]=i; scanf("%d", &t); while(t--){ scanf("%d", &n); for(i=0; primes[i]<n; i++)if(n%primes[i]==0){p=primes[i];break;} q=n/primes[i]; congruences[0][0]=0;congruences[0][1]=p; congruences[1][0]=1;congruences[1][1]=q; x1 = (int)CRT(2); congruences[0][0]=0;congruences[0][1]=q; congruences[1][0]=1;congruences[1][1]=p; x2 = (int)CRT(2); printf("0 1"); x1=x1%n; x2=x2%n; while(x1<0)x1+=n; while(x2<0)x2+=n; printf(" %d %d\n", (x1<x2)?x1:x2, (x1>x2)?x1:x2); } return 0; }
Integer InvertibleRabinFunction::CalculateInverse(const Integer &in) const { Integer cp=in%p, cq=in%q; int jp = Jacobi(cp, p); int jq = Jacobi(cq, q); if (jq==-1) { cp = cp*EuclideanMultiplicativeInverse(r, p)%p; cq = cq*EuclideanMultiplicativeInverse(r, q)%q; } if (jp==-1) { cp = cp*EuclideanMultiplicativeInverse(s, p)%p; cq = cq*EuclideanMultiplicativeInverse(s, q)%q; } cp = ModularSquareRoot(cp, p); cq = ModularSquareRoot(cq, q); if (jp==-1) cp = p-cp; Integer out = CRT(cq, q, cp, p, u); if ((jq==-1 && out.IsEven()) || (jq==1 && out.IsOdd())) out = n-out; return out; }
Integer InvertibleRabinFunction::CalculateInverse(const Integer &in) const { DoQuickSanityCheck(); Integer cp=in%m_p, cq=in%m_q; int jp = Jacobi(cp, m_p); int jq = Jacobi(cq, m_q); if (jq==-1) { cp = cp*EuclideanMultiplicativeInverse(m_r, m_p)%m_p; cq = cq*EuclideanMultiplicativeInverse(m_r, m_q)%m_q; } if (jp==-1) { cp = cp*EuclideanMultiplicativeInverse(m_s, m_p)%m_p; cq = cq*EuclideanMultiplicativeInverse(m_s, m_q)%m_q; } cp = ModularSquareRoot(cp, m_p); cq = ModularSquareRoot(cq, m_q); if (jp==-1) cp = m_p-cp; Integer out = CRT(cq, m_q, cp, m_p, m_u); if ((jq==-1 && out.IsEven()) || (jq==1 && out.IsOdd())) out = m_n-out; return out; }
void SerialMonitor::ReadSerialPort(void) { if (serialPort.isOpen()) { QByteArray bytes = serialPort.readAll(); if (ui.btnPause->isChecked() == false) { CRT(QString(bytes)); } //ui.plainTextEdit->insertPlainText(QString(bytes)); /*QByteArray bytes; int size = serialPort.bytesAvailable(); bytes.resize(size); serialPort.read(bytes.data(), bytes.size()); //bytes = serialPort.readAll(); int count = bytes.count(); QString text = ""; for (int i=0; i < count; i++) { unsigned char byte = bytes[i]; if ( (byte == '\n') || (byte == '\r')) { CRT(text); text = ""; } else { text += byte; } } if (text.length() > 0) { CRT(text); }*/ } }
void main() { int x,y,M; printf("Enter x & y and Modulus: "); scanf("%d%d%d",&x,&y,&M); printf("Mod Value: %d",CRT(x,y,M)); getche(); }
// Calculate fast decryption with chinese remainder and pre-computed values void paillier_priv::D (bigint &m, const bigint &msg) const { #if _PAILLIER_CRT_ // mq = Lq (msg^a mod q^2) hq mod q bigint mq; if (fast) mq = powm (msg, a, qsq); else mq = powm (msg, q1, qsq); // Compute Lq (m) mq -= 1; mq *= lq; mq %= two_q; m %= q; mq *= hq; mq %= q; // mp = Lp (msg^a mod p^2) hp mod p if (fast) m = powm (msg, a, psq); else m = powm (msg, p1, psq); // Compute L_p(m) m -= 1; m *= lp; m %= two_p; m %= p; m *= hp; m %= p; // Recombine modulo residues CRT (m, mq); #else /* PAILLIER_CRT */ if (fast) m = powm (msg, a, nsq); else m = powm (msg, k, nsq); m -= 1; m *= ln; m %= two_n; m %= n; m *= hn; m %= n; #endif }
bool SerialMonitor::OpenPort(QString port, QString speed) { if (serialPort.isOpen()) { return true; } portId = port; portSpeed = speed; //CRT("BAUD: " + ui.cbSpeed->currentText() + "\n\r"); serialPort.setPortName(portId); //ui.cbSpeed->setCurrentText(speed); PrepareSerialPort(portId, portSpeed); /*if (PrepareSerialPort(portId, portSpeed) == false) { CRT(">> Failed to open serial port [" + portId + "] at " + portSpeed + "!\n\r"); return false; }*/ if (serialPort.open(QIODevice::ReadWrite)) { serialPort.setFlowControl(QSerialPort::NoFlowControl); serialPort.setBaudRate(portSpeed.toInt()); serialPort.setParity(QSerialPort::NoParity); serialPort.setStopBits(QSerialPort::OneStop); serialPort.setDataBits(QSerialPort::Data8); //serialPort.setDataTerminalReady(true); //serialPort.setRequestToSend(true); CRT(">> Serial port [" + portId + "] open at " + ui.cbSpeed->currentText() + "!\n\r"); connect (&serialPort, SIGNAL(readyRead()), this, SLOT(ReadSerialPort())); return true; } else { CRT(">> Failed to open serial port [" + portId + "] at " + ui.cbSpeed->currentText() + "!\n\r"); return false; } }
int main() { long long n; long long a[15],m[15]; scanf("%lld",&n); for(long long i=0;i<n;i++) { scanf("%lld%lld",&m[i],&a[i]); } printf("%lld\n",CRT(a,m,n)); return 0; }
Integer ModularRoot(const Integer &a, const Integer &dp, const Integer &dq, const Integer &p, const Integer &q, const Integer &u) { Integer p2, q2; #pragma omp parallel #pragma omp sections { #pragma omp section p2 = ModularExponentiation((a % p), dp, p); #pragma omp section q2 = ModularExponentiation((a % q), dq, q); } return CRT(p2, p, q2, q, u); }
bool SerialMonitor::ClosePort(void) { if (serialPort.isOpen() == false) { return true; } disconnect (&serialPort, SIGNAL(readyRead()), this, SLOT(ReadSerialPort())); serialPort.clear(); QThread::msleep(100); serialPort.close(); if (serialPort.isOpen()) { CRT(">> Failed: Could not close the serial port [" + portId + "]\n\r"); return false; } else { CRT(">> Serial port [" + portId + "] closed!\n\r"); return true; } }
void XTR_FindPrimesAndGenerator(RandomNumberGenerator &rng, Integer &p, Integer &q, GFP2Element &g, unsigned int pbits, unsigned int qbits) { CRYPTOPP_ASSERT(qbits > 9); // no primes exist for pbits = 10, qbits = 9 CRYPTOPP_ASSERT(pbits > qbits); const Integer minQ = Integer::Power2(qbits - 1); const Integer maxQ = Integer::Power2(qbits) - 1; const Integer minP = Integer::Power2(pbits - 1); const Integer maxP = Integer::Power2(pbits) - 1; top: Integer r1, r2; do { (void)q.Randomize(rng, minQ, maxQ, Integer::PRIME, 7, 12); // Solution always exists because q === 7 mod 12. (void)SolveModularQuadraticEquation(r1, r2, 1, -1, 1, q); // I believe k_i, r1 and r2 are being used slightly different than the // paper's algorithm. I believe it is leading to the failed asserts. // Just make the assert part of the condition. if(!p.Randomize(rng, minP, maxP, Integer::PRIME, CRT(rng.GenerateBit() ? r1 : r2, q, 2, 3, EuclideanMultiplicativeInverse(p, 3)), 3 * q)) { continue; } } while (((p % 3U) != 2) || (((p.Squared() - p + 1) % q).NotZero())); // CRYPTOPP_ASSERT((p % 3U) == 2); // CRYPTOPP_ASSERT(((p.Squared() - p + 1) % q).IsZero()); GFP2_ONB<ModularArithmetic> gfp2(p); GFP2Element three = gfp2.ConvertIn(3), t; while (true) { g.c1.Randomize(rng, Integer::Zero(), p-1); g.c2.Randomize(rng, Integer::Zero(), p-1); t = XTR_Exponentiate(g, p+1, p); if (t.c1 == t.c2) continue; g = XTR_Exponentiate(g, (p.Squared()-p+1)/q, p); if (g != three) break; } if (XTR_Exponentiate(g, q, p) != three) goto top; // CRYPTOPP_ASSERT(XTR_Exponentiate(g, q, p) == three); }
void mul(int *A, int *B, int *C, int n) { static int A1[maxN], B1[maxN], C1[maxN]; int N = init(n); memset(A1, 0, sizeof(*A1) * N); memset(B1, 0, sizeof(*B1) * N); memset(C1, 0, sizeof(*C1) * N); memset(C, 0, sizeof(*C) * N); memcpy(A1, A, sizeof(*A) * n); memcpy(B1, B, sizeof(*B) * n); NTT(A1, P1, E1, N); NTT(B1, P1, E1, N); for (int i = 0; i < N; ++i) C1[i] = (LL)A1[i] * B1[i] % P1; NTT(C1, P1, F1, N); for (int i = 0; i < N; ++i) C1[i] = (LL)C1[i] * I1 % P1; NTT(A, P2, E2, N); NTT(B, P2, E2, N); for (int i = 0; i < N; ++i) C[i] = (LL)A[i] * B[i] % P2; NTT(C, P2, F2, N); for (int i = 0; i < N; ++i) C[i] = (LL)C[i] * I2 % P2; for (int i = 0; i < N; ++i) C[i] = CRT(C1[i], C[i]); for (int i = n; i < N; ++i) C[i] = 0; }
unsigned int BlumGoldwasserPrivateKey::Decrypt(const byte *input, unsigned int cipherTextLength, byte *output) { if (cipherTextLength <= modulusLen) return 0; Integer xt(input, modulusLen); PublicBlumBlumShub bbs(n, Integer::Zero()); unsigned int plainTextLength = cipherTextLength - modulusLen; unsigned int t = ((plainTextLength)*8 + bbs.maxBits-1) / bbs.maxBits; Integer dp = a_exp_b_mod_c((p+1)/4, t, p-1); Integer dq = a_exp_b_mod_c((q+1)/4, t, q-1); Integer xp = a_exp_b_mod_c(xt%p, dp, p); Integer xq = a_exp_b_mod_c(xt%q, dq, q); bbs.current = CRT(xp, p, xq, q, u); bbs.bitsLeft = bbs.maxBits; bbs.ProcessString(output, input+modulusLen, plainTextLength); return plainTextLength; }
Integer InvertibleRabinFunction::CalculateInverse(RandomNumberGenerator &rng, const Integer &in) const { DoQuickSanityCheck(); ModularArithmetic modn(m_n); Integer r(rng, Integer::One(), m_n - Integer::One()); r = modn.Square(r); Integer r2 = modn.Square(r); Integer c = modn.Multiply(in, r2); // blind Integer cp=c%m_p, cq=c%m_q; int jp = Jacobi(cp, m_p); int jq = Jacobi(cq, m_q); if (jq==-1) { cp = cp*EuclideanMultiplicativeInverse(m_r, m_p)%m_p; cq = cq*EuclideanMultiplicativeInverse(m_r, m_q)%m_q; } if (jp==-1) { cp = cp*EuclideanMultiplicativeInverse(m_s, m_p)%m_p; cq = cq*EuclideanMultiplicativeInverse(m_s, m_q)%m_q; } cp = ModularSquareRoot(cp, m_p); cq = ModularSquareRoot(cq, m_q); if (jp==-1) cp = m_p-cp; Integer out = CRT(cq, m_q, cp, m_p, m_u); out = modn.Divide(out, r); // unblind if ((jq==-1 && out.IsEven()) || (jq==1 && out.IsOdd())) out = m_n-out; return out; }
Integer InverseLucas(const Integer &e, const Integer &m, const Integer &p, const Integer &q, const Integer &u) { Integer d = (m*m-4); Integer p2, q2; #pragma omp parallel #pragma omp sections { #pragma omp section { p2 = p-Jacobi(d,p); p2 = Lucas(EuclideanMultiplicativeInverse(e,p2), m, p); } #pragma omp section { q2 = q-Jacobi(d,q); q2 = Lucas(EuclideanMultiplicativeInverse(e,q2), m, q); } } return CRT(p2, p, q2, q, u); }
//FIXME: both the reduction from powerful to the individual primes and // the CRT back to poly can be made more efficient void PowerfulDCRT::powerfulToZZX(ZZX& poly, const Vec<ZZ>& powerful, IndexSet set) const { zz_pBak bak; bak.save(); // backup NTL's current modulus if (empty(set)) set = IndexSet(0, pConvVec.length()-1); clear(poly); // poly.SetLength(powerful.length()); ZZ product = conv<ZZ>(1L); for (long i = set.first(); i <= set.last(); i = set.next(i)) { pConvVec[i].restoreModulus(); // long newPrime = zz_p::modulus(); HyperCube<zz_p> oneRowPwrfl(indexes.shortSig); conv(oneRowPwrfl.getData(), powerful); // reduce and convert to Vec<zz_p> zz_pX oneRowPoly; pConvVec[i].powerfulToPoly(oneRowPoly, oneRowPwrfl); CRT(poly, product, oneRowPoly); // NTL :-) } poly.normalize(); }
void XTR_FindPrimesAndGenerator(RandomNumberGenerator &rng, Integer &p, Integer &q, GFP2Element &g, unsigned int pbits, unsigned int qbits) { assert(qbits > 9); // no primes exist for pbits = 10, qbits = 9 assert(pbits > qbits); const Integer minQ = Integer::Power2(qbits - 1); const Integer maxQ = Integer::Power2(qbits) - 1; const Integer minP = Integer::Power2(pbits - 1); const Integer maxP = Integer::Power2(pbits) - 1; Integer r1, r2; do { bool qFound = q.Randomize(rng, minQ, maxQ, Integer::PRIME, 7, 12); CRYPTOPP_UNUSED(qFound); assert(qFound); bool solutionsExist = SolveModularQuadraticEquation(r1, r2, 1, -1, 1, q); CRYPTOPP_UNUSED(solutionsExist); assert(solutionsExist); } while (!p.Randomize(rng, minP, maxP, Integer::PRIME, CRT(rng.GenerateBit()?r1:r2, q, 2, 3, EuclideanMultiplicativeInverse(p, 3)), 3*q)); assert(((p.Squared() - p + 1) % q).IsZero()); GFP2_ONB<ModularArithmetic> gfp2(p); GFP2Element three = gfp2.ConvertIn(3), t; while (true) { g.c1.Randomize(rng, Integer::Zero(), p-1); g.c2.Randomize(rng, Integer::Zero(), p-1); t = XTR_Exponentiate(g, p+1, p); if (t.c1 == t.c2) continue; g = XTR_Exponentiate(g, (p.Squared()-p+1)/q, p); if (g != three) break; } assert(XTR_Exponentiate(g, q, p) == three); }
void inv(ZZ& d_out, mat_ZZ& x_out, const mat_ZZ& A, long deterministic) { long n = A.NumRows(); if (A.NumCols() != n) Error("solve: nonsquare matrix"); if (n == 0) { set(d_out); x_out.SetDims(0, 0); return; } zz_pBak zbak; zbak.save(); ZZ_pBak Zbak; Zbak.save(); mat_ZZ x(INIT_SIZE, n, n); ZZ d, d1; ZZ d_prod, x_prod; set(d_prod); set(x_prod); long d_instable = 1; long x_instable = 1; long gp_cnt = 0; long check = 0; mat_ZZ y; long i; long bound = 2+DetBound(A); for (i = 0; ; i++) { if ((check || IsZero(d)) && !d_instable) { if (NumBits(d_prod) > bound) { break; } else if (!deterministic && bound > 1000 && NumBits(d_prod) < 0.25*bound) { ZZ P; long plen = 90 + NumBits(max(bound, NumBits(d))); GenPrime(P, plen, 90 + 2*NumBits(gp_cnt++)); ZZ_p::init(P); mat_ZZ_p AA; conv(AA, A); ZZ_p dd; determinant(dd, AA); if (CRT(d, d_prod, rep(dd), P)) d_instable = 1; else break; } } zz_p::FFTInit(i); long p = zz_p::modulus(); mat_zz_p AA; conv(AA, A); if (!check) { mat_zz_p xx; zz_p dd; inv(dd, xx, AA); d_instable = CRT(d, d_prod, rep(dd), p); if (!IsZero(dd)) { mul(xx, xx, dd); x_instable = CRT(x, x_prod, xx); } else x_instable = 1; if (!d_instable && !x_instable) { mul(y, x, A); if (IsDiag(y, n, d)) { d1 = d; check = 1; } } } else { zz_p dd; determinant(dd, AA); d_instable = CRT(d, d_prod, rep(dd), p); } } if (check && d1 != d) { mul(x, x, d); ExactDiv(x, d1); } d_out = d; if (check) x_out = x; zbak.restore(); Zbak.restore(); }
void* worker(void* arg) { State& state = *((State*) arg); long k = state.k; #ifdef USE_THREADS pthread_mutex_lock(&state.lock); #endif while (1) { if (state.next * BLOCK_SIZE < state.bound) { // need to generate more modular data long next = state.next++; #ifdef USE_THREADS pthread_mutex_unlock(&state.lock); #endif Item* item = new Item; mpz_set_ui(item->modulus, 1); mpz_set_ui(item->residue, 0); for (long p = max(5, state.table->next_prime(next * BLOCK_SIZE)); p < state.bound && p < (next+1) * BLOCK_SIZE; p = state.table->next_prime(p)) { if (k % (p-1) == 0) continue; // compute B_k mod p long b = bern_modp(p, k); // CRT into running total long x = MulMod(SubMod(b, mpz_fdiv_ui(item->residue, p), p), InvMod(mpz_fdiv_ui(item->modulus, p), p), p); mpz_addmul_ui(item->residue, item->modulus, x); mpz_mul_ui(item->modulus, item->modulus, p); } #ifdef USE_THREADS pthread_mutex_lock(&state.lock); #endif state.items.insert(item); } else { // all modular data has been generated if (state.items.size() <= 1) { // no more CRTs for this thread to perform #ifdef USE_THREADS pthread_mutex_unlock(&state.lock); #endif return NULL; } // CRT two smallest items together Item* item1 = *(state.items.begin()); state.items.erase(state.items.begin()); Item* item2 = *(state.items.begin()); state.items.erase(state.items.begin()); #ifdef USE_THREADS pthread_mutex_unlock(&state.lock); #endif Item* item3 = CRT(item1, item2); delete item1; delete item2; #ifdef USE_THREADS pthread_mutex_lock(&state.lock); #endif state.items.insert(item3); } } }
void determinant(ZZ& rres, const mat_ZZ& a, long deterministic) { long n = a.NumRows(); if (a.NumCols() != n) Error("determinant: nonsquare matrix"); if (n == 0) { set(rres); return; } zz_pBak zbak; zbak.save(); ZZ_pBak Zbak; Zbak.save(); long instable = 1; long gp_cnt = 0; long bound = 2+DetBound(a); ZZ res, prod; clear(res); set(prod); long i; for (i = 0; ; i++) { if (NumBits(prod) > bound) break; if (!deterministic && !instable && bound > 1000 && NumBits(prod) < 0.25*bound) { ZZ P; long plen = 90 + NumBits(max(bound, NumBits(res))); GenPrime(P, plen, 90 + 2*NumBits(gp_cnt++)); ZZ_p::init(P); mat_ZZ_p A; conv(A, a); ZZ_p t; determinant(t, A); if (CRT(res, prod, rep(t), P)) instable = 1; else break; } zz_p::FFTInit(i); long p = zz_p::modulus(); mat_zz_p A; conv(A, a); zz_p t; determinant(t, A); instable = CRT(res, prod, rep(t), p); } rres = res; zbak.restore(); Zbak.restore(); }
bool FirstPrime(Integer &p, const Integer &max, const Integer &equiv, const Integer &mod, const PrimeSelector *pSelector) { assert(!equiv.IsNegative() && equiv < mod); Integer gcd = GCD(equiv, mod); if (gcd != Integer::One()) { // the only possible prime p such that p%mod==equiv where GCD(mod,equiv)!=1 is GCD(mod,equiv) if (p <= gcd && gcd <= max && IsPrime(gcd) && (!pSelector || pSelector->IsAcceptable(gcd))) { p = gcd; return true; } else return false; } unsigned int primeTableSize; const word16 * primeTable = GetPrimeTable(primeTableSize); if (p <= primeTable[primeTableSize-1]) { const word16 *pItr; --p; if (p.IsPositive()) pItr = std::upper_bound(primeTable, primeTable+primeTableSize, (word)p.ConvertToLong()); else pItr = primeTable; while (pItr < primeTable+primeTableSize && !(*pItr%mod == equiv && (!pSelector || pSelector->IsAcceptable(*pItr)))) ++pItr; if (pItr < primeTable+primeTableSize) { p = *pItr; return p <= max; } p = primeTable[primeTableSize-1]+1; } assert(p > primeTable[primeTableSize-1]); if (mod.IsOdd()) return FirstPrime(p, max, CRT(equiv, mod, 1, 2, 1), mod<<1, pSelector); p += (equiv-p)%mod; if (p>max) return false; PrimeSieve sieve(p, max, mod); while (sieve.NextCandidate(p)) { if ((!pSelector || pSelector->IsAcceptable(p)) && FastProbablePrimeTest(p) && IsPrime(p)) return true; } return false; }
void CharPoly(ZZX& gg, const mat_ZZ& a, long deterministic) { long n = a.NumRows(); if (a.NumCols() != n) LogicError("CharPoly: nonsquare matrix"); if (n == 0) { set(gg); return; } if (n == 1) { ZZ t; SetX(gg); negate(t, a(1, 1)); SetCoeff(gg, 0, t); return; } long bound = 2 + CharPolyBound(a); zz_pBak bak; bak.save(); ZZ_pBak bak1; bak1.save(); ZZX g; ZZ prod; clear(g); set(prod); long i; long instable = 1; long gp_cnt = 0; for (i = 0; ; i++) { if (NumBits(prod) > bound) break; if (!deterministic && !instable && bound > 1000 && NumBits(prod) < 0.25*bound) { long plen = 90 + NumBits(max(bound, MaxBits(g))); ZZ P; GenPrime(P, plen, 90 + 2*NumBits(gp_cnt++)); ZZ_p::init(P); mat_ZZ_p A; ZZ_pX G; conv(A, a); CharPoly(G, A); if (CRT(g, prod, G)) instable = 1; else break; } zz_p::FFTInit(i); mat_zz_p A; zz_pX G; conv(A, a); CharPoly(G, A); instable = CRT(g, prod, G); } gg = g; bak.restore(); bak1.restore(); }
Integer CRT(const Integer &xp, const Integer &p, const Integer &xq, const Integer &q) { return CRT(xp, p, xq, q, EuclideanMultiplicativeInverse(p, q)); }
bool FirstPrime(Integer &p, const Integer &max, const Integer &equiv, const Integer &mod) { assert(!equiv.IsNegative() && equiv < mod); Integer gcd = GCD(equiv, mod); if (gcd != Integer::One()) { // the only possible prime p such that p%mod==equiv where GCD(mod,equiv)!=1 is GCD(mod,equiv) if (p <= gcd && gcd <= max && IsPrime(gcd)) { p = gcd; return true; } else return false; } BuildPrimeTable(); if (p <= primeTable[primeTableSize-1]) { word *pItr; --p; if (p.IsPositive()) pItr = std::upper_bound(primeTable, primeTable+primeTableSize, p.ConvertToLong()); else pItr = primeTable; while (pItr < primeTable+primeTableSize && *pItr%mod != equiv) ++pItr; if (pItr < primeTable+primeTableSize) { p = *pItr; return p <= max; } p = primeTable[primeTableSize-1]+1; } assert(p > primeTable[primeTableSize-1]); if (mod.IsOdd()) return FirstPrime(p, max, CRT(equiv, mod, 1, 2, 1), mod<<1); p += (equiv-p)%mod; if (p>max) return false; PrimeSieve sieve(p, max, mod); while (sieve.NextCandidate(p)) { if (FastProbablePrimeTest(p) && IsPrime(p)) return true; } return false; }
NTL_START_IMPL void CharPolyMod(ZZX& gg, const ZZX& a, const ZZX& f, long deterministic) { if (!IsOne(LeadCoeff(f)) || deg(f) < 1 || deg(a) >= deg(f)) Error("CharPolyMod: bad args"); if (IsZero(a)) { clear(gg); SetCoeff(gg, deg(f)); return; } long bound = 2 + CharPolyBound(a, f); long gp_cnt = 0; zz_pBak bak; bak.save(); ZZ_pBak bak1; bak1.save(); ZZX g; ZZ prod; clear(g); set(prod); long i; long instable = 1; for (i = 0; ; i++) { if (NumBits(prod) > bound) break; if (!deterministic && !instable && bound > 1000 && NumBits(prod) < 0.25*bound) { long plen = 90 + NumBits(max(bound, MaxBits(g))); ZZ P; GenPrime(P, plen, 90 + 2*NumBits(gp_cnt++)); ZZ_p::init(P); ZZ_pX G, A, F; conv(A, a); conv(F, f); CharPolyMod(G, A, F); if (CRT(g, prod, G)) instable = 1; else break; } zz_p::FFTInit(i); zz_pX G, A, F; conv(A, a); conv(F, f); CharPolyMod(G, A, F); instable = CRT(g, prod, G); } gg = g; bak.restore(); bak1.restore(); }
// no need to do blinding because RW is only used for signatures DoQuickSanityCheck(); Integer cp=in%m_p, cq=in%m_q; if (Jacobi(cp, m_p) * Jacobi(cq, m_q) != 1) { cp = cp%2 ? (cp+m_p) >> 1 : cp >> 1; cq = cq%2 ? (cq+m_q) >> 1 : cq >> 1; } cp = ModularSquareRoot(cp, m_p); cq = ModularSquareRoot(cq, m_q); Integer out = CRT(cq, m_q, cp, m_p, m_u); return STDMIN(out, m_n-out); } bool InvertibleRWFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const { bool pass = RWFunction::Validate(rng, level); pass = pass && m_p > Integer::One() && m_p%8 == 3 && m_p < m_n; pass = pass && m_q > Integer::One() && m_q%8 == 7 && m_q < m_n; pass = pass && m_u.IsPositive() && m_u < m_p; if (level >= 1) { pass = pass && m_p * m_q == m_n; pass = pass && m_u * m_q % m_p == 1; }
Vector::Vector(const Vector& obj) : m_size(obj.m_size) , m_data(new int[obj.m_size]) { CRT("Copy constructor"); std::copy(obj.m_data, obj.m_data + obj.m_size, m_data); }