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