Crypto++  5.6.3
Free C++ class library of cryptographic schemes
eprecomp.cpp
1 // eprecomp.cpp - 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 "asn.h"
10 
11 NAMESPACE_BEGIN(CryptoPP)
12 
13 template <class T> void DL_FixedBasePrecomputationImpl<T>::SetBase(const DL_GroupPrecomputation<Element> &group, const Element &i_base)
14 {
15  m_base = group.NeedConversions() ? group.ConvertIn(i_base) : i_base;
16 
17  if (m_bases.empty() || !(m_base == m_bases[0]))
18  {
19  m_bases.resize(1);
20  m_bases[0] = m_base;
21  }
22 
23  if (group.NeedConversions())
24  m_base = i_base;
25 }
26 
27 template <class T> void DL_FixedBasePrecomputationImpl<T>::Precompute(const DL_GroupPrecomputation<Element> &group, unsigned int maxExpBits, unsigned int storage)
28 {
29  assert(m_bases.size() > 0);
30  assert(storage <= maxExpBits);
31 
32  if (storage > 1)
33  {
34  m_windowSize = (maxExpBits+storage-1)/storage;
35  m_exponentBase = Integer::Power2(m_windowSize);
36  }
37 
38  m_bases.resize(storage);
39  for (unsigned i=1; i<storage; i++)
40  m_bases[i] = group.GetGroup().ScalarMultiply(m_bases[i-1], m_exponentBase);
41 }
42 
44 {
45  BERSequenceDecoder seq(bt);
46  word32 version;
47  BERDecodeUnsigned<word32>(seq, version, INTEGER, 1, 1);
48  m_exponentBase.BERDecode(seq);
49  m_windowSize = m_exponentBase.BitCount() - 1;
50  m_bases.clear();
51  while (!seq.EndReached())
52  m_bases.push_back(group.BERDecodeElement(seq));
53  if (!m_bases.empty() && group.NeedConversions())
54  m_base = group.ConvertOut(m_bases[0]);
55  seq.MessageEnd();
56 }
57 
59 {
60  DERSequenceEncoder seq(bt);
61  DEREncodeUnsigned<word32>(seq, 1); // version
62  m_exponentBase.DEREncode(seq);
63  for (unsigned i=0; i<m_bases.size(); i++)
64  group.DEREncodeElement(seq, m_bases[i]);
65  seq.MessageEnd();
66 }
67 
68 template <class T> void DL_FixedBasePrecomputationImpl<T>::PrepareCascade(const DL_GroupPrecomputation<Element> &i_group, std::vector<BaseAndExponent<Element> > &eb, const Integer &exponent) const
69 {
70  const AbstractGroup<T> &group = i_group.GetGroup();
71 
72  Integer r, q, e = exponent;
73  bool fastNegate = group.InversionIsFast() && m_windowSize > 1;
74  unsigned int i;
75 
76  for (i=0; i+1<m_bases.size(); i++)
77  {
78  Integer::DivideByPowerOf2(r, q, e, m_windowSize);
79  std::swap(q, e);
80  if (fastNegate && r.GetBit(m_windowSize-1))
81  {
82  ++e;
83  eb.push_back(BaseAndExponent<Element>(group.Inverse(m_bases[i]), m_exponentBase - r));
84  }
85  else
86  eb.push_back(BaseAndExponent<Element>(m_bases[i], r));
87  }
88  eb.push_back(BaseAndExponent<Element>(m_bases[i], e));
89 }
90 
91 template <class T> T DL_FixedBasePrecomputationImpl<T>::Exponentiate(const DL_GroupPrecomputation<Element> &group, const Integer &exponent) const
92 {
93  std::vector<BaseAndExponent<Element> > eb; // array of segments of the exponent and precalculated bases
94  eb.reserve(m_bases.size());
95  PrepareCascade(group, eb, exponent);
96  return group.ConvertOut(GeneralCascadeMultiplication<Element>(group.GetGroup(), eb.begin(), eb.end()));
97 }
98 
99 template <class T> T
101  const DL_FixedBasePrecomputation<T> &i_pc2, const Integer &exponent2) const
102 {
103  std::vector<BaseAndExponent<Element> > eb; // array of segments of the exponent and precalculated bases
104  const DL_FixedBasePrecomputationImpl<T> &pc2 = static_cast<const DL_FixedBasePrecomputationImpl<T> &>(i_pc2);
105  eb.reserve(m_bases.size() + pc2.m_bases.size());
106  PrepareCascade(group, eb, exponent);
107  pc2.PrepareCascade(group, eb, exponent2);
108  return group.ConvertOut(GeneralCascadeMultiplication<Element>(group.GetGroup(), eb.begin(), eb.end()));
109 }
110 
111 NAMESPACE_END
112 
113 #endif
bool GetBit(size_t i) const
return the i-th bit, i=0 being the least significant bit
Definition: integer.cpp:2958
static void DivideByPowerOf2(Integer &r, Integer &q, const Integer &a, unsigned int n)
returns same result as Divide(r, q, a, Power2(n)), but faster
Definition: integer.cpp:3823
BER Sequence Decoder.
Definition: asn.h:197
Interface for buffered transformations.
Definition: cryptlib.h:1247
static Integer Power2(size_t e)
Exponentiates to a power of 2.
Definition: integer.cpp:2910
Multiple precision integer with arithmetic operations.
Definition: integer.h:31
Abstract Group.
Definition: algebra.h:27
Classes and functions for working with ANS.1 objects.
Classes for precomputation in a group.
DER Sequence Encoder.
Definition: asn.h:207
Base and Exponent.
Definition: algebra.h:129
Crypto++ library namespace.