1#ifndef CRYPTOPP_EPRECOMP_H
2#define CRYPTOPP_EPRECOMP_H
3
4#include "integer.h"
5#include "algebra.h"
6#include <vector>
7
8NAMESPACE_BEGIN(CryptoPP)
9
10template <class T>
11class DL_GroupPrecomputation
12{
13public:
14	typedef T Element;
15
16	virtual bool NeedConversions() const {return false;}
17	virtual Element ConvertIn(const Element &v) const {return v;}
18	virtual Element ConvertOut(const Element &v) const {return v;}
19	virtual const AbstractGroup<Element> & GetGroup() const =0;
20	virtual Element BERDecodeElement(BufferedTransformation &bt) const =0;
21	virtual void DEREncodeElement(BufferedTransformation &bt, const Element &P) const =0;
22};
23
24template <class T>
25class DL_FixedBasePrecomputation
26{
27public:
28	typedef T Element;
29
30	virtual bool IsInitialized() const =0;
31	virtual void SetBase(const DL_GroupPrecomputation<Element> &group, const Element &base) =0;
32	virtual const Element & GetBase(const DL_GroupPrecomputation<Element> &group) const =0;
33	virtual void Precompute(const DL_GroupPrecomputation<Element> &group, unsigned int maxExpBits, unsigned int storage) =0;
34	virtual void Load(const DL_GroupPrecomputation<Element> &group, BufferedTransformation &storedPrecomputation) =0;
35	virtual void Save(const DL_GroupPrecomputation<Element> &group, BufferedTransformation &storedPrecomputation) const =0;
36	virtual Element Exponentiate(const DL_GroupPrecomputation<Element> &group, const Integer &exponent) const =0;
37	virtual Element CascadeExponentiate(const DL_GroupPrecomputation<Element> &group, const Integer &exponent, const DL_FixedBasePrecomputation<Element> &pc2, const Integer &exponent2) const =0;
38};
39
40template <class T>
41class DL_FixedBasePrecomputationImpl : public DL_FixedBasePrecomputation<T>
42{
43public:
44	typedef T Element;
45
46	DL_FixedBasePrecomputationImpl() : m_windowSize(0) {}
47
48	// DL_FixedBasePrecomputation
49	bool IsInitialized() const
50		{return !m_bases.empty();}
51	void SetBase(const DL_GroupPrecomputation<Element> &group, const Element &base);
52	const Element & GetBase(const DL_GroupPrecomputation<Element> &group) const
53		{return group.NeedConversions() ? m_base : m_bases[0];}
54	void Precompute(const DL_GroupPrecomputation<Element> &group, unsigned int maxExpBits, unsigned int storage);
55	void Load(const DL_GroupPrecomputation<Element> &group, BufferedTransformation &storedPrecomputation);
56	void Save(const DL_GroupPrecomputation<Element> &group, BufferedTransformation &storedPrecomputation) const;
57	Element Exponentiate(const DL_GroupPrecomputation<Element> &group, const Integer &exponent) const;
58	Element CascadeExponentiate(const DL_GroupPrecomputation<Element> &group, const Integer &exponent, const DL_FixedBasePrecomputation<Element> &pc2, const Integer &exponent2) const;
59
60private:
61	void PrepareCascade(const DL_GroupPrecomputation<Element> &group, std::vector<BaseAndExponent<Element> > &eb, const Integer &exponent) const;
62
63	Element m_base;
64	unsigned int m_windowSize;
65	Integer m_exponentBase;			// what base to represent the exponent in
66	std::vector<Element> m_bases;	// precalculated bases
67};
68
69NAMESPACE_END
70
71#ifdef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES
72#include "eprecomp.cpp"
73#endif
74
75#endif
76