00001
00002
00003 #include "pch.h"
00004
00005 #ifndef CRYPTOPP_IMPORTS
00006
00007 #include "eprecomp.h"
00008 #include "integer.h"
00009 #include "asn.h"
00010
00011 NAMESPACE_BEGIN(CryptoPP)
00012
00013 template <class T> void DL_FixedBasePrecomputationImpl<T>::SetBase(const DL_GroupPrecomputation<Element> &group, const Element &i_base)
00014 {
00015 m_base = group.NeedConversions() ? group.ConvertIn(i_base) : i_base;
00016
00017 if (m_bases.empty() || !(m_base == m_bases[0]))
00018 {
00019 m_bases.resize(1);
00020 m_bases[0] = m_base;
00021 }
00022
00023 if (group.NeedConversions())
00024 m_base = i_base;
00025 }
00026
00027 template <class T> void DL_FixedBasePrecomputationImpl<T>::Precompute(const DL_GroupPrecomputation<Element> &group, unsigned int maxExpBits, unsigned int storage)
00028 {
00029 assert(m_bases.size() > 0);
00030 assert(storage <= maxExpBits);
00031
00032 if (storage > 1)
00033 {
00034 m_windowSize = (maxExpBits+storage-1)/storage;
00035 m_exponentBase = Integer::Power2(m_windowSize);
00036 }
00037
00038 m_bases.resize(storage);
00039 for (unsigned i=1; i<storage; i++)
00040 m_bases[i] = group.GetGroup().ScalarMultiply(m_bases[i-1], m_exponentBase);
00041 }
00042
00043 template <class T> void DL_FixedBasePrecomputationImpl<T>::Load(const DL_GroupPrecomputation<Element> &group, BufferedTransformation &bt)
00044 {
00045 BERSequenceDecoder seq(bt);
00046 word32 version;
00047 BERDecodeUnsigned<word32>(seq, version, INTEGER, 1, 1);
00048 m_exponentBase.BERDecode(seq);
00049 m_windowSize = m_exponentBase.BitCount() - 1;
00050 m_bases.clear();
00051 while (!seq.EndReached())
00052 m_bases.push_back(group.BERDecodeElement(seq));
00053 if (!m_bases.empty() && group.NeedConversions())
00054 m_base = group.ConvertOut(m_bases[0]);
00055 seq.MessageEnd();
00056 }
00057
00058 template <class T> void DL_FixedBasePrecomputationImpl<T>::Save(const DL_GroupPrecomputation<Element> &group, BufferedTransformation &bt) const
00059 {
00060 DERSequenceEncoder seq(bt);
00061 DEREncodeUnsigned<word32>(seq, 1);
00062 m_exponentBase.DEREncode(seq);
00063 for (unsigned i=0; i<m_bases.size(); i++)
00064 group.DEREncodeElement(seq, m_bases[i]);
00065 seq.MessageEnd();
00066 }
00067
00068 template <class T> void DL_FixedBasePrecomputationImpl<T>::PrepareCascade(const DL_GroupPrecomputation<Element> &i_group, std::vector<BaseAndExponent<Element> > &eb, const Integer &exponent) const
00069 {
00070 const AbstractGroup<T> &group = i_group.GetGroup();
00071
00072 Integer r, q, e = exponent;
00073 bool fastNegate = group.InversionIsFast() && m_windowSize > 1;
00074 unsigned int i;
00075
00076 for (i=0; i+1<m_bases.size(); i++)
00077 {
00078 Integer::DivideByPowerOf2(r, q, e, m_windowSize);
00079 std::swap(q, e);
00080 if (fastNegate && r.GetBit(m_windowSize-1))
00081 {
00082 ++e;
00083 eb.push_back(BaseAndExponent<Element>(group.Inverse(m_bases[i]), m_exponentBase - r));
00084 }
00085 else
00086 eb.push_back(BaseAndExponent<Element>(m_bases[i], r));
00087 }
00088 eb.push_back(BaseAndExponent<Element>(m_bases[i], e));
00089 }
00090
00091 template <class T> T DL_FixedBasePrecomputationImpl<T>::Exponentiate(const DL_GroupPrecomputation<Element> &group, const Integer &exponent) const
00092 {
00093 std::vector<BaseAndExponent<Element> > eb;
00094 eb.reserve(m_bases.size());
00095 PrepareCascade(group, eb, exponent);
00096 return group.ConvertOut(GeneralCascadeMultiplication<Element>(group.GetGroup(), eb.begin(), eb.end()));
00097 }
00098
00099 template <class T> T
00100 DL_FixedBasePrecomputationImpl<T>::CascadeExponentiate(const DL_GroupPrecomputation<Element> &group, const Integer &exponent,
00101 const DL_FixedBasePrecomputation<T> &i_pc2, const Integer &exponent2) const
00102 {
00103 std::vector<BaseAndExponent<Element> > eb;
00104 const DL_FixedBasePrecomputationImpl<T> &pc2 = static_cast<const DL_FixedBasePrecomputationImpl<T> &>(i_pc2);
00105 eb.reserve(m_bases.size() + pc2.m_bases.size());
00106 PrepareCascade(group, eb, exponent);
00107 pc2.PrepareCascade(group, eb, exponent2);
00108 return group.ConvertOut(GeneralCascadeMultiplication<Element>(group.GetGroup(), eb.begin(), eb.end()));
00109 }
00110
00111 NAMESPACE_END
00112
00113 #endif