10 #include "polynomi.cpp"
14 #if (defined(_MSC_VER) && (_MSC_VER < 1400)) && !defined(__MWERKS__)
16 typedef std::reverse_bidirectional_iterator<const byte *, const byte> RevIt;
17 #elif defined(_RWSTD_NO_CLASS_PARTIAL_SPEC)
18 typedef std::reverse_iterator<const byte *, std::random_access_iterator_tag, const byte> RevIt;
20 typedef std::reverse_iterator<const byte *> RevIt;
25 if (!parameters.
GetIntValue(
"RecoveryThreshold", m_threshold))
30 throw InvalidArgument(
"RawIDA: RecoveryThreshold must be greater than 0");
32 m_lastMapPosition = m_inputChannelMap.end();
34 m_channelsFinished = 0;
37 m_inputQueues.reserve(m_threshold);
39 m_outputChannelIds.clear();
40 m_outputChannelIdStrings.clear();
41 m_outputQueues.clear();
43 word32 outputChannelID;
44 if (parameters.
GetValue(
"OutputChannelID", outputChannelID))
45 AddOutputChannel(outputChannelID);
50 if (nShares <= 0) {nShares = m_threshold;}
51 for (
unsigned int i=0; i< (
unsigned int)(nShares); i++)
56 unsigned int RawIDA::InsertInputChannel(word32 channelId)
58 if (m_lastMapPosition != m_inputChannelMap.end())
60 if (m_lastMapPosition->first == channelId)
63 if (m_lastMapPosition != m_inputChannelMap.end() && m_lastMapPosition->first == channelId)
66 m_lastMapPosition = m_inputChannelMap.find(channelId);
69 if (m_lastMapPosition == m_inputChannelMap.end())
71 if (m_inputChannelIds.size() ==
size_t(m_threshold))
74 m_lastMapPosition = m_inputChannelMap.insert(InputChannelMap::value_type(channelId, (
unsigned int)m_inputChannelIds.size())).first;
76 m_inputChannelIds.push_back(channelId);
78 if (m_inputChannelIds.size() ==
size_t(m_threshold))
79 PrepareInterpolation();
81 return m_lastMapPosition->second;
84 unsigned int RawIDA::LookupInputChannel(word32 channelId)
const
86 std::map<word32, unsigned int>::const_iterator it = m_inputChannelMap.find(channelId);
87 if (it == m_inputChannelMap.end())
93 void RawIDA::ChannelData(word32 channelId,
const byte *inString,
size_t length,
bool messageEnd)
95 int i = InsertInputChannel(channelId);
98 lword size = m_inputQueues[i].MaxRetrievable();
99 m_inputQueues[i].Put(inString, length);
100 if (size < 4 && size + length >= 4)
103 if (m_channelsReady ==
size_t(m_threshold))
104 ProcessInputQueues();
109 m_inputQueues[i].MessageEnd();
112 m_channelsFinished++;
113 if (m_channelsFinished ==
size_t(m_threshold))
116 for (i=0; i<m_threshold; i++)
118 ProcessInputQueues();
125 lword RawIDA::InputBuffered(word32 channelId)
const
127 int i = LookupInputChannel(channelId);
128 return i < m_threshold ? m_inputQueues[i].MaxRetrievable() : 0;
131 void RawIDA::ComputeV(
unsigned int i)
136 m_outputToInput.resize(i+1);
139 m_outputToInput[i] = LookupInputChannel(m_outputChannelIds[i]);
140 if (m_outputToInput[i] ==
size_t(m_threshold) && i *
size_t(m_threshold) <= 1000*1000)
142 m_v[i].resize(m_threshold);
143 PrepareBulkPolynomialInterpolationAt(m_gf32, m_v[i].begin(), m_outputChannelIds[i], &(m_inputChannelIds[0]), m_w.
begin(), m_threshold);
147 void RawIDA::AddOutputChannel(word32 channelId)
149 m_outputChannelIds.push_back(channelId);
150 m_outputChannelIdStrings.push_back(
WordToString(channelId));
152 if (m_inputChannelIds.size() ==
size_t(m_threshold))
153 ComputeV((
unsigned int)m_outputChannelIds.size() - 1);
156 void RawIDA::PrepareInterpolation()
159 PrepareBulkPolynomialInterpolation(m_gf32, m_w.
begin(), &(m_inputChannelIds[0]), (
unsigned int)(m_threshold));
160 for (
unsigned int i=0; i<m_outputChannelIds.size(); i++)
164 void RawIDA::ProcessInputQueues()
166 bool finished = (m_channelsFinished == size_t(m_threshold));
169 while (finished ? m_channelsReady > 0 : m_channelsReady ==
size_t(m_threshold))
172 for (i=0; i<size_t(m_threshold); i++)
183 for (i=0; (
unsigned int)i<m_outputChannelIds.size(); i++)
185 if (m_outputToInput[i] !=
size_t(m_threshold))
186 m_outputQueues[i].
PutWord32(m_y[m_outputToInput[i]]);
187 else if (m_v[i].size() == size_t(m_threshold))
188 m_outputQueues[i].
PutWord32(BulkPolynomialInterpolateAt(m_gf32, m_y.
begin(), m_v[i].begin(), m_threshold));
192 PrepareBulkPolynomialInterpolationAt(m_gf32, m_u.
begin(), m_outputChannelIds[i], &(m_inputChannelIds[0]), m_w.
begin(), m_threshold);
193 m_outputQueues[i].PutWord32(BulkPolynomialInterpolateAt(m_gf32, m_y.
begin(), m_u.
begin(), m_threshold));
198 if (m_outputChannelIds.size() > 0 && m_outputQueues[0].AnyRetrievable())
206 m_channelsFinished = 0;
209 std::vector<MessageQueue> inputQueues;
210 std::vector<word32> inputChannelIds;
212 inputQueues.swap(m_inputQueues);
213 inputChannelIds.swap(m_inputChannelIds);
214 m_inputChannelMap.clear();
215 m_lastMapPosition = m_inputChannelMap.end();
217 for (i=0; i<size_t(m_threshold); i++)
219 inputQueues[i].GetNextMessage();
225 void RawIDA::FlushOutputQueues()
227 for (
unsigned int i=0; i<m_outputChannelIds.size(); i++)
231 void RawIDA::OutputMessageEnds()
235 for (
unsigned int i=0; i<m_outputChannelIds.size(); i++)
254 unsigned int threshold = m_ida.GetThreshold();
258 m_ida.ChannelData(0xffffffff, begin, len,
false);
259 for (
unsigned int i=0; i<threshold-1; i++)
262 m_ida.ChannelData(i, buf, len,
false);
274 while (m_ida.InputBuffered(0xffffffff) > 0)
277 m_ida.ChannelData(0xffffffff, NULLPTR, 0,
true);
278 for (
unsigned int i=0; i<m_ida.GetThreshold()-1; i++)
279 m_ida.ChannelData(i, NULLPTR, 0,
true);
291 void SecretRecovery::FlushOutputQueues()
299 void SecretRecovery::OutputMessageEnds()
304 m_outputQueues[0].TransferAllTo(paddingRemover);
327 m_ida.ChannelData(m_nextChannel, begin, 1,
false);
330 if (m_nextChannel == m_ida.GetThreshold())
339 for (word32 i=0; i<m_ida.GetThreshold(); i++)
340 m_ida.ChannelData(i, NULLPTR, 0,
true);
352 void InformationRecovery::FlushOutputQueues()
356 for (
unsigned int i=0; i<m_outputChannelIds.size(); i++)
366 void InformationRecovery::OutputMessageEnds()
383 const byte *
const end = begin + length;
385 if (m_possiblePadding)
387 size_t len =
FindIfNot(begin, end,
byte(0)) - begin;
394 while (m_zeroCount--)
397 m_possiblePadding =
false;
400 const byte *x =
FindIfNot(RevIt(end), RevIt(begin),
byte(0)).base();
401 if (x != begin && *(x-1) == 1)
404 m_possiblePadding =
true;
405 m_zeroCount = end - x;
412 m_possiblePadding =
false;
413 Output(0, begin, length, messageEnd, blocking);