10 #include "polynomi.cpp" 14 ANONYMOUS_NAMESPACE_BEGIN
15 static const CryptoPP::GF2_32 field;
22 if (!parameters.GetIntValue(
"RecoveryThreshold", m_threshold))
25 assert(m_threshold > 0);
27 throw InvalidArgument(
"RawIDA: RecoveryThreshold must be greater than 0");
29 m_lastMapPosition = m_inputChannelMap.end();
31 m_channelsFinished = 0;
34 m_inputQueues.reserve(m_threshold);
36 m_outputChannelIds.clear();
37 m_outputChannelIdStrings.clear();
38 m_outputQueues.clear();
40 word32 outputChannelID;
41 if (parameters.GetValue(
"OutputChannelID", outputChannelID))
42 AddOutputChannel(outputChannelID);
45 int nShares = parameters.GetIntValueWithDefault(
"NumberOfShares", m_threshold);
47 if (nShares <= 0) {nShares = m_threshold;}
48 for (
unsigned int i=0; i< (
unsigned int)(nShares); i++)
53 unsigned int RawIDA::InsertInputChannel(word32 channelId)
55 if (m_lastMapPosition != m_inputChannelMap.end())
57 if (m_lastMapPosition->first == channelId)
60 if (m_lastMapPosition != m_inputChannelMap.end() && m_lastMapPosition->first == channelId)
63 m_lastMapPosition = m_inputChannelMap.find(channelId);
66 if (m_lastMapPosition == m_inputChannelMap.end())
68 if (m_inputChannelIds.size() == size_t(m_threshold))
71 m_lastMapPosition = m_inputChannelMap.insert(InputChannelMap::value_type(channelId, (
unsigned int)m_inputChannelIds.size())).first;
73 m_inputChannelIds.push_back(channelId);
75 if (m_inputChannelIds.size() == size_t(m_threshold))
76 PrepareInterpolation();
78 return m_lastMapPosition->second;
81 unsigned int RawIDA::LookupInputChannel(word32 channelId)
const 83 std::map<word32, unsigned int>::const_iterator it = m_inputChannelMap.find(channelId);
84 if (it == m_inputChannelMap.end())
90 void RawIDA::ChannelData(word32 channelId,
const byte *inString,
size_t length,
bool messageEnd)
92 int i = InsertInputChannel(channelId);
95 lword size = m_inputQueues[i].MaxRetrievable();
96 m_inputQueues[i].Put(inString, length);
97 if (size < 4 && size + length >= 4)
100 if (m_channelsReady ==
size_t(m_threshold))
101 ProcessInputQueues();
106 m_inputQueues[i].MessageEnd();
109 m_channelsFinished++;
110 if (m_channelsFinished ==
size_t(m_threshold))
113 for (i=0; i<m_threshold; i++)
115 ProcessInputQueues();
122 lword RawIDA::InputBuffered(word32 channelId)
const 124 int i = LookupInputChannel(channelId);
125 return i < m_threshold ? m_inputQueues[i].MaxRetrievable() : 0;
128 void RawIDA::ComputeV(
unsigned int i)
133 m_outputToInput.resize(i+1);
136 m_outputToInput[i] = LookupInputChannel(m_outputChannelIds[i]);
137 if (m_outputToInput[i] ==
size_t(m_threshold) && i *
size_t(m_threshold) <= 1000*1000)
139 m_v[i].resize(m_threshold);
140 PrepareBulkPolynomialInterpolationAt(field, m_v[i].begin(), m_outputChannelIds[i], &(m_inputChannelIds[0]), m_w.
begin(), m_threshold);
144 void RawIDA::AddOutputChannel(word32 channelId)
146 m_outputChannelIds.push_back(channelId);
147 m_outputChannelIdStrings.push_back(WordToString(channelId));
149 if (m_inputChannelIds.size() == size_t(m_threshold))
150 ComputeV((
unsigned int)m_outputChannelIds.size() - 1);
153 void RawIDA::PrepareInterpolation()
155 assert(m_inputChannelIds.size() == size_t(m_threshold));
156 PrepareBulkPolynomialInterpolation(field, m_w.
begin(), &(m_inputChannelIds[0]), (
unsigned int)(m_threshold));
157 for (
unsigned int i=0; i<m_outputChannelIds.size(); i++)
161 void RawIDA::ProcessInputQueues()
163 bool finished = (m_channelsFinished == size_t(m_threshold));
166 while (finished ? m_channelsReady > 0 : m_channelsReady ==
size_t(m_threshold))
169 for (i=0; i<size_t(m_threshold); i++)
180 for (i=0; (
unsigned int)i<m_outputChannelIds.size(); i++)
182 if (m_outputToInput[i] !=
size_t(m_threshold))
183 m_outputQueues[i].
PutWord32(m_y[m_outputToInput[i]]);
184 else if (m_v[i].size() == size_t(m_threshold))
185 m_outputQueues[i].
PutWord32(BulkPolynomialInterpolateAt(field, m_y.
begin(), m_v[i].begin(), m_threshold));
189 PrepareBulkPolynomialInterpolationAt(field, m_u.
begin(), m_outputChannelIds[i], &(m_inputChannelIds[0]), m_w.
begin(), m_threshold);
190 m_outputQueues[i].PutWord32(BulkPolynomialInterpolateAt(field, m_y.
begin(), m_u.
begin(), m_threshold));
195 if (m_outputChannelIds.size() > 0 && m_outputQueues[0].AnyRetrievable())
203 m_channelsFinished = 0;
206 std::vector<MessageQueue> inputQueues;
207 std::vector<word32> inputChannelIds;
209 inputQueues.swap(m_inputQueues);
210 inputChannelIds.swap(m_inputChannelIds);
211 m_inputChannelMap.clear();
212 m_lastMapPosition = m_inputChannelMap.end();
214 for (i=0; i<size_t(m_threshold); i++)
216 inputQueues[i].GetNextMessage();
222 void RawIDA::FlushOutputQueues()
224 for (
unsigned int i=0; i<m_outputChannelIds.size(); i++)
228 void RawIDA::OutputMessageEnds()
230 if (GetAutoSignalPropagation() != 0)
232 for (
unsigned int i=0; i<m_outputChannelIds.size(); i++)
242 m_ida.IsolatedInitialize(parameters);
245 size_t SecretSharing::Put2(
const byte *begin,
size_t length,
int messageEnd,
bool blocking)
248 throw BlockingInputOnly(
"SecretSharing");
251 unsigned int threshold = m_ida.GetThreshold();
254 size_t len =
STDMIN(length, buf.size());
255 m_ida.ChannelData(0xffffffff, begin, len,
false);
256 for (
unsigned int i=0; i<threshold-1; i++)
258 m_rng.GenerateBlock(buf, len);
259 m_ida.ChannelData(i, buf, len,
false);
267 m_ida.SetAutoSignalPropagation(messageEnd-1);
271 while (m_ida.InputBuffered(0xffffffff) > 0)
274 m_ida.ChannelData(0xffffffff, NULL, 0,
true);
275 for (
unsigned int i=0; i<m_ida.GetThreshold()-1; i++)
276 m_ida.ChannelData(i, NULL, 0,
true);
288 void SecretRecovery::FlushOutputQueues()
296 void SecretRecovery::OutputMessageEnds()
301 m_outputQueues[0].TransferAllTo(paddingRemover);
304 if (GetAutoSignalPropagation() != 0)
314 m_ida.IsolatedInitialize(parameters);
320 throw BlockingInputOnly(
"InformationDispersal");
324 m_ida.ChannelData(m_nextChannel, begin, 1,
false);
327 if (m_nextChannel == m_ida.GetThreshold())
333 m_ida.SetAutoSignalPropagation(messageEnd-1);
336 for (word32 i=0; i<m_ida.GetThreshold(); i++)
337 m_ida.ChannelData(i, NULL, 0,
true);
349 void InformationRecovery::FlushOutputQueues()
353 for (
unsigned int i=0; i<m_outputChannelIds.size(); i++)
363 void InformationRecovery::OutputMessageEnds()
368 m_queue.TransferAllTo(paddingRemover);
371 if (GetAutoSignalPropagation() != 0)
378 throw BlockingInputOnly(
"PaddingRemover");
380 const byte *
const end = begin + length;
382 if (m_possiblePadding)
384 size_t len = std::find_if(begin, end, std::bind2nd(std::not_equal_to<byte>(), byte(0))) - begin;
391 while (m_zeroCount--)
394 m_possiblePadding =
false;
397 #if defined(_MSC_VER) && !defined(__MWERKS__) && (_MSC_VER <= 1300) 399 typedef std::reverse_bidirectional_iterator<const byte *, const byte> RevIt;
400 #elif defined(_RWSTD_NO_CLASS_PARTIAL_SPEC) 401 typedef std::reverse_iterator<const byte *, random_access_iterator_tag, const byte> RevIt;
403 typedef std::reverse_iterator<const byte *> RevIt;
405 const byte *x = std::find_if(RevIt(end), RevIt(begin), bind2nd(std::not_equal_to<byte>(), byte(0))).base();
406 if (x != begin && *(x-1) == 1)
409 m_possiblePadding =
true;
410 m_zeroCount = end - x;
417 m_possiblePadding =
false;
418 Output(0, begin, length, messageEnd, blocking);
An invalid argument was detected.
T GetValueWithDefault(const char *name, T defaultValue) const
Get a named value.
unsigned int NumberOfMessages() const
Provides the number of meesages processed by this object.
void resize(size_type newSize)
Change size and preserve contents.
base class for secret sharing and information dispersal
Library configuration file.
SecByteBlock is a SecBlock<byte> typedef.
Classes for performing mathematics over different fields.
lword MaxRetrievable() const
Provides the number of bytes ready for retrieval.
void IsolatedInitialize(const NameValuePairs ¶meters=g_nullNameValuePairs)
Initialize or reinitialize this object, without signal propagation.
bool AnyRetrievable() const
Determines whether bytes are ready for retrieval.
AlgorithmParameters MakeParameters(const char *name, const T &value, bool throwIfNotUsed=true)
Create an object that implements NameValuePairs.
BufferedTransformation * AttachedTransformation()
Retrieve attached transformation.
const T1 UnsignedMin(const T1 &a, const T2 &b)
Safe comparison of values that could be neagtive and incorrectly promoted.
size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
Input multiple bytes for processing.
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Classes for polynomial basis and operations.
Redirect input to another BufferedTransformation without owning it.
iterator begin()
Provides an iterator pointing to the first element in the memory block.
void IsolatedInitialize(const NameValuePairs ¶meters=g_nullNameValuePairs)
Initialize or reinitialize this object, without signal propagation.
void IsolatedInitialize(const NameValuePairs ¶meters=g_nullNameValuePairs)
Initialize or reinitialize this object, without signal propagation.
Crypto++ library namespace.
size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
Input multiple bytes for processing.
Classes for Information Dispersal Algorithm (IDA)
Interface for retrieving values given their names.