182 const size_t RTSS_HEADER_SIZE = 20;
184 for(
size_t i = 0; i != shares.size(); ++i)
186 if(shares[i].
size() != shares[0].size())
187 throw Decoding_Error(
"Different sized RTSS shares detected");
189 throw Decoding_Error(
"Invalid (id = 0) RTSS share detected");
190 if(shares[i].
size() < RTSS_HEADER_SIZE)
191 throw Decoding_Error(
"Missing or malformed RTSS header");
193 if(!
same_mem(&shares[0].m_contents[0],
194 &shares[i].m_contents[0], RTSS_HEADER_SIZE))
195 throw Decoding_Error(
"Different RTSS headers detected");
198 if(shares.size() < shares[0].m_contents[17])
199 throw Decoding_Error(
"Insufficient shares to do TSS reconstruction");
201 uint16_t secret_len =
make_uint16(shares[0].m_contents[18],
202 shares[0].m_contents[19]);
204 uint8_t hash_id = shares[0].m_contents[16];
206 std::unique_ptr<HashFunction>
hash(get_rtss_hash_by_id(hash_id));
208 if(shares[0].
size() != secret_len +
hash->output_length() + RTSS_HEADER_SIZE + 1)
209 throw Decoding_Error(
"Bad RTSS length field in header");
211 std::vector<uint8_t> V(shares.size());
212 secure_vector<uint8_t> secret;
214 for(
size_t i = RTSS_HEADER_SIZE + 1; i != shares[0].size(); ++i)
216 for(
size_t j = 0; j != V.size(); ++j)
217 V[j] = shares[j].m_contents[i];
220 for(
size_t k = 0; k != shares.size(); ++k)
224 for(
size_t l = 0; l != shares.size(); ++l)
229 uint8_t share_k = shares[k].share_id();
230 uint8_t share_l = shares[l].share_id();
232 if(share_k == share_l)
233 throw Decoding_Error(
"Duplicate shares found in RTSS recovery");
235 uint8_t div = RTSS_EXP[(255 +
237 RTSS_LOG[share_k ^ share_l]) % 255];
239 r2 = gfp_mul(r2, div);
242 r ^= gfp_mul(V[k], r2);
247 if(secret.size() != secret_len +
hash->output_length())
248 throw Decoding_Error(
"Bad length in RTSS output");
250 hash->update(secret.data(), secret_len);
251 secure_vector<uint8_t> hash_check =
hash->final();
254 &secret[secret_len],
hash->output_length()))
255 throw Decoding_Error(
"RTSS hash check failed");
257 return secure_vector<uint8_t>(secret.cbegin(), secret.cbegin() + secret_len);
bool same_mem(const T *p1, const T *p2, size_t n)
uint16_t make_uint16(uint8_t i0, uint8_t i1)