Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/jellevos/scicrypt
Browse files Browse the repository at this point in the history
  • Loading branch information
jellevos committed Sep 7, 2022
2 parents eee8507 + 2d26bc4 commit d205b21
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 0 deletions.
30 changes: 30 additions & 0 deletions scicrypt-he/src/cryptosystems/curve_el_gamal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,14 @@ impl DecryptionKey<CurveElGamalPK> for CurveElGamalSK {
) -> RistrettoPoint {
self.decrypt_directly(ciphertext)
}

fn decrypt_identity_raw(
&self,
_public_key: &CurveElGamalPK,
ciphertext: &<CurveElGamalPK as EncryptionKey>::Ciphertext,
) -> bool {
ciphertext.c2 == self.key * ciphertext.c1
}
}

impl DecryptionKey<PrecomputedCurveElGamalPK> for CurveElGamalSK {
Expand All @@ -170,6 +178,14 @@ impl DecryptionKey<PrecomputedCurveElGamalPK> for CurveElGamalSK {
) -> RistrettoPoint {
self.decrypt_directly(ciphertext)
}

fn decrypt_identity_raw(
&self,
_public_key: &PrecomputedCurveElGamalPK,
ciphertext: &<CurveElGamalPK as EncryptionKey>::Ciphertext,
) -> bool {
ciphertext.c2 == self.key * ciphertext.c1
}
}

impl HomomorphicAddition for CurveElGamalPK {
Expand Down Expand Up @@ -282,7 +298,9 @@ impl HomomorphicAddition for PrecomputedCurveElGamalPK {
mod tests {
use crate::cryptosystems::curve_el_gamal::CurveElGamal;
use curve25519_dalek::constants::RISTRETTO_BASEPOINT_POINT;
use curve25519_dalek::ristretto::RistrettoPoint;
use curve25519_dalek::scalar::Scalar;
use curve25519_dalek::traits::Identity;
use rand_core::OsRng;
use scicrypt_traits::cryptosystems::{AsymmetricCryptosystem, DecryptionKey, EncryptionKey};
use scicrypt_traits::randomness::GeneralRng;
Expand All @@ -299,6 +317,18 @@ mod tests {
assert_eq!(RISTRETTO_BASEPOINT_POINT, sk.decrypt(&ciphertext));
}

#[test]
fn test_encrypt_decrypt_identity() {
let mut rng = GeneralRng::new(OsRng);

let el_gamal = CurveElGamal::setup(&Default::default());
let (pk, sk) = el_gamal.generate_keys(&mut rng);

let ciphertext = pk.encrypt(&RistrettoPoint::identity(), &mut rng);

assert!(sk.decrypt_identity(&ciphertext));
}

#[test]
fn test_probabilistic_encryption() {
let mut rng = GeneralRng::new(OsRng);
Expand Down
25 changes: 25 additions & 0 deletions scicrypt-he/src/cryptosystems/integer_el_gamal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,19 @@ impl DecryptionKey<IntegerElGamalPK> for IntegerElGamalSK {
.unwrap())
.rem(&public_key.modulus)
}

fn decrypt_identity_raw(
&self,
public_key: &IntegerElGamalPK,
ciphertext: &<IntegerElGamalPK as EncryptionKey>::Ciphertext,
) -> bool {
ciphertext.c2
== Integer::from(
ciphertext
.c1
.secure_pow_mod_ref(&self.key, &public_key.modulus),
)
}
}

impl HomomorphicMultiplication for IntegerElGamalPK {
Expand Down Expand Up @@ -217,6 +230,18 @@ mod tests {
assert_eq!(19, sk.decrypt(&ciphertext));
}

#[test]
fn test_encrypt_decrypt_identity() {
let mut rng = GeneralRng::new(OsRng);

let el_gamal = IntegerElGamal::setup(&Default::default());
let (pk, sk) = el_gamal.generate_keys(&mut rng);

let ciphertext = pk.encrypt(&Integer::from(1), &mut rng);

assert!(sk.decrypt_identity(&ciphertext));
}

#[test]
fn test_homomorphic_mul() {
let mut rng = GeneralRng::new(OsRng);
Expand Down
21 changes: 21 additions & 0 deletions scicrypt-he/src/cryptosystems/paillier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,15 @@ impl DecryptionKey<PaillierPK> for PaillierSK {

inner.rem(&public_key.n)
}

fn decrypt_identity_raw(
&self,
public_key: &PaillierPK,
ciphertext: &<PaillierPK as EncryptionKey>::Ciphertext,
) -> bool {
// TODO: This can be optimized
self.decrypt_raw(public_key, ciphertext) == 0
}
}

impl HomomorphicAddition for PaillierPK {
Expand Down Expand Up @@ -220,6 +229,18 @@ mod tests {
assert_eq!(15, sk.decrypt(&ciphertext));
}

#[test]
fn test_encrypt_decrypt_identity() {
let mut rng = GeneralRng::new(OsRng);

let paillier = Paillier::setup(&BitsOfSecurity::ToyParameters);
let (pk, sk) = paillier.generate_keys(&mut rng);

let ciphertext = pk.encrypt(&Integer::from(0), &mut rng);

assert!(sk.decrypt_identity(&ciphertext));
}

#[test]
fn test_homomorphic_add() {
let mut rng = GeneralRng::new(OsRng);
Expand Down
21 changes: 21 additions & 0 deletions scicrypt-he/src/cryptosystems/rsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,15 @@ impl DecryptionKey<RsaPK> for RsaSK {
fn decrypt_raw(&self, public_key: &RsaPK, ciphertext: &RsaCiphertext) -> Integer {
Integer::from(ciphertext.c.secure_pow_mod_ref(&self.d, &public_key.n))
}

fn decrypt_identity_raw(
&self,
public_key: &RsaPK,
ciphertext: &<RsaPK as EncryptionKey>::Ciphertext,
) -> bool {
// TODO: This can be optimized
self.decrypt_raw(public_key, ciphertext) == 1
}
}

impl HomomorphicMultiplication for RsaPK {
Expand Down Expand Up @@ -150,6 +159,18 @@ mod tests {
assert_eq!(15, sk.decrypt(&ciphertext));
}

#[test]
fn test_encrypt_decrypt_identity() {
let mut rng = GeneralRng::new(OsRng);

let rsa = Rsa::setup(&BitsOfSecurity::ToyParameters);
let (pk, sk) = rsa.generate_keys(&mut rng);

let ciphertext = pk.encrypt(&Integer::from(1), &mut rng);

assert!(sk.decrypt_identity(&ciphertext));
}

#[test]
fn test_homomorphic_mul() {
let mut rng = GeneralRng::new(OsRng);
Expand Down
11 changes: 11 additions & 0 deletions scicrypt-traits/src/cryptosystems.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,19 @@ pub trait DecryptionKey<PK: EncryptionKey> {
self.decrypt_raw(ciphertext.public_key, &ciphertext.ciphertext)
}

/// Returns true if the associated ciphertext encrypts the identity. This is typically faster than a full decryption.
fn decrypt_identity<'pk>(
&self,
ciphertext: &AssociatedCiphertext<'pk, PK::Ciphertext, PK>,
) -> bool {
self.decrypt_identity_raw(ciphertext.public_key, &ciphertext.ciphertext)
}

/// Decrypt the ciphertext using the secret key and its related public key.
fn decrypt_raw(&self, public_key: &PK, ciphertext: &PK::Ciphertext) -> PK::Plaintext;

/// Returns true if the encrypted value equals the identity. This is typically faster than a full decryption.
fn decrypt_identity_raw(&self, public_key: &PK, ciphertext: &PK::Ciphertext) -> bool;
}

#[derive(PartialEq, Eq, Debug)]
Expand Down

0 comments on commit d205b21

Please sign in to comment.