Botan  1.11.15
Public Member Functions | Static Public Member Functions
Botan::RTSS_Share Class Reference

#include <tss.h>

List of all members.

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< bytereconstruct (const std::vector< RTSS_Share > &shares)
static std::vector< RTSS_Sharesplit (byte M, byte N, const byte secret[], u16bit secret_len, const byte 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

Definition at line 44 of file tss.h.

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

Definition at line 106 of file tss.cpp.

References Botan::hex_decode_locked().

   {
   contents = hex_decode_locked(hex_input);
   }

Member Function Documentation

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().

{ return (contents.size() > 0); }
secure_vector< byte > 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::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]);
   }
Returns:
share identifier

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]
Returns:
size of this share in bytes

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]
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 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
Returns:
hex representation

Definition at line 119 of file tss.cpp.

References Botan::hex_encode().

   {
   return hex_encode(&contents[0], contents.size());
   }

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