Botan  2.6.0
Crypto and TLS for C++11
Public Member Functions | Static Public Member Functions | List of all members
Botan::RTSS_Share Class Referencefinal

#include <tss.h>

Public Member Functions

bool initialized () const
 
 RTSS_Share ()=default
 
 RTSS_Share (const std::string &hex_input)
 
uint8_t share_id () const
 
size_t size () const
 
std::string to_string () const
 

Static Public Member Functions

static secure_vector< uint8_t > reconstruct (const std::vector< RTSS_Share > &shares)
 
static std::vector< RTSS_Sharesplit (uint8_t M, uint8_t N, const uint8_t secret[], uint16_t secret_len, const uint8_t identifier[16], RandomNumberGenerator &rng)
 

Detailed Description

A split secret, using the format from draft-mcgrew-tss-03

Definition at line 21 of file tss.h.

Constructor & Destructor Documentation

◆ RTSS_Share() [1/2]

Botan::RTSS_Share::RTSS_Share ( )
default

◆ RTSS_Share() [2/2]

Botan::RTSS_Share::RTSS_Share ( const std::string &  hex_input)
explicit
Parameters
hex_inputthe share encoded in hexadecimal

Definition at line 105 of file tss.cpp.

References Botan::hex_decode_locked().

106  {
107  m_contents = hex_decode_locked(hex_input);
108  }
secure_vector< uint8_t > hex_decode_locked(const char input[], size_t input_length, bool ignore_ws)
Definition: hex.cpp:165

Member Function Documentation

◆ initialized()

bool Botan::RTSS_Share::initialized ( ) const
inline
Returns
if this TSS share was initialized or not

Definition at line 69 of file tss.h.

Referenced by share_id().

69 { return (m_contents.size() > 0); }

◆ reconstruct()

secure_vector< uint8_t > Botan::RTSS_Share::reconstruct ( const std::vector< RTSS_Share > &  shares)
static
Parameters
sharesthe list of shares

Definition at line 181 of file tss.cpp.

References Botan::constant_time_compare(), hash, Botan::make_uint16(), Botan::same_mem(), share_id(), and size().

182  {
183  const size_t RTSS_HEADER_SIZE = 20;
184 
185  for(size_t i = 0; i != shares.size(); ++i)
186  {
187  if(shares[i].size() != shares[0].size())
188  throw Decoding_Error("Different sized RTSS shares detected");
189  if(shares[i].share_id() == 0)
190  throw Decoding_Error("Invalid (id = 0) RTSS share detected");
191  if(shares[i].size() < RTSS_HEADER_SIZE)
192  throw Decoding_Error("Missing or malformed RTSS header");
193 
194  if(!same_mem(&shares[0].m_contents[0],
195  &shares[i].m_contents[0], RTSS_HEADER_SIZE))
196  throw Decoding_Error("Different RTSS headers detected");
197  }
198 
199  if(shares.size() < shares[0].m_contents[17])
200  throw Decoding_Error("Insufficient shares to do TSS reconstruction");
201 
202  uint16_t secret_len = make_uint16(shares[0].m_contents[18],
203  shares[0].m_contents[19]);
204 
205  uint8_t hash_id = shares[0].m_contents[16];
206 
207  std::unique_ptr<HashFunction> hash(get_rtss_hash_by_id(hash_id));
208 
209  if(shares[0].size() != secret_len + hash->output_length() + RTSS_HEADER_SIZE + 1)
210  throw Decoding_Error("Bad RTSS length field in header");
211 
212  std::vector<uint8_t> V(shares.size());
213  secure_vector<uint8_t> secret;
214 
215  for(size_t i = RTSS_HEADER_SIZE + 1; i != shares[0].size(); ++i)
216  {
217  for(size_t j = 0; j != V.size(); ++j)
218  V[j] = shares[j].m_contents[i];
219 
220  uint8_t r = 0;
221  for(size_t k = 0; k != shares.size(); ++k)
222  {
223  // L_i function:
224  uint8_t r2 = 1;
225  for(size_t l = 0; l != shares.size(); ++l)
226  {
227  if(k == l)
228  continue;
229 
230  uint8_t share_k = shares[k].share_id();
231  uint8_t share_l = shares[l].share_id();
232 
233  if(share_k == share_l)
234  throw Decoding_Error("Duplicate shares found in RTSS recovery");
235 
236  uint8_t div = RTSS_EXP[(255 +
237  RTSS_LOG[share_l] -
238  RTSS_LOG[share_k ^ share_l]) % 255];
239 
240  r2 = gfp_mul(r2, div);
241  }
242 
243  r ^= gfp_mul(V[k], r2);
244  }
245  secret.push_back(r);
246  }
247 
248  if(secret.size() != secret_len + hash->output_length())
249  throw Decoding_Error("Bad length in RTSS output");
250 
251  hash->update(secret.data(), secret_len);
252  secure_vector<uint8_t> hash_check = hash->final();
253 
254  if(!constant_time_compare(hash_check.data(),
255  &secret[secret_len],
256  hash->output_length()))
257  {
258  throw Decoding_Error("RTSS hash check failed");
259  }
260 
261  return secure_vector<uint8_t>(secret.cbegin(), secret.cbegin() + secret_len);
262  }
bool same_mem(const T *p1, const T *p2, size_t n)
Definition: mem_ops.h:158
bool constant_time_compare(const uint8_t x[], const uint8_t y[], size_t len)
Definition: mem_ops.cpp:51
uint8_t share_id() const
Definition: tss.cpp:110
size_t size() const
Definition: tss.h:64
uint16_t make_uint16(uint8_t i0, uint8_t i1)
Definition: loadstor.h:52
MechanismType hash

◆ share_id()

uint8_t Botan::RTSS_Share::share_id ( ) const
Returns
share identifier

Definition at line 110 of file tss.cpp.

References initialized().

Referenced by reconstruct().

111  {
112  if(!initialized())
113  throw Invalid_State("RTSS_Share::share_id not initialized");
114 
115  return m_contents[20];
116  }
bool initialized() const
Definition: tss.h:69

◆ size()

size_t Botan::RTSS_Share::size ( ) const
inline
Returns
size of this share in bytes

Definition at line 64 of file tss.h.

Referenced by reconstruct().

64 { return m_contents.size(); }

◆ split()

std::vector< RTSS_Share > Botan::RTSS_Share::split ( uint8_t  M,
uint8_t  N,
const uint8_t  secret[],
uint16_t  secret_len,
const uint8_t  identifier[16],
RandomNumberGenerator rng 
)
static
Parameters
Mthe number of shares needed to reconstruct
Nthe number of shares generated
secretthe secret to split
secret_lenthe length of the secret
identifierthe 16 byte share identifier
rngthe random number generator to use

Definition at line 124 of file tss.cpp.

References Botan::HashFunction::create_or_throw(), Botan::get_byte(), hash, Botan::RandomNumberGenerator::randomize(), and X.

128  {
129  if(M == 0 || N == 0 || M > N)
130  throw Encoding_Error("RTSS_Share::split: M == 0 or N == 0 or M > N");
131 
132  // always use SHA-256 when generating shares
133  std::unique_ptr<HashFunction> hash = HashFunction::create_or_throw("SHA-256");
134 
135  std::vector<RTSS_Share> shares(N);
136 
137  // Create RTSS header in each share
138  for(uint8_t i = 0; i != N; ++i)
139  {
140  shares[i].m_contents += std::make_pair(identifier, 16);
141  shares[i].m_contents += rtss_hash_id(hash->name());
142  shares[i].m_contents += M;
143  shares[i].m_contents += get_byte(0, S_len);
144  shares[i].m_contents += get_byte(1, S_len);
145  }
146 
147  // Choose sequential values for X starting from 1
148  for(uint8_t i = 0; i != N; ++i)
149  shares[i].m_contents.push_back(i+1);
150 
151  // secret = S || H(S)
152  secure_vector<uint8_t> secret(S, S + S_len);
153  secret += hash->process(S, S_len);
154 
155  for(size_t i = 0; i != secret.size(); ++i)
156  {
157  std::vector<uint8_t> coefficients(M-1);
158  rng.randomize(coefficients.data(), coefficients.size());
159 
160  for(uint8_t j = 0; j != N; ++j)
161  {
162  const uint8_t X = j + 1;
163 
164  uint8_t sum = secret[i];
165  uint8_t X_i = X;
166 
167  for(size_t k = 0; k != coefficients.size(); ++k)
168  {
169  sum ^= gfp_mul(X_i, coefficients[k]);
170  X_i = gfp_mul(X_i, X);
171  }
172 
173  shares[j].m_contents.push_back(sum);
174  }
175  }
176 
177  return shares;
178  }
fe X
Definition: ge.cpp:27
static std::unique_ptr< HashFunction > create_or_throw(const std::string &algo_spec, const std::string &provider="")
Definition: hash.cpp:345
uint8_t get_byte(size_t byte_num, T input)
Definition: loadstor.h:39
MechanismType hash

◆ to_string()

std::string Botan::RTSS_Share::to_string ( ) const
Returns
hex representation

Definition at line 118 of file tss.cpp.

References Botan::hex_encode().

119  {
120  return hex_encode(m_contents.data(), m_contents.size());
121  }
void hex_encode(char output[], const uint8_t input[], size_t input_length, bool uppercase)
Definition: hex.cpp:14

The documentation for this class was generated from the following files: