Botan
1.11.15
|
#include <tss.h>
Public Member Functions | |
bool | initialized () const |
RTSS_Share () | |
RTSS_Share (const std::string &hex_input) | |
byte | share_id () const |
size_t | size () const |
std::string | to_string () const |
Static Public Member Functions | |
static secure_vector< byte > | reconstruct (const std::vector< RTSS_Share > &shares) |
static std::vector< RTSS_Share > | split (byte M, byte N, const byte secret[], u16bit secret_len, const byte identifier[16], RandomNumberGenerator &rng) |
Botan::RTSS_Share::RTSS_Share | ( | ) | [inline] |
Botan::RTSS_Share::RTSS_Share | ( | const std::string & | hex_input | ) |
hex_input | the share encoded in hexadecimal |
Definition at line 106 of file tss.cpp.
References Botan::hex_decode_locked().
{ contents = hex_decode_locked(hex_input); }
bool Botan::RTSS_Share::initialized | ( | ) | const [inline] |
Definition at line 69 of file tss.h.
Referenced by share_id().
{ return (contents.size() > 0); }
secure_vector< byte > Botan::RTSS_Share::reconstruct | ( | const std::vector< RTSS_Share > & | shares | ) | [static] |
shares | the list of shares |
Definition at line 181 of file tss.cpp.
References Botan::make_u16bit(), Botan::same_mem(), share_id(), and size().
{ const size_t RTSS_HEADER_SIZE = 20; for(size_t i = 0; i != shares.size(); ++i) { if(shares[i].size() != shares[0].size()) throw Decoding_Error("Different sized RTSS shares detected"); if(shares[i].share_id() == 0) throw Decoding_Error("Invalid (id = 0) RTSS share detected"); if(shares[i].size() < RTSS_HEADER_SIZE) throw Decoding_Error("Missing or malformed RTSS header"); if(!same_mem(&shares[0].contents[0], &shares[i].contents[0], RTSS_HEADER_SIZE)) throw Decoding_Error("Different RTSS headers detected"); } if(shares.size() < shares[0].contents[17]) throw Decoding_Error("Insufficient shares to do TSS reconstruction"); u16bit secret_len = make_u16bit(shares[0].contents[18], shares[0].contents[19]); byte hash_id = shares[0].contents[16]; std::unique_ptr<HashFunction> hash(get_rtss_hash_by_id(hash_id)); if(shares[0].size() != secret_len + hash->output_length() + RTSS_HEADER_SIZE + 1) throw Decoding_Error("Bad RTSS length field in header"); std::vector<byte> V(shares.size()); secure_vector<byte> secret; for(size_t i = RTSS_HEADER_SIZE + 1; i != shares[0].size(); ++i) { for(size_t j = 0; j != V.size(); ++j) V[j] = shares[j].contents[i]; byte r = 0; for(size_t k = 0; k != shares.size(); ++k) { // L_i function: byte r2 = 1; for(size_t l = 0; l != shares.size(); ++l) { if(k == l) continue; byte share_k = shares[k].share_id(); byte share_l = shares[l].share_id(); if(share_k == share_l) throw Decoding_Error("Duplicate shares found in RTSS recovery"); byte div = RTSS_EXP[(255 + RTSS_LOG[share_l] - RTSS_LOG[share_k ^ share_l]) % 255]; r2 = gfp_mul(r2, div); } r ^= gfp_mul(V[k], r2); } secret.push_back(r); } if(secret.size() != secret_len + hash->output_length()) throw Decoding_Error("Bad length in RTSS output"); hash->update(&secret[0], secret_len); secure_vector<byte> hash_check = hash->final(); if(!same_mem(&hash_check[0], &secret[secret_len], hash->output_length())) throw Decoding_Error("RTSS hash check failed"); return secure_vector<byte>(&secret[0], &secret[secret_len]); }
byte Botan::RTSS_Share::share_id | ( | ) | const |
Definition at line 111 of file tss.cpp.
References initialized().
Referenced by reconstruct().
{ if(!initialized()) throw Invalid_State("RTSS_Share::share_id not initialized"); return contents[20]; }
size_t Botan::RTSS_Share::size | ( | ) | const [inline] |
Definition at line 64 of file tss.h.
Referenced by reconstruct().
{ return contents.size(); }
std::vector< RTSS_Share > Botan::RTSS_Share::split | ( | byte | M, |
byte | N, | ||
const byte | secret[], | ||
u16bit | secret_len, | ||
const byte | identifier[16], | ||
RandomNumberGenerator & | rng | ||
) | [static] |
M | the number of shares needed to reconstruct |
N | the number of shares generated |
secret | the secret to split |
secret_len | the length of the secret |
identifier | the 16 byte share identifier |
rng | the random number generator to use |
Definition at line 125 of file tss.cpp.
References Botan::get_byte(), Botan::SHA_256::name(), Botan::Buffered_Computation::process(), and Botan::RandomNumberGenerator::randomize().
{ if(M == 0 || N == 0 || M > N) throw Encoding_Error("RTSS_Share::split: M == 0 or N == 0 or M > N"); SHA_256 hash; // always use SHA-256 when generating shares std::vector<RTSS_Share> shares(N); // Create RTSS header in each share for(byte i = 0; i != N; ++i) { shares[i].contents += std::make_pair(identifier, 16); shares[i].contents += rtss_hash_id(hash.name()); shares[i].contents += M; shares[i].contents += get_byte(0, S_len); shares[i].contents += get_byte(1, S_len); } // Choose sequential values for X starting from 1 for(byte i = 0; i != N; ++i) shares[i].contents.push_back(i+1); // secret = S || H(S) secure_vector<byte> secret(S, S + S_len); secret += hash.process(S, S_len); for(size_t i = 0; i != secret.size(); ++i) { std::vector<byte> coefficients(M-1); rng.randomize(&coefficients[0], coefficients.size()); for(byte j = 0; j != N; ++j) { const byte X = j + 1; byte sum = secret[i]; byte X_i = X; for(size_t k = 0; k != coefficients.size(); ++k) { sum ^= gfp_mul(X_i, coefficients[k]); X_i = gfp_mul(X_i, X); } shares[j].contents.push_back(sum); } } return shares; }
std::string Botan::RTSS_Share::to_string | ( | ) | const |
Definition at line 119 of file tss.cpp.
References Botan::hex_encode().
{ return hex_encode(&contents[0], contents.size()); }