コード例 #1
0
    def test_ccp_proof(
        self,
        keypair: ElGamalKeyPair,
        nonce: ElementModQ,
        seed: ElementModQ,
        constant: int,
        bad_constant: int,
    ):
        if constant == bad_constant:
            bad_constant = constant + 1

        message = get_optional(elgamal_encrypt(constant, nonce, keypair.public_key))
        decryption = message.partial_decrypt(keypair.secret_key)
        proof = make_chaum_pedersen(
            message, keypair.secret_key, decryption, seed, ONE_MOD_Q
        )
        bad_proof = make_chaum_pedersen(
            message, keypair.secret_key, int_to_p(bad_constant), seed, ONE_MOD_Q
        )
        self.assertTrue(
            proof.is_valid(message, keypair.public_key, decryption, ONE_MOD_Q)
        )
        self.assertFalse(
            bad_proof.is_valid(message, keypair.public_key, decryption, ONE_MOD_Q)
        )
コード例 #2
0
 def test_cp_proofs_simple(self):
     keypair = elgamal_keypair_from_secret(TWO_MOD_Q)
     nonce = ONE_MOD_Q
     seed = TWO_MOD_Q
     message = get_optional(elgamal_encrypt(0, nonce, keypair.public_key))
     decryption = message.partial_decrypt(keypair.secret_key)
     proof = make_chaum_pedersen(message, keypair.secret_key, decryption,
                                 seed, ONE_MOD_Q)
     bad_proof = make_chaum_pedersen(message, keypair.secret_key, TWO_MOD_Q,
                                     seed, ONE_MOD_Q)
     self.assertTrue(
         proof.is_valid(message, keypair.public_key, decryption, ONE_MOD_Q))
     self.assertFalse(
         bad_proof.is_valid(message, keypair.public_key, decryption,
                            ONE_MOD_Q))
コード例 #3
0
def partially_decrypt(
    guardian_keys: ElectionKeyPair,
    elgamal: ElGamalCiphertext,
    extended_base_hash: ElementModQ,
    nonce_seed: ElementModQ = None,
) -> Tuple[ElementModP, ChaumPedersenProof]:
    """
    Compute a partial decryption of an elgamal encryption

    :param elgamal: the `ElGamalCiphertext` that will be partially decrypted
    :param extended_base_hash: the extended base hash of the election that
                                was used to generate t he ElGamal Ciphertext
    :param nonce_seed: an optional value used to generate the `ChaumPedersenProof`
                        if no value is provided, a random number will be used.
    :return: a `Tuple[ElementModP, ChaumPedersenProof]` of the decryption and its proof
    """
    if nonce_seed is None:
        nonce_seed = rand_q()

    # TODO: ISSUE #47: Decrypt the election secret key

    # 𝑀_i = 𝐴^𝑠𝑖 mod 𝑝
    partial_decryption = elgamal.partial_decrypt(
        guardian_keys.key_pair.secret_key)

    # 𝑀_i = 𝐴^𝑠𝑖 mod 𝑝 and 𝐾𝑖 = 𝑔^𝑠𝑖 mod 𝑝
    proof = make_chaum_pedersen(
        message=elgamal,
        s=guardian_keys.key_pair.secret_key,
        m=partial_decryption,
        seed=nonce_seed,
        hash_header=extended_base_hash,
    )

    return (partial_decryption, proof)
コード例 #4
0
def compensate_decrypt(
    guardian_auxiliary_keys: AuxiliaryKeyPair,
    missing_guardian_backup: ElectionPartialKeyBackup,
    ciphertext: ElGamalCiphertext,
    extended_base_hash: ElementModQ,
    nonce_seed: ElementModQ = None,
    decrypt: AuxiliaryDecrypt = rsa_decrypt,
) -> Optional[Tuple[ElementModP, ChaumPedersenProof]]:
    """
    Compute a compensated partial decryption of an elgamal encryption
    on behalf of the missing guardian

    :param guardian_auxiliary_keys: Auxiliary key pair for guardian decrypting
    :param missing_guardian_backup: Missing guardians backup
    :param ciphertext: the `ElGamalCiphertext` that will be partially decrypted
    :param extended_base_hash: the extended base hash of the election that
                                was used to generate t he ElGamal Ciphertext
    :param nonce_seed: an optional value used to generate the `ChaumPedersenProof`
                        if no value is provided, a random number will be used.
    :param decrypt: an `AuxiliaryDecrypt` function to decrypt the missing guardina private key backup
    :return: a `Tuple[ElementModP, ChaumPedersenProof]` of the decryption and its proof
    """
    if nonce_seed is None:
        nonce_seed = rand_q()

    decrypted_value = decrypt(missing_guardian_backup.encrypted_value,
                              guardian_auxiliary_keys.secret_key)
    if decrypted_value is None:
        log_warning(
            (f"compensate decrypt guardian {guardian_auxiliary_keys.owner_id}"
             f" failed decryption for {missing_guardian_backup.owner_id}"))
        return None
    partial_secret_key = get_optional(hex_to_q(decrypted_value))

    # 𝑀_{𝑖,l} = 𝐴^P𝑖_{l}
    partial_decryption = ciphertext.partial_decrypt(partial_secret_key)

    # 𝑀_{𝑖,l} = 𝐴^𝑠𝑖 mod 𝑝 and 𝐾𝑖 = 𝑔^𝑠𝑖 mod 𝑝
    proof = make_chaum_pedersen(
        ciphertext,
        partial_secret_key,
        partial_decryption,
        nonce_seed,
        extended_base_hash,
    )

    return (partial_decryption, proof)