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.

161 lines
5.2 KiB

  1. // ida.h - written and placed in the public domain by Wei Dai
  2. //! \file ida.h
  3. //! \brief Classes for Information Dispersal Algorithm (IDA)
  4. #ifndef CRYPTOPP_IDA_H
  5. #define CRYPTOPP_IDA_H
  6. #include "cryptlib.h"
  7. #include "mqueue.h"
  8. #include "filters.h"
  9. #include "channels.h"
  10. #include "secblock.h"
  11. #include "stdcpp.h"
  12. #include "misc.h"
  13. NAMESPACE_BEGIN(CryptoPP)
  14. /// base class for secret sharing and information dispersal
  15. class RawIDA : public AutoSignaling<Unflushable<Multichannel<Filter> > >
  16. {
  17. public:
  18. RawIDA(BufferedTransformation *attachment=NULL)
  19. : m_threshold (0), m_channelsReady(0), m_channelsFinished(0)
  20. {Detach(attachment);}
  21. unsigned int GetThreshold() const {return m_threshold;}
  22. void AddOutputChannel(word32 channelId);
  23. void ChannelData(word32 channelId, const byte *inString, size_t length, bool messageEnd);
  24. lword InputBuffered(word32 channelId) const;
  25. void IsolatedInitialize(const NameValuePairs &parameters=g_nullNameValuePairs);
  26. size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking)
  27. {
  28. if (!blocking)
  29. throw BlockingInputOnly("RawIDA");
  30. ChannelData(StringToWord<word32>(channel), begin, length, messageEnd != 0);
  31. return 0;
  32. }
  33. protected:
  34. virtual void FlushOutputQueues();
  35. virtual void OutputMessageEnds();
  36. unsigned int InsertInputChannel(word32 channelId);
  37. unsigned int LookupInputChannel(word32 channelId) const;
  38. void ComputeV(unsigned int);
  39. void PrepareInterpolation();
  40. void ProcessInputQueues();
  41. typedef std::map<word32, unsigned int> InputChannelMap;
  42. InputChannelMap m_inputChannelMap;
  43. InputChannelMap::iterator m_lastMapPosition;
  44. std::vector<MessageQueue> m_inputQueues;
  45. std::vector<word32> m_inputChannelIds, m_outputChannelIds, m_outputToInput;
  46. std::vector<std::string> m_outputChannelIdStrings;
  47. std::vector<ByteQueue> m_outputQueues;
  48. int m_threshold;
  49. unsigned int m_channelsReady, m_channelsFinished;
  50. std::vector<SecBlock<word32> > m_v;
  51. SecBlock<word32> m_u, m_w, m_y;
  52. };
  53. /// a variant of Shamir's Secret Sharing Algorithm
  54. class SecretSharing : public CustomFlushPropagation<Filter>
  55. {
  56. public:
  57. SecretSharing(RandomNumberGenerator &rng, int threshold, int nShares, BufferedTransformation *attachment=NULL, bool addPadding=true)
  58. : m_rng(rng), m_ida(new OutputProxy(*this, true))
  59. {
  60. Detach(attachment);
  61. IsolatedInitialize(MakeParameters("RecoveryThreshold", threshold)("NumberOfShares", nShares)("AddPadding", addPadding));
  62. }
  63. void IsolatedInitialize(const NameValuePairs &parameters=g_nullNameValuePairs);
  64. size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking);
  65. bool Flush(bool hardFlush, int propagation=-1, bool blocking=true) {return m_ida.Flush(hardFlush, propagation, blocking);}
  66. protected:
  67. RandomNumberGenerator &m_rng;
  68. RawIDA m_ida;
  69. bool m_pad;
  70. };
  71. /// a variant of Shamir's Secret Sharing Algorithm
  72. class SecretRecovery : public RawIDA
  73. {
  74. public:
  75. SecretRecovery(int threshold, BufferedTransformation *attachment=NULL, bool removePadding=true)
  76. : RawIDA(attachment)
  77. {IsolatedInitialize(MakeParameters("RecoveryThreshold", threshold)("RemovePadding", removePadding));}
  78. void IsolatedInitialize(const NameValuePairs &parameters=g_nullNameValuePairs);
  79. protected:
  80. void FlushOutputQueues();
  81. void OutputMessageEnds();
  82. bool m_pad;
  83. };
  84. /// a variant of Rabin's Information Dispersal Algorithm
  85. class InformationDispersal : public CustomFlushPropagation<Filter>
  86. {
  87. public:
  88. InformationDispersal(int threshold, int nShares, BufferedTransformation *attachment=NULL, bool addPadding=true)
  89. : m_ida(new OutputProxy(*this, true)), m_pad(false), m_nextChannel(0)
  90. {
  91. Detach(attachment);
  92. IsolatedInitialize(MakeParameters("RecoveryThreshold", threshold)("NumberOfShares", nShares)("AddPadding", addPadding));
  93. }
  94. void IsolatedInitialize(const NameValuePairs &parameters=g_nullNameValuePairs);
  95. size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking);
  96. bool Flush(bool hardFlush, int propagation=-1, bool blocking=true) {return m_ida.Flush(hardFlush, propagation, blocking);}
  97. protected:
  98. RawIDA m_ida;
  99. bool m_pad;
  100. unsigned int m_nextChannel;
  101. };
  102. /// a variant of Rabin's Information Dispersal Algorithm
  103. class InformationRecovery : public RawIDA
  104. {
  105. public:
  106. InformationRecovery(int threshold, BufferedTransformation *attachment=NULL, bool removePadding=true)
  107. : RawIDA(attachment), m_pad(false)
  108. {IsolatedInitialize(MakeParameters("RecoveryThreshold", threshold)("RemovePadding", removePadding));}
  109. void IsolatedInitialize(const NameValuePairs &parameters=g_nullNameValuePairs);
  110. protected:
  111. void FlushOutputQueues();
  112. void OutputMessageEnds();
  113. bool m_pad;
  114. ByteQueue m_queue;
  115. };
  116. class PaddingRemover : public Unflushable<Filter>
  117. {
  118. public:
  119. PaddingRemover(BufferedTransformation *attachment=NULL)
  120. : m_possiblePadding(false), m_zeroCount(0) {Detach(attachment);}
  121. void IsolatedInitialize(const NameValuePairs &parameters)
  122. {CRYPTOPP_UNUSED(parameters); m_possiblePadding = false;}
  123. size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking);
  124. // GetPossiblePadding() == false at the end of a message indicates incorrect padding
  125. bool GetPossiblePadding() const {return m_possiblePadding;}
  126. private:
  127. bool m_possiblePadding;
  128. lword m_zeroCount;
  129. };
  130. NAMESPACE_END
  131. #endif