|
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());
}
1.7.6.1