Example #1
0
    def decode(self, plain):
        """Decodes a plaintext polynomial and returns the integer.

        Mathematically this amounts to evaluating the input polynomial at x=2.

        Args:
            plain: The plaintext to be decoded.

        Returns:
            An integer value.
        """

        result = 0
        bit_index = get_significant_count(plain.data)
        while bit_index > 0:
            bit_index -= 1
            coeff = plain.data[bit_index]

            # Left shift result.
            next_result = result << 1
            if (next_result < 0) != (result < 0):
                # Check for overflow.
                raise OverflowError("output out of range")

            if coeff >= self.plain_modulus:
                # Coefficient is bigger than plaintext modulus
                raise ValueError("plain does not represent a valid plaintext polynomial")

            coeff_is_negative = coeff >= self.coeff_neg_threshold
            pos_value = coeff

            if coeff_is_negative:
                pos_value = self.plain_modulus - pos_value

            coeff_value = pos_value
            if coeff_is_negative:
                coeff_value = -coeff_value

            next_result_was_negative = next_result < 0
            next_result += coeff_value
            next_result_is_negative = next_result < 0
            if (
                next_result_was_negative == coeff_is_negative
                and next_result_was_negative != next_result_is_negative
            ):
                # Accumulation and coefficient had same signs, but accumulator changed signs
                # after addition, so must be overflow.
                raise OverflowError("output out of range")
            result = next_result
        return result
Example #2
0
    def decrypt(self, encrypted):
        """Decrypts the encrypted ciphertext objects.

        Args:
            encrypted: A ciphertext object which has to be decrypted.

        Returns:
            A PlainText object containing the decrypted result.
        """

        # Calculate [c0 + c1 * sk + c2 * sk^2 ...]_q
        temp_product_modq = self._mul_ct_sk(copy.deepcopy(encrypted.data))

        # Divide scaling variant using BEHZ FullRNS techniques
        result = self._context.rns_tool.decrypt_scale_and_round(temp_product_modq)

        # removing leading zeroes in plaintext representation.
        plain_coeff_count = get_significant_count(result)
        return PlainText(result[:plain_coeff_count])
Example #3
0
def test_get_significant_count(ptr, result):
    assert result == get_significant_count(ptr)