1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
use crate::cryptosystems::{AssociatedCiphertext, EncryptionKey};
use crate::randomness::GeneralRng;
use crate::randomness::SecureRng;
use crate::security::BitsOfSecurity;
use crate::DecryptionError;
/// An asymmetric threshold cryptosystem is a system of methods to encrypt plaintexts into
/// ciphertexts, but instead of having a single secret key to decrypt them back into plaintexts, we
/// require a given number of parties to decrypt with their own partial key. If enough parties
/// partially decrypt, the resulting shares can be combined into the original plaintext. Still,
/// anyone who has access to the public key can perform encryptions.
///
/// We denote a threshold cryptosystem using a tuple like (t, n). This means that t parties can
/// collectively decrypt, and that there are in total n partial keys. In this special case, all n
/// keys must be used to decrypt.
///
/// The struct that implements an `NOfNCryptosystem` will hold the general parameters
/// of that cryptosystem. Depending on the cryptosystem, those parameters could play an important
/// role in deciding the level of security. As such, each cryptosystem should clearly indicate
/// these.
pub trait NOfNCryptosystem {
/// The public key used to encrypt plaintexts.
type PublicKey: EncryptionKey;
/// The secret key used to partially decrypt ciphertexts.
type SecretKey: PartialDecryptionKey<Self::PublicKey>;
/// Sets up an instance of this cryptosystem with parameters satisfying the security parameter.
fn setup(security_parameter: &BitsOfSecurity) -> Self;
/// Generate a public key, and $n$ secret keys using a cryptographic RNG.
fn generate_keys<R: SecureRng>(
&self,
key_count_n: usize,
rng: &mut GeneralRng<R>,
) -> (Self::PublicKey, Vec<Self::SecretKey>);
}
/// A partial decryption key partially decrypts ciphertexts to return a decryption share. If enough decryption shares of different keys are combined, they output the correct decryption.
pub trait PartialDecryptionKey<PK: EncryptionKey> {
/// The type of the decryption share. If enough decryption shares of different keys are combined, they output the correct decryption.
type DecryptionShare: DecryptionShare<PK>;
/// Partially decrypts a ciphertext, returning a valid decryption share.
fn partial_decrypt<'pk>(
&self,
ciphertext: &AssociatedCiphertext<'pk, PK::Ciphertext, PK>,
) -> Self::DecryptionShare {
self.partial_decrypt_raw(ciphertext.public_key, &ciphertext.ciphertext)
}
/// Partially decrypts a ciphertext, returning a valid decryption share.
fn partial_decrypt_raw(
&self,
public_key: &PK,
ciphertext: &PK::Ciphertext,
) -> Self::DecryptionShare;
}
/// A `DecryptionShare` is the result of decrypting with a partial key. When enough of these shares
/// are combined, they reveal the actual decryption.
pub trait DecryptionShare<PK: EncryptionKey>: Sized {
/// Combine $t$ decryption shares belonging to distinct partial keys to finish decryption. It is
/// the responsibility of the programmer to supply the right number of decryption shares to
/// this function.
fn combine(
decryption_shares: &[Self],
public_key: &PK,
) -> Result<PK::Plaintext, DecryptionError>;
}
/// An asymmetric threshold cryptosystem is a system of methods to encrypt plaintexts into
/// ciphertexts, but instead of having a single secret key to decrypt them back into plaintexts, we
/// require a given number of parties to decrypt with their own partial key. If enough parties
/// partially decrypt, the resulting shares can be combined into the original plaintext. Still,
/// anyone who has access to the public key can perform encryptions.
///
/// We denote a threshold cryptosystem using a tuple like (t, n). This means that t parties can
/// collectively decrypt, and that there are in total n partial keys.
///
/// The struct that implements an `TOfNCryptosystem` will hold the general parameters
/// of that cryptosystem. Depending on the cryptosystem, those parameters could play an important
/// role in deciding the level of security. As such, each cryptosystem should clearly indicate
/// these.
pub trait TOfNCryptosystem {
/// The public key used to encrypt plaintexts.
type PublicKey: EncryptionKey;
/// The secret key used to partially decrypt ciphertexts.
type SecretKey: PartialDecryptionKey<Self::PublicKey>;
/// Sets up an instance of this cryptosystem with parameters satisfying the security parameter.
fn setup(security_parameter: &BitsOfSecurity) -> Self;
/// Generate a public and private key pair using a cryptographic RNG.
fn generate_keys<R: SecureRng>(
&self,
threshold_t: usize,
key_count_n: usize,
rng: &mut GeneralRng<R>,
) -> (Self::PublicKey, Vec<Self::SecretKey>);
}