Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

113 lines
3.7 KiB

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