def lam(i: int) -> int: S_prime = self.S - {i} l = self.public_key.delta % self.public_key.n_s_m for i_prime in S_prime: l = l * i_prime * inv_mod(i_prime - i, self.public_key.n_s_m) % self.public_key.n_s_m return l
def __rsub__(self, other: Any) -> 'EncryptedNumber': """See `__sub__`.""" # Multiply self by -1 via inv_mod self_inv = EncryptedNumber( value=inv_mod(self.value, self.public_key.n_s_1), public_key=self.public_key ) return self_inv.__add__(other)
def __truediv__(self, other: int): """Divides an EncryptedNumber by a scalar. Applies the appropriate operations such that the result is an EncryptedNumber that decrypts to the quotient of the the decryption of this number divided by `other`. :param other: An integer. :return: An EncryptedNumber containing the quotient of this number and `other`. """ return self * inv_mod(other, self.public_key.n_s_1)
def __init__(self, private_key_shares: List[PrivateKeyShare]): """Initializes the PrivateKeyRing, checks that enough PrivateKeyShares are provided, and performs pre-computations. :param private_key_shares: A list of PrivateKeyShares. """ if len(private_key_shares) == 0: raise ValueError('Must have at least one PrivateKeyShare') if len({pks.public_key for pks in private_key_shares}) > 1: raise ValueError('PrivateKeyShares do not have the same public key') public_key = private_key_shares[0].public_key private_key_shares = set(private_key_shares) if len(private_key_shares) < public_key.threshold: raise ValueError('Number of unique PrivateKeyShares is less than the threshold to decrypt') self.public_key = public_key self.private_key_shares = list(private_key_shares)[:self.public_key.threshold] self.i_list = [pks.i for pks in self.private_key_shares] self.S = set(self.i_list) self.inv_four_delta_squared = inv_mod(4 * (self.public_key.delta ** 2), self.public_key.n_s)
def damgard_jurik_reduce(a: int, s: int, n: int) -> int: """Computes i given a = (1 + n)^i (mod n^(s+1)). :param a: The integer a in the above equation. :param s: The integer s in the above equation. :param n: The integer n in the above equation. :return: The integer i in the above equation. """ def L(b: int) -> int: assert (b - 1) % n == 0 return (b - 1) // n @lru_cache(int(s)) @int_to_mpz def n_pow(p: int) -> int: return n ** p @lru_cache(int(s)) @int_to_mpz def fact(k: int) -> int: return mpz(factorial(k)) i = mpz(0) for j in range(1, s + 1): j = mpz(j) t_1 = L(a % n_pow(j + 1)) t_2 = i for k in range(2, j + 1): k = mpz(k) i = i - 1 t_2 = t_2 * i % n_pow(j) t_1 = t_1 - (t_2 * n_pow(k - 1) * inv_mod(fact(k), n_pow(j))) % n_pow(j) i = t_1 return i
def __sub__(self, other: Any) -> 'EncryptedNumber': """Subtracts two EncryptedNumbers. Applies the appropriate operations such that the result is an EncryptedNumber that decrypts to the difference of the the decryption of this number and the decryption of `other`. :param other: An EncryptedNumber. :return: An EncryptedNumber containing the difference of this number and `other`. """ if not isinstance(other, EncryptedNumber): raise ValueError('Can only add/subtract an EncryptedNumber from another EncryptedNumber') if self.public_key != other.public_key: raise ValueError("Attempted to add/subtract numbers encrypted against different public keys!") # Multiply other by -1 via inv_mod other_inv = EncryptedNumber( value=inv_mod(other.value, other.public_key.n_s_1), public_key=other.public_key ) return self.__add__(other_inv)
def reconstruct(shares: List[Tuple[int, int]], modulus: int) -> int: """Reconstructs a secret from shares. Assumes the shares are unique and there are at least as many shares as the required threshold. :param shares: Shares of a secret. :param modulus: The modulus used when sharing the secret. :return: The secret. """ # Convert to mpz shares = [(mpz(x), mpz(f_x)) for x, f_x in shares] # Reconstruct secret secret = mpz(0) for i, (x_i, f_x_i) in enumerate(shares): product = mpz(1) for j, (x_j, _) in enumerate(shares): if i != j: product = product * x_j * inv_mod(x_j - x_i, modulus) % modulus secret = (secret + f_x_i * product % modulus) % modulus return secret