1 // eprecomp.cpp - originally written and placed in the public domain by Wei Dai 2 3 #include "pch.h" 4 5 #ifndef CRYPTOPP_IMPORTS 6 7 #include "eprecomp.h" 8 #include "integer.h" 9 #include "algebra.h" 10 #include "asn.h" 11 12 NAMESPACE_BEGIN(CryptoPP) 13 14 template <class T> void DL_FixedBasePrecomputationImpl<T>::SetBase(const DL_GroupPrecomputation<Element> &group, const Element &i_base) 15 { 16 m_base = group.NeedConversions() ? group.ConvertIn(i_base) : i_base; 17 18 if (m_bases.empty() || !(m_base == m_bases[0])) 19 { 20 m_bases.resize(1); 21 m_bases[0] = m_base; 22 } 23 24 if (group.NeedConversions()) 25 m_base = i_base; 26 } 27 28 template <class T> void DL_FixedBasePrecomputationImpl<T>::Precompute(const DL_GroupPrecomputation<Element> &group, unsigned int maxExpBits, unsigned int storage) 29 { 30 CRYPTOPP_ASSERT(m_bases.size() > 0); 31 CRYPTOPP_ASSERT(storage <= maxExpBits); 32 33 if (storage > 1) 34 { 35 m_windowSize = (maxExpBits+storage-1)/storage; 36 m_exponentBase = Integer::Power2(m_windowSize); 37 } 38 39 m_bases.resize(storage); 40 for (unsigned i=1; i<storage; i++) 41 m_bases[i] = group.GetGroup().ScalarMultiply(m_bases[i-1], m_exponentBase); 42 } 43 44 template <class T> void DL_FixedBasePrecomputationImpl<T>::Load(const DL_GroupPrecomputation<Element> &group, BufferedTransformation &bt) 45 { 46 BERSequenceDecoder seq(bt); 47 word32 version; 48 BERDecodeUnsigned<word32>(seq, version, INTEGER, 1, 1); 49 m_exponentBase.BERDecode(seq); 50 m_windowSize = m_exponentBase.BitCount() - 1; 51 m_bases.clear(); 52 while (!seq.EndReached()) 53 m_bases.push_back(group.BERDecodeElement(seq)); 54 if (!m_bases.empty() && group.NeedConversions()) 55 m_base = group.ConvertOut(m_bases[0]); 56 seq.MessageEnd(); 57 } 58 59 template <class T> void DL_FixedBasePrecomputationImpl<T>::Save(const DL_GroupPrecomputation<Element> &group, BufferedTransformation &bt) const 60 { 61 DERSequenceEncoder seq(bt); 62 DEREncodeUnsigned<word32>(seq, 1); // version 63 m_exponentBase.DEREncode(seq); 64 for (unsigned i=0; i<m_bases.size(); i++) 65 group.DEREncodeElement(seq, m_bases[i]); 66 seq.MessageEnd(); 67 } 68 69 template <class T> void DL_FixedBasePrecomputationImpl<T>::PrepareCascade(const DL_GroupPrecomputation<Element> &i_group, std::vector<BaseAndExponent<Element> > &eb, const Integer &exponent) const 70 { 71 const AbstractGroup<T> &group = i_group.GetGroup(); 72 73 Integer r, q, e = exponent; 74 bool fastNegate = group.InversionIsFast() && m_windowSize > 1; 75 unsigned int i; 76 77 for (i=0; i+1<m_bases.size(); i++) 78 { 79 Integer::DivideByPowerOf2(r, q, e, m_windowSize); 80 std::swap(q, e); 81 if (fastNegate && r.GetBit(m_windowSize-1)) 82 { 83 ++e; 84 eb.push_back(BaseAndExponent<Element>(group.Inverse(m_bases[i]), m_exponentBase - r)); 85 } 86 else 87 eb.push_back(BaseAndExponent<Element>(m_bases[i], r)); 88 } 89 eb.push_back(BaseAndExponent<Element>(m_bases[i], e)); 90 } 91 92 template <class T> T DL_FixedBasePrecomputationImpl<T>::Exponentiate(const DL_GroupPrecomputation<Element> &group, const Integer &exponent) const 93 { 94 std::vector<BaseAndExponent<Element> > eb; // array of segments of the exponent and precalculated bases 95 eb.reserve(m_bases.size()); 96 PrepareCascade(group, eb, exponent); 97 return group.ConvertOut(GeneralCascadeMultiplication<Element>(group.GetGroup(), eb.begin(), eb.end())); 98 } 99 100 template <class T> T 101 DL_FixedBasePrecomputationImpl<T>::CascadeExponentiate(const DL_GroupPrecomputation<Element> &group, const Integer &exponent, 102 const DL_FixedBasePrecomputation<T> &i_pc2, const Integer &exponent2) const 103 { 104 std::vector<BaseAndExponent<Element> > eb; // array of segments of the exponent and precalculated bases 105 const DL_FixedBasePrecomputationImpl<T> &pc2 = static_cast<const DL_FixedBasePrecomputationImpl<T> &>(i_pc2); 106 eb.reserve(m_bases.size() + pc2.m_bases.size()); 107 PrepareCascade(group, eb, exponent); 108 pc2.PrepareCascade(group, eb, exponent2); 109 return group.ConvertOut(GeneralCascadeMultiplication<Element>(group.GetGroup(), eb.begin(), eb.end())); 110 } 111 112 NAMESPACE_END 113 114 #endif 115