Skip to content

Commit

Permalink
Cleanup API
Browse files Browse the repository at this point in the history
  • Loading branch information
JobDoesburg committed Oct 31, 2024
1 parent 416cb2b commit 454af8f
Show file tree
Hide file tree
Showing 8 changed files with 389 additions and 173 deletions.
157 changes: 142 additions & 15 deletions src/distributed.rs
Original file line number Diff line number Diff line change
@@ -1,41 +1,132 @@
use std::fmt::Formatter;
use crate::arithmetic::*;
use crate::high_level::*;
use crate::utils::*;
use derive_more::{Deref, From};
use rand_core::{CryptoRng, RngCore};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde::de::{Error, Visitor};

#[derive(Copy, Clone, Eq, PartialEq, Debug, Deref, From)]
pub struct BlindingFactor(pub ScalarNonZero);
#[derive(Copy, Clone, Eq, PartialEq, Debug, Deref, From)]
pub struct BlindedGlobalSecretKey(pub ScalarNonZero);
#[derive(Copy, Clone, Eq, PartialEq, Debug, Deref, From)]
pub struct SessionKeyShare(pub ScalarNonZero);
/// GLOBAL KEY BLINDING
#[derive(Copy, Clone, Debug, From)]
pub struct BlindingFactor(ScalarNonZero);
impl BlindingFactor {
pub fn random<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
let scalar = ScalarNonZero::random(rng);
assert_ne!(scalar, ScalarNonZero::one());
BlindingFactor(scalar)
}
pub fn from(x: ScalarNonZero) -> Self {
BlindingFactor(x)
}
pub fn random<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
BlindingFactor(ScalarNonZero::random(rng))
pub fn encode(&self) -> [u8; 32] {
self.0.encode()
}
pub fn decode(bytes: &[u8; 32]) -> Option<Self> {
ScalarNonZero::decode(bytes).map(BlindingFactor)
}
pub fn from_hex(s: &str) -> Option<Self> {
hex::decode(s).ok().and_then(|bytes| {
if bytes.len() == 32 {
Some(BlindingFactor::decode(<&[u8; 32]>::try_from(bytes.as_slice()).unwrap()).unwrap())
} else {
None
}
})
}
pub fn to_hex(&self) -> String {
hex::encode(self.encode())
}
}

#[derive(Copy, Clone, Eq, PartialEq, Debug, Deref, From)]
pub struct BlindedGlobalSecretKey(ScalarNonZero);
impl Serialize for BlindedGlobalSecretKey {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&self.encode_to_hex().as_str())
}
}
impl<'de> Deserialize<'de> for BlindedGlobalSecretKey {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct BlindedGlobalSecretKeyVisitor;
impl<'de> Visitor<'de> for BlindedGlobalSecretKeyVisitor {
type Value = BlindedGlobalSecretKey;
fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
formatter.write_str("a hex encoded string representing a BlindedGlobalSecretKey")
}

fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: Error,
{
ScalarNonZero::decode_from_hex(&v).map(BlindedGlobalSecretKey)
.ok_or(E::custom(format!("invalid hex encoded string: {}", v)))
}
}

deserializer.deserialize_str(BlindedGlobalSecretKeyVisitor)
}
}

pub fn make_blinded_global_secret_key(
global_secret_key: &GlobalSecretKey,
blinding_factors: &Vec<BlindingFactor>,
) -> Option<BlindedGlobalSecretKey> {
let y = global_secret_key.clone();
let k = blinding_factors.iter().fold(ScalarNonZero::one(), |acc, x| acc * x.deref().invert());
let k = blinding_factors.iter().fold(ScalarNonZero::one(), |acc, x| acc * x.0.invert());
if k == ScalarNonZero::one() {
return None;
}
Some(BlindedGlobalSecretKey(*y * k))
Some(BlindedGlobalSecretKey(y.0 * k))
}

#[derive(Copy, Clone, Eq, PartialEq, Debug, Deref, From)]
pub struct SessionKeyShare(ScalarNonZero);
impl Serialize for SessionKeyShare {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&self.encode_to_hex().as_str())
}
}
impl<'de> Deserialize<'de> for SessionKeyShare {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct SessionKeyShareVisitor;
impl<'de> Visitor<'de> for SessionKeyShareVisitor {
type Value = SessionKeyShare;
fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
formatter.write_str("a hex encoded string representing a SessionKeyShare")
}

fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: Error,
{
ScalarNonZero::decode_from_hex(&v).map(SessionKeyShare)
.ok_or(E::custom(format!("invalid hex encoded string: {}", v)))
}
}

deserializer.deserialize_str(SessionKeyShareVisitor)
}
}

pub fn make_session_key_share(key_factor: &ScalarNonZero, blinding_factor: &ScalarNonZero) -> SessionKeyShare {
SessionKeyShare(key_factor * blinding_factor)
pub fn make_session_key_share(key_factor: &ScalarNonZero, blinding_factor: &BlindingFactor) -> SessionKeyShare {
SessionKeyShare(key_factor * blinding_factor.0)
}

pub type PEPSystemID = String;

/// PEP SYSTEM
#[derive(Clone)]
pub struct PEPSystem {
pub(crate) pseudonymisation_secret: PseudonymizationSecret,
Expand Down Expand Up @@ -107,6 +198,24 @@ impl PEPSystem {
) -> EncryptedDataPoint {
rerandomize_encrypted(&encrypted, rng)
}
#[cfg(feature = "elgamal2")]
pub fn rerandomize_encrypted_pseudonym<R: RngCore + CryptoRng>(
&self,
encrypted: EncryptedPseudonym,
public_key: &GroupElement,
rng: &mut R,
) -> EncryptedPseudonym {
rerandomize_encrypted_pseudonym(&encrypted, public_key, rng)
}
#[cfg(feature = "elgamal2")]
pub fn rerandomize_encrypted_data_point<R: RngCore + CryptoRng>(
&self,
encrypted: EncryptedDataPoint,
public_key: &GroupElement,
rng: &mut R,
) -> EncryptedDataPoint {
rerandomize_encrypted(&encrypted, public_key, rng)
}
}

#[derive(Clone)]
Expand All @@ -119,12 +228,12 @@ impl PEPClient {
blinded_global_private_key: BlindedGlobalSecretKey,
session_key_shares: Vec<SessionKeyShare>,
) -> Self {
let secret_key = SessionSecretKey(
let secret_key = SessionSecretKey::from(
session_key_shares
.iter()
.fold(*blinded_global_private_key, |acc, x| acc * x.deref()),
);
let public_key = SessionPublicKey(secret_key.deref() * &G);
let public_key = SessionPublicKey::from(secret_key.0 * &G);
Self {
session_secret_key: secret_key,
session_public_key: public_key,
Expand Down Expand Up @@ -166,4 +275,22 @@ impl PEPClient {
) -> EncryptedDataPoint {
rerandomize_encrypted(&encrypted, rng)
}
#[cfg(feature = "elgamal2")]
pub fn rerandomize_encrypted_pseudonym<R: RngCore + CryptoRng>(
&self,
encrypted: EncryptedPseudonym,
public_key: &GroupElement,
rng: &mut R,
) -> EncryptedPseudonym {
rerandomize_encrypted_pseudonym(&encrypted, public_key, rng)
}
#[cfg(feature = "elgamal2")]
pub fn rerandomize_encrypted_data_point<R: RngCore + CryptoRng>(
&self,
encrypted: EncryptedDataPoint,
public_key: &GroupElement,
rng: &mut R,
) -> EncryptedDataPoint {
rerandomize_encrypted(&encrypted, public_key, rng)
}
}
2 changes: 1 addition & 1 deletion src/elgamal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ pub fn encrypt<R: RngCore + CryptoRng>(
rng: &mut R,
) -> ElGamal {
let r = ScalarNonZero::random(rng); // random() should never return a zero scalar
debug_assert!(public_key != &GroupElement::identity()); // we should not encrypt anything with an empty public key, as this will result in plain text send over the line
debug_assert!(public_key != &GroupElement::identity()); // we should not encrypt anything with an empty public key, as this will result in plain text sent over the line
ElGamal {
b: r * G,
c: msg + r * public_key,
Expand Down
Loading

0 comments on commit 454af8f

Please sign in to comment.