Integer Lucas(const Integer &e, const Integer &pIn, const Integer &n) { unsigned i = e.BitCount(); if (i==0) return 2; MontgomeryRepresentation m(n); Integer p=m.ConvertIn(pIn%n), two=m.ConvertIn(2); Integer v=p, v1=m.Subtract(m.Square(p), two); i--; while (i--) { if (e.GetBit(i)) { // v = (v*v1 - p) % m; v = m.Subtract(m.Multiply(v,v1), p); // v1 = (v1*v1 - 2) % m; v1 = m.Subtract(m.Square(v1), two); } else { // v1 = (v*v1 - p) % m; v1 = m.Subtract(m.Multiply(v,v1), p); // v = (v*v - 2) % m; v = m.Subtract(m.Square(v), two); } } return m.ConvertOut(v); }
GFP2Element XTR_Exponentiate(const GFP2Element &b, const Integer &e, const Integer &p) { unsigned int bitCount = e.BitCount(); if (bitCount == 0) return GFP2Element(-3, -3); // find the lowest bit of e that is 1 unsigned int lowest1bit; for (lowest1bit=0; e.GetBit(lowest1bit) == 0; lowest1bit++) {} GFP2_ONB<MontgomeryRepresentation> gfp2(p); GFP2Element c = gfp2.ConvertIn(b); GFP2Element cp = gfp2.PthPower(c); GFP2Element S[5] = {gfp2.ConvertIn(3), c, gfp2.SpecialOperation1(c)}; // do all exponents bits except the lowest zeros starting from the top unsigned int i; for (i = e.BitCount() - 1; i>lowest1bit; i--) { if (e.GetBit(i)) { gfp2.RaiseToPthPower(S[0]); gfp2.Accumulate(S[0], gfp2.SpecialOperation2(S[2], c, S[1])); S[1] = gfp2.SpecialOperation1(S[1]); S[2] = gfp2.SpecialOperation1(S[2]); S[0].swap(S[1]); } else { gfp2.RaiseToPthPower(S[2]); gfp2.Accumulate(S[2], gfp2.SpecialOperation2(S[0], cp, S[1])); S[1] = gfp2.SpecialOperation1(S[1]); S[0] = gfp2.SpecialOperation1(S[0]); S[2].swap(S[1]); } } // now do the lowest zeros while (i--) S[1] = gfp2.SpecialOperation1(S[1]); return gfp2.ConvertOut(S[1]); }
bool DSA::GeneratePrimes(const byte *seedIn, unsigned int g, int &counter, Integer &p, unsigned int L, Integer &q, bool useInputCounterValue) { assert(g%8 == 0); SHA sha; SecByteBlock seed(seedIn, g/8); SecByteBlock U(SHA::DIGESTSIZE); SecByteBlock temp(SHA::DIGESTSIZE); SecByteBlock W(((L-1)/160+1) * SHA::DIGESTSIZE); const int n = (L-1) / 160; const int b = (L-1) % 160; Integer X; sha.CalculateDigest(U, seed, g/8); for (int i=g/8-1, carry=true; i>=0 && carry; i--) carry=!++seed[i]; sha.CalculateDigest(temp, seed, g/8); xorbuf(U, temp, SHA::DIGESTSIZE); U[0] |= 0x80; U[SHA::DIGESTSIZE-1] |= 1; q.Decode(U, SHA::DIGESTSIZE); if (!IsPrime(q)) return false; int counterEnd = useInputCounterValue ? counter+1 : 4096; for (int c = 0; c < counterEnd; c++) { for (int k=0; k<=n; k++) { for (int i=g/8-1, carry=true; i>=0 && carry; i--) carry=!++seed[i]; if (!useInputCounterValue || c == counter) sha.CalculateDigest(W+(n-k)*SHA::DIGESTSIZE, seed, g/8); } if (!useInputCounterValue || c == counter) { W[SHA::DIGESTSIZE - 1 - b/8] |= 0x80; X.Decode(W + SHA::DIGESTSIZE - 1 - b/8, L/8); p = X-((X % (2*q))-1); if (p.GetBit(L-1) && IsPrime(p)) { counter = c; return true; } } } return false; }
vector<bool> Receiver::decode(Integer v) { vector<bool> res(com.l); for(unsigned i = 0; i < com.l; ++i) { res[i] = com.S[i] ^ v.GetBit(0); v = a_times_b_mod_c(v, v, com.n); } if (v != com.u) { throw SanityException("v != com.u"); } return res; }
template <class T> T AbstractGroup<T>::CascadeScalarMultiply(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const { const unsigned expLen = STDMAX(e1.BitCount(), e2.BitCount()); if (expLen==0) return this->Identity(); const unsigned w = (expLen <= 46 ? 1 : (expLen <= 260 ? 2 : 3)); const unsigned tableSize = 1<<w; std::vector<Element> powerTable(tableSize << w); powerTable[1] = x; powerTable[tableSize] = y; if (w==1) powerTable[3] = this->Add(x,y); else { powerTable[2] = this->Double(x); powerTable[2*tableSize] = this->Double(y); unsigned i, j; for (i=3; i<tableSize; i+=2) powerTable[i] = Add(powerTable[i-2], powerTable[2]); for (i=1; i<tableSize; i+=2) for (j=i+tableSize; j<(tableSize<<w); j+=tableSize) powerTable[j] = Add(powerTable[j-tableSize], y); for (i=3*tableSize; i<(tableSize<<w); i+=2*tableSize) powerTable[i] = Add(powerTable[i-2*tableSize], powerTable[2*tableSize]); for (i=tableSize; i<(tableSize<<w); i+=2*tableSize) for (j=i+2; j<i+tableSize; j+=2) powerTable[j] = Add(powerTable[j-1], x); } Element result; unsigned power1 = 0, power2 = 0, prevPosition = expLen-1; bool firstTime = true; for (int i = expLen-1; i>=0; i--) { power1 = 2*power1 + e1.GetBit(i); power2 = 2*power2 + e2.GetBit(i); if (i==0 || 2*power1 >= tableSize || 2*power2 >= tableSize) { unsigned squaresBefore = prevPosition-i; unsigned squaresAfter = 0; prevPosition = i; while ((power1 || power2) && power1%2 == 0 && power2%2==0) { power1 /= 2; power2 /= 2; squaresBefore--; squaresAfter++; } if (firstTime) { result = powerTable[(power2<<w) + power1]; firstTime = false; } else { while (squaresBefore--) result = this->Double(result); if (power1 || power2) Accumulate(result, powerTable[(power2<<w) + power1]); } while (squaresAfter--) result = this->Double(result); power1 = power2 = 0; } } return result; }