def _share_secret_int(num_players, reconstruction_threshold, max_secret_length, secret): ''' Args: num_players, the number of shares to be distributed reconstruction_threshold, the number of shares needed for reconstruction any collection of fewer shares will reveal no information about the secret max_secret_length, the maximum length of the secret represented as a bytestring (ie, len(secret)) secret, an integer to be Shamir secret shared Returns: a list of tuples of (x, f(x)) values Raises: ValueError, the input parameters are invalid ''' bitlength = max(num_players.bit_length(), max_secret_length * 8) prime = primes.get_prime_by_bitlength(bitlength) if not _verify_parameters(num_players, reconstruction_threshold, secret, prime): raise ValueError("invalid secret sharing parameters") # fix n distinct points, alpha_1,...,alpha_n in Z_ps (public) alphas = [i for i in xrange(1, num_players + 1)] # choose at random t points, a_1,...,a_t in Z_ps (private) # we will use the a_i values as our coefficients to define the polynomial f(x) = (a_t x^t) + ... + (a_1 x) + s coefficients = [secret] + random.get_distinct_positive_random_ints_in_field(reconstruction_threshold - 1, prime) # for values of i from 1 to n, calculate f(alpha_i) return polynomials.evaluate(coefficients, alphas, prime)
def get_large_prime(max_length): ''' Generate a large prime that accommodates the max message length or defaults to a large prime Args: integer value of maximum digit-length for a message Returns: a sufficiently large prime to be used in the check vector authentication scheme ''' bitlength = max(PRIME_EXP, max_length * 8) return primes.get_prime_by_bitlength(bitlength)
def _reconstruct_secret_int(num_players, max_secret_length, shares): ''' Args: num_players, the total number of players (can be greater than or equal to the number of shares) max_secret_length, the maximum length of the secret represented as a bytestring (ie, len(secret)) shares, a list of tuples representing (x, f(x)) values Returns: the integer that was shared by _share_secret_int if all shares are valid otherwise, no guarantees are made about the value of the integer returned ''' bitlength = max(num_players.bit_length(), max_secret_length * 8) prime = primes.get_prime_by_bitlength(bitlength) return polynomials.interpolate(shares, prime)(0)
def test_get_prime_by_bitlength_prime(): secret_size = 17 assert primes.get_prime_by_bitlength(secret_size) == 2**19 - 1
def test_get_prime_by_bitlength_negative(): secret_size = -7 with pytest.raises(ValueError): primes.get_prime_by_bitlength(secret_size)
def test_get_prime_by_bitlength_standard(): secret_size = 61 assert primes.get_prime_by_bitlength(secret_size) == 2**89 - 1
def test_get_prime_by_bitlength_too_large(): secret_size = 4444 with pytest.raises(ValueError): primes.get_prime_by_bitlength(secret_size)
def test_get_prime_by_bitlength_very_large(): secret_size = 4400 assert primes.get_prime_by_bitlength(secret_size) == 2**4423 - 1
def test_get_prime_by_batch_equal_prime(): secret_size = 521 assert primes.get_prime_by_bitlength(secret_size) == 2**607 - 1
def test_get_prime_by_bitlength_zero(): secret_size = 0 assert primes.get_prime_by_bitlength(secret_size) == 2**2 - 1