// Cycle through integer types TEST(Exp, VarySubgroup) { const int pbits = 2048; for(int qbits = 160; qbits<pbits; qbits+=64) { // Generate prime CryptoPP::AutoSeededX917RNG<CryptoPP::AES> rng(false, true); CryptoPP::PrimeAndGenerator pand(1, rng, pbits, qbits); const CryptoPP::Integer two(2); double total = 0.0f; // Do 1000 exps for(int i=0; i<1000; i++) { CryptoPP::Integer v = a_exp_b_mod_c( pand.Generator(), CryptoPP::Integer(rng, two, pand.SubPrime(), CryptoPP::Integer::ANY), pand.Prime()); CryptoPP::Integer e(rng, two, pand.SubPrime(), CryptoPP::Integer::ANY); double start = QDateTime::currentMSecsSinceEpoch(); CryptoPP::Integer r = a_exp_b_mod_c(v, e, pand.Prime()); double end = QDateTime::currentMSecsSinceEpoch(); total += (end-start); } qDebug() << qbits << total; } }
void ElGamalDecryptor::RawDecrypt(const Integer &a, const Integer &b, Integer &m) const { if (x.BitCount()+20 < p.BitCount()) // if x is short m = b * EuclideanMultiplicativeInverse(a_exp_b_mod_c(a, x, p), p) % p; else // save a multiplicative inverse calculation m = b * a_exp_b_mod_c(a, p-1-x, p) % p; }
// the following two functions are based on code and comments provided by Preda Mihailescu static bool ProvePrime(const Integer &p, const Integer &q) { assert(p < q*q*q); assert(p % q == 1); // this is the Quisquater test. Numbers p having passed the Lucas - Lehmer test // for q and verifying p < q^3 can only be built up of two factors, both = 1 mod q, // or be prime. The next two lines build the discriminant of a quadratic equation // which holds iff p is built up of two factors (excercise ... ) Integer r = (p-1)/q; if (((r%q).Squared()-4*(r/q)).IsSquare()) return false; unsigned int primeTableSize; const word16 * primeTable = GetPrimeTable(primeTableSize); assert(primeTableSize >= 50); for (int i=0; i<50; i++) { Integer b = a_exp_b_mod_c(primeTable[i], r, p); if (b != 1) return a_exp_b_mod_c(b, q, p) == 1; } return false; }
static void rsadecrypt(Integer* key, Integer* m) { Integer xp = a_exp_b_mod_c(*m%key[AsymmCipher::PRIV_P],key[AsymmCipher::PRIV_D]%(key[AsymmCipher::PRIV_P]-Integer::One()),key[AsymmCipher::PRIV_P]); Integer xq = a_exp_b_mod_c(*m%key[AsymmCipher::PRIV_Q],key[AsymmCipher::PRIV_D]%(key[AsymmCipher::PRIV_Q]-Integer::One()),key[AsymmCipher::PRIV_Q]); if (xp > xq) *m = key[AsymmCipher::PRIV_Q]-(((xp-xq)*key[AsymmCipher::PRIV_U])%key[AsymmCipher::PRIV_Q]); else *m = ((xq-xp)*key[AsymmCipher::PRIV_U])%key[AsymmCipher::PRIV_Q]; *m = *m*key[AsymmCipher::PRIV_P]+xp; }
Integer Commiter::open() { Integer vp; vp = a_exp_b_mod_c( com.h, a_exp_b_mod_c(2, Integer::Power2(com.K) - com.l, phi), n); return vp; }
Integer ModularSquareRoot(const Integer &a, const Integer &p) { if (p%4 == 3) return a_exp_b_mod_c(a, (p+1)/4, p); Integer q=p-1; unsigned int r=0; while (q.IsEven()) { r++; q >>= 1; } Integer n=2; while (Jacobi(n, p) != -1) ++n; Integer y = a_exp_b_mod_c(n, q, p); Integer x = a_exp_b_mod_c(a, (q-1)/2, p); Integer b = (x.Squared()%p)*a%p; x = a*x%p; Integer tempb, t; while (b != 1) { unsigned m=0; tempb = b; do { m++; b = b.Squared()%p; if (m==r) return Integer::Zero(); } while (b != 1); t = y; for (unsigned i=0; i<r-m-1; i++) t = t.Squared()%p; y = t.Squared()%p; r = m; x = x*t%p; b = tempb*y%p; } assert(x.Squared()%p == a); return x; }
// Generate public value void DH::GeneratePublic(const byte* priv, byte* pub) { const word32 bc(p_.ByteCount()); Integer x(priv, bc); Integer y(a_exp_b_mod_c(g_, x, p_)); y.Encode(pub, bc); }
//-------------------------------------------------------------- //LinkableRingSignProver constructor check TEST(LinkableRingSignProverTest, DefaultArgs) { unsigned int n = 100, identity = 12; Integer g_in, p_in, q_in, private_key_in; vector<Integer> public_keys_in; GetGroupParameters(g_in, p_in, q_in); RandomPool rng; //set safe_NO for private key here. Integer SAFE_NO = 1231; //generate private_public keys for(unsigned int i = 1; i <= n; i++) { Integer a = Integer(rng, SAFE_NO, q_in - 1); if(i == 11) private_key_in = a; public_keys_in.push_back(a_exp_b_mod_c(g_in, a, p_in)); } LinkableRingSignProver P(n, identity, g_in, p_in, q_in, public_keys_in, private_key_in); EXPECT_EQ(P.num_members, n); EXPECT_EQ(P.g, g_in); EXPECT_EQ(P.q, q_in); EXPECT_EQ(P.p, p_in); vector<Integer>::iterator itr = public_keys_in.begin(); unsigned int j = 0; for(itr = public_keys_in.begin(); itr != public_keys_in.end(); itr++) { ASSERT_EQ(P.public_keys[j++], *itr); } }
// find order of a element mod (p1*p2) // p1 and p2 are safe primes static Integer find_order(const Integer &p1, const Integer &p2, const Integer &g) { Integer n = p1 * p2; Integer phi = (p1-1)*(p2-1); Integer q1 = (p1-1)/2; Integer q2 = (p2-2)/2; Integer order = phi; vector<Integer> primes; primes.push_back(q1); primes.push_back(q2); primes.push_back(2); for(Integer q: primes) { while(true) { Integer rest, quotient; Integer::Divide(rest, quotient, order, q); if (rest != 0) break; if (a_exp_b_mod_c(g, quotient, n) == 1) { order = quotient; } else break; } } return order; }
bool IsStrongProbablePrime(const Integer &n, const Integer &b) { if (n <= 3) return n==2 || n==3; assert(n>3 && b>1 && b<n-1); if ((n.IsEven() && n!=2) || GCD(b, n) != 1) return false; Integer nminus1 = (n-1); unsigned int a; // calculate a = largest power of 2 that divides (n-1) for (a=0; ; a++) if (nminus1.GetBit(a)) break; Integer m = nminus1>>a; Integer z = a_exp_b_mod_c(b, m, n); if (z==1 || z==nminus1) return true; for (unsigned j=1; j<a; j++) { z = z.Squared()%n; if (z==nminus1) return true; if (z==1) return false; } return false; }
vI Commiter::zk_4(const vI &commit_values) { if (commit_values.size() != com.K+1) { throw ProtocolException("invalid commit_values size"); } for(unsigned i = 1; i <= com.K; ++i) { if (!regular_verify(commits[i], commit_values[i])) { throw ProtocolException("regular commit didn't verify"); } } vI y(com.K+1); for(unsigned i = 1; i <= com.K; ++i) { Integer yi = a_times_b_mod_c( commit_values[i], a_exp_b_mod_c(2, Integer::Power2(i-1), order), order); yi += alpha[i]; yi %= order; y[i] = yi; } return y; }
void DL_GroupParameters_DSA::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg) { Integer p, q, g; if (alg.GetValue("Modulus", p) && alg.GetValue("SubgroupGenerator", g)) { q = alg.GetValueWithDefault("SubgroupOrder", ComputeGroupOrder(p)/2); } else { int modulusSize = 1024; alg.GetIntValue("ModulusSize", modulusSize) || alg.GetIntValue("KeySize", modulusSize); if (!DSA::IsValidPrimeLength(modulusSize)) throw InvalidArgument("DSA: not a valid prime length"); SecByteBlock seed(SHA::DIGESTSIZE); Integer h; int c; do { rng.GenerateBlock(seed, SHA::DIGESTSIZE); } while (!DSA::GeneratePrimes(seed, SHA::DIGESTSIZE*8, c, p, modulusSize, q)); do { h.Randomize(rng, 2, p-2); g = a_exp_b_mod_c(h, (p-1)/q, p); } while (g <= 1); } Initialize(p, q, g); }
//-------------------------------------------------------------- //GenerateGroupParameters TEST(GenerateGroupParametersTest, IntegerInputs) { Integer p, q, g; GetGroupParameters(g, p, q); EXPECT_EQ(1, a_exp_b_mod_c(g, q, p)); }
bool IsFermatProbablePrime(const Integer &n, const Integer &b) { if (n <= 3) return n==2 || n==3; assert(n>3 && b>1 && b<n-1); return a_exp_b_mod_c(b, n-1, n)==1; }
void BlumBlumShub::Seek(lword index) { Integer i(Integer::POSITIVE, index); i *= 8; Integer e = a_exp_b_mod_c (2, i / maxBits + 1, (p-1)*(q-1)); current = modn.Exponentiate(x0, e); bitsLeft = maxBits - i % maxBits; }
Ed25519 () { q = CryptoPP::Integer::Power2 (255) - CryptoPP::Integer (19); // 2^255-19 l = CryptoPP::Integer::Power2 (252) + CryptoPP::Integer ("27742317777372353535851937790883648493"); // 2^252 + 27742317777372353535851937790883648493 d = CryptoPP::Integer (-121665) * CryptoPP::Integer (121666).InverseMod (q); // -121665/121666 I = a_exp_b_mod_c (CryptoPP::Integer::Two (), (q - CryptoPP::Integer::One ()).DividedBy (4), q); B = DecodePoint (CryptoPP::Integer (4)*CryptoPP::Integer (5).InverseMod (q)); }
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; }
CryptoPP::Integer RecoverX (const CryptoPP::Integer& y) const { auto y2 = y.Squared (); auto xx = (y2 - CryptoPP::Integer::One())*(d*y2 + CryptoPP::Integer::One()).InverseMod (q); auto x = a_exp_b_mod_c (xx, (q + CryptoPP::Integer (3)).DividedBy (8), q); if (!(x.Squared () - xx).Modulo (q).IsZero ()) x = a_times_b_mod_c (x, I, q); if (x.IsOdd ()) x = q - x; return x; }
Integer MaurerProvablePrime(RandomNumberGenerator &rng, unsigned int bits) { const unsigned smallPrimeBound = 29, c_opt=10; Integer p; unsigned int primeTableSize; const word16 * primeTable = GetPrimeTable(primeTableSize); if (bits < smallPrimeBound) { do p.Randomize(rng, Integer::Power2(bits-1), Integer::Power2(bits)-1, Integer::ANY, 1, 2); while (TrialDivision(p, 1 << ((bits+1)/2))); } else { const unsigned margin = bits > 50 ? 20 : (bits-10)/2; double relativeSize; do relativeSize = pow(2.0, double(rng.GenerateWord32())/0xffffffff - 1); while (bits * relativeSize >= bits - margin); Integer a,b; Integer q = MaurerProvablePrime(rng, unsigned(bits*relativeSize)); Integer I = Integer::Power2(bits-2)/q; Integer I2 = I << 1; unsigned int trialDivisorBound = (unsigned int)STDMIN((unsigned long)primeTable[primeTableSize-1], (unsigned long)bits*bits/c_opt); bool success = false; while (!success) { p.Randomize(rng, I, I2, Integer::ANY); p *= q; p <<= 1; ++p; if (!TrialDivision(p, trialDivisorBound)) { a.Randomize(rng, 2, p-1, Integer::ANY); b = a_exp_b_mod_c(a, (p-1)/q, p); success = (GCD(b-1, p) == 1) && (a_exp_b_mod_c(b, q, p) == 1); } } } return p; }
bool DH::Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey) const { Integer w(otherPublicKey, PublicKeyLength()); if (validateOtherPublicKey && !(w > 1 && w < p && Jacobi(w, p) == 1)) return false; Integer s(privateKey, PrivateKeyLength()); Integer z = a_exp_b_mod_c(w, s, p); z.Encode(agreedValue, AgreedValueLength()); return true; }
vector<bool> Receiver::open(Integer vp) { Integer v = get_g(com.n, vp); Integer u = a_exp_b_mod_c(v, Integer::Power2(com.l), com.n); if (u != com.u) { throw ProtocolException("u != com.u"); } return decode(v); }
// generate a random prime p of the form 2*r*q+delta, where q is also prime PrimeAndGenerator::PrimeAndGenerator(signed int delta, RandomNumberGenerator &rng, unsigned int pbits, unsigned int qbits) { // no prime exists for delta = -1, qbits = 4, and pbits = 5 assert(qbits > 4); assert(pbits > qbits); Integer minQ = Integer::Power2(qbits-1); Integer maxQ = Integer::Power2(qbits) - 1; Integer minP = Integer::Power2(pbits-1); Integer maxP = Integer::Power2(pbits) - 1; do { q.Randomize(rng, minQ, maxQ, Integer::PRIME); } while (!p.Randomize(rng, minP, maxP, Integer::PRIME, delta%q, q)); // find a random g of order q if (delta==1) { do { Integer h(rng, 2, p-2, Integer::ANY); g = a_exp_b_mod_c(h, (p-1)/q, p); } while (g <= 1); assert(a_exp_b_mod_c(g, q, p)==1); } else { assert(delta==-1); do { Integer h(rng, 3, p-1, Integer::ANY); if (Jacobi(h*h-4, p)==1) continue; g = Lucas((p+1)/q, h, p); } while (g <= 2); assert(Lucas(q, g, p) == 2); } }
void B::cont_sig(ECPPoint Ks, Integer cs, byte *m, unsigned m_len){ kb.Randomize(common::rng(), Integer::One(), n-1); K = ec.Multiply(kb, Ks); r = K.x % n; if (r == 0) throw ProtocolException("r == 0"); Integer hi = hash_m_to_int(m, m_len, n.ByteCount()); Integer c1 = paillier.enc( a_times_b_mod_c(kb.InverseMod(n), hi, n) ); Integer t = a_times_b_mod_c(a_times_b_mod_c(kb.InverseMod(n), r, n), db, n); Integer c2 = a_times_b_mod_c(c1, a_exp_b_mod_c(cs, t, paillier.get_n2()), paillier.get_n2()); Integer u(common::rng(), Integer::Zero(), n*n - 1); cb = a_times_b_mod_c(c2, paillier.enc(u*n), paillier.get_n2()); }
vIvI Commiter::zk_2(const vector<RegularCommitment> &commits) { if (commits.size() != com.K+1) { throw ProtocolException("ERR zk_2 commits size"); } this->commits = commits; vector<Integer> z, w; alpha.resize(com.K+1); for(unsigned i = 1; i <= com.K; ++i) { alpha[i].Randomize(common::rng(), Integer::Zero(), order-1); } z.resize(com.K+1); w.resize(com.K+1); for(unsigned i = 1; i <= com.K; ++i) { z[i] = a_exp_b_mod_c(com.g, alpha[i], n); w[i] = a_exp_b_mod_c(com.W[i-1], alpha[i], n); } return vIvI(z, w); }
// Generate Agreement void DH::Agree(byte* agree, const byte* priv, const byte* otherPub, word32 otherSz) { const word32 bc(p_.ByteCount()); Integer x(priv, bc); Integer y; if (otherSz) y.Decode(otherPub, otherSz); else y.Decode(otherPub, bc); Integer z(a_exp_b_mod_c(y, x, p_)); z.Encode(agree, bc); }
void Receiver::zk_5(const vI &y) { if (y.size() != com.K+1) { throw ProtocolException("y size != K+1"); } for(unsigned i = 1; i <= com.K; ++i) { Integer zi = a_times_b_mod_c( a_exp_b_mod_c(com.g, y[i], com.n), a_exp_b_mod_c(com.W[i-1].InverseMod(com.n), commit_values[i], com.n), com.n); if (zi != zw.first[i]) { throw ProtocolException("zi verification failed"); } Integer wi = a_times_b_mod_c( a_exp_b_mod_c(com.W[i-1], y[i], com.n), a_exp_b_mod_c(com.W[i].InverseMod(com.n), commit_values[i], com.n), com.n); if (wi != zw.second[i]) { throw ProtocolException("wi verification failed"); } } }
vector<bool> Receiver::force_open_smart() { Integer v = com.W[com.K-1]; for(Integer i = 0; i < Integer::Power2(com.K-1) - com.l; ++i) { v = a_times_b_mod_c(v, v, com.n); } Integer u = a_exp_b_mod_c(v, Integer::Power2(com.l), com.n); if (u != com.u) { throw ProtocolException("u != com.u"); } return decode(v); }
// computes g as h ** ( mult (qi ** n) ) // where qi are all primes smaller than B Integer get_g(const Integer &n, const Integer &h) { const word16 *primes; unsigned available_primes; // get the array of primes primes = GetPrimeTable(available_primes); if (available_primes <= B) { throw ProtocolException("not enough primes"); } Integer mult = 1; for(int i = 0; primes[i] < B; ++i) { mult *= exp(primes[i], BITS); } return a_exp_b_mod_c(h, mult, n); }
word32 DSA_Signer::Sign(const byte* sha_digest, byte* sig, RandomNumberGenerator& rng) { const Integer& p = key_.GetModulus(); const Integer& q = key_.GetSubGroupOrder(); const Integer& g = key_.GetSubGroupGenerator(); const Integer& x = key_.GetPrivatePart(); byte* tmpPtr = sig; // initial signature output Integer k(rng, 1, q - 1); r_ = a_exp_b_mod_c(g, k, p); r_ %= q; Integer H(sha_digest, SHA::DIGEST_SIZE); // sha Hash(m) Integer kInv = k.InverseMod(q); s_ = (kInv * (H + x*r_)) % q; if (!(!!r_ && !!s_)) return -1; int rSz = r_.ByteCount(); int tmpSz = rSz; while (tmpSz++ < SHA::DIGEST_SIZE) { *sig++ = 0; } r_.Encode(sig, rSz); sig = tmpPtr + SHA::DIGEST_SIZE; // advance sig output to s int sSz = s_.ByteCount(); tmpSz = sSz; while (tmpSz++ < SHA::DIGEST_SIZE) { *sig++ = 0; } s_.Encode(sig, sSz); return 40; }
word32 DSA_Signer::Sign(const byte* sha_digest, byte* sig, RandomNumberGenerator& rng) { const Integer& p = key_.GetModulus(); const Integer& q = key_.GetSubGroupOrder(); const Integer& g = key_.GetSubGroupGenerator(); const Integer& x = key_.GetPrivatePart(); Integer k(rng, 1, q - 1); r_ = a_exp_b_mod_c(g, k, p); r_ %= q; Integer H(sha_digest, SHA::DIGEST_SIZE); // sha Hash(m) Integer kInv = k.InverseMod(q); s_ = (kInv * (H + x*r_)) % q; if (!(!!r_ && !!s_)) return (word32) -1; int rSz = r_.ByteCount(); if (rSz == 19) { sig[0] = 0; sig++; } r_.Encode(sig, rSz); int sSz = s_.ByteCount(); if (sSz == 19) { sig[rSz] = 0; sig++; } s_.Encode(sig + rSz, sSz); return 40; }