10 #include "polynomi.cpp"
14 ANONYMOUS_NAMESPACE_BEGIN
15 static const CryptoPP::GF2_32 field;
22 if (!parameters.
GetIntValue(
"RecoveryThreshold", m_threshold))
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);
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()
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++)
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++)
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)
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()
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) && (_MSC_VER <= 1300) && !defined(__MWERKS__)
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 *, std::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), std::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);