示例#1
0
        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
示例#2
0
    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)
示例#3
0
    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)
示例#4
0
    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)
示例#5
0
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
示例#6
0
    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)
示例#7
0
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