From 90c73180f00f8a1122594881ea67f5a75a9fb0b1 Mon Sep 17 00:00:00 2001 From: Piotr Roslaniec Date: Mon, 3 Jul 2023 15:46:30 +0200 Subject: [PATCH] feat: expose ferveo variant in bindings --- ferveo-python/ferveo/__init__.py | 2 ++ ferveo-python/ferveo/__init__.pyi | 12 +++++++++ ferveo-python/test/test_serialization.py | 8 +++++- ferveo/src/api.rs | 34 +++++++++++++++++++++++- ferveo/src/bindings_python.rs | 22 +++++++++++++++ ferveo/src/bindings_wasm.rs | 16 +++++++++++ ferveo/src/lib.rs | 3 +++ 7 files changed, 95 insertions(+), 2 deletions(-) diff --git a/ferveo-python/ferveo/__init__.py b/ferveo-python/ferveo/__init__.py index fbaab504..869f3a18 100644 --- a/ferveo-python/ferveo/__init__.py +++ b/ferveo-python/ferveo/__init__.py @@ -15,6 +15,7 @@ DkgPublicKey, SharedSecret, ValidatorMessage, + FerveoVariant, ThresholdEncryptionError, InvalidShareNumberParameter, InvalidDkgStateToDeal, @@ -32,4 +33,5 @@ ValidatorsNotSorted, ValidatorPublicKeyMismatch, SerializationError, + InvalidVariant, ) diff --git a/ferveo-python/ferveo/__init__.pyi b/ferveo-python/ferveo/__init__.pyi index 170e98b0..dd2acbf2 100644 --- a/ferveo-python/ferveo/__init__.pyi +++ b/ferveo-python/ferveo/__init__.pyi @@ -170,6 +170,14 @@ class SharedSecret: ... +class FerveoVariant: + @staticmethod + def simple() -> str: ... + + @staticmethod + def precomputed() -> str: ... + + def encrypt(message: bytes, add: bytes, dkg_public_key: DkgPublicKey) -> Ciphertext: ... @@ -260,3 +268,7 @@ class ValidatorPublicKeyMismatch(Exception): class SerializationError(Exception): pass + + +class InvalidVariant(Exception): + pass diff --git a/ferveo-python/test/test_serialization.py b/ferveo-python/test/test_serialization.py index e5de35f0..0c56f4ff 100644 --- a/ferveo-python/test/test_serialization.py +++ b/ferveo-python/test/test_serialization.py @@ -4,6 +4,7 @@ Dkg, DkgPublicKey, FerveoPublicKey, + FerveoVariant, ) @@ -64,7 +65,12 @@ def test_dkg_public_key_serialization(): assert len(serialized) == DkgPublicKey.serialized_size() -def test_dkg_public_key_serialization(): +def test_public_key_serialization(): pk = make_pk() serialized = bytes(pk) assert len(serialized) == FerveoPublicKey.serialized_size() + + +def test_ferveo_variant_serialization(): + assert FerveoVariant.precomputed() == "FerveoVariant::Precomputed" + assert FerveoVariant.simple() == "FerveoVariant::Simple" diff --git a/ferveo/src/api.rs b/ferveo/src/api.rs index 99c5af02..b10e48c4 100644 --- a/ferveo/src/api.rs +++ b/ferveo/src/api.rs @@ -1,4 +1,4 @@ -use std::io; +use std::{fmt, io}; use ark_poly::{EvaluationDomain, Radix2EvaluationDomain}; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; @@ -69,6 +69,38 @@ pub fn decrypt_with_shared_secret( .map_err(Error::from) } +/// The ferveo variant to use for the decryption share derivation. +#[derive(PartialEq, Eq, Debug, Serialize, Deserialize, Copy, Clone)] +pub enum FerveoVariant { + /// The simple variant requires m of n shares to decrypt + Simple, + /// The precomputed variant requires n of n shares to decrypt + Precomputed, +} + +impl fmt::Display for FerveoVariant { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.as_str()) + } +} + +impl FerveoVariant { + pub fn as_str(&self) -> &'static str { + match self { + FerveoVariant::Simple => "FerveoVariant::Simple", + FerveoVariant::Precomputed => "FerveoVariant::Precomputed", + } + } + + pub fn from_string(s: &str) -> Result { + match s { + "FerveoVariant::Simple" => Ok(FerveoVariant::Simple), + "FerveoVariant::Precomputed" => Ok(FerveoVariant::Precomputed), + _ => Err(Error::InvalidVariant(s.to_string())), + } + } +} + #[serde_as] #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] pub struct DkgPublicKey( diff --git a/ferveo/src/bindings_python.rs b/ferveo/src/bindings_python.rs index 05756164..a81cd8f5 100644 --- a/ferveo/src/bindings_python.rs +++ b/ferveo/src/bindings_python.rs @@ -94,6 +94,9 @@ impl From for PyErr { expected, actual )) } + Error::InvalidVariant(variant) => { + InvalidVariant::new_err(variant.to_string()) + } }, _ => default(), } @@ -128,6 +131,7 @@ create_exception!(exceptions, ValidatorsNotSorted, PyValueError); create_exception!(exceptions, ValidatorPublicKeyMismatch, PyValueError); create_exception!(exceptions, SerializationError, PyValueError); create_exception!(exceptions, InvalidByteLength, PyValueError); +create_exception!(exceptions, InvalidVariant, PyValueError); fn from_py_bytes(bytes: &[u8]) -> PyResult { T::from_bytes(bytes) @@ -278,6 +282,22 @@ pub fn decrypt_with_shared_secret( .map_err(|err| FerveoPythonError::FerveoError(err).into()) } +#[pyclass(module = "ferveo")] +struct FerveoVariant {} + +#[pymethods] +impl FerveoVariant { + #[staticmethod] + fn precomputed() -> &'static str { + api::FerveoVariant::Precomputed.as_str() + } + + #[staticmethod] + fn simple() -> &'static str { + api::FerveoVariant::Simple.as_str() + } +} + #[pyclass(module = "ferveo")] #[derive(derive_more::AsRef)] pub struct SharedSecret(api::SharedSecret); @@ -600,6 +620,7 @@ pub fn make_ferveo_py_module(py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_class::()?; m.add_class::()?; m.add_class::()?; + m.add_class::()?; // Exceptions m.add( @@ -655,6 +676,7 @@ pub fn make_ferveo_py_module(py: Python<'_>, m: &PyModule) -> PyResult<()> { py.get_type::(), )?; m.add("SerializationError", py.get_type::())?; + m.add("InvalidVariant", py.get_type::())?; Ok(()) } diff --git a/ferveo/src/bindings_wasm.rs b/ferveo/src/bindings_wasm.rs index 8e071564..ab610160 100644 --- a/ferveo/src/bindings_wasm.rs +++ b/ferveo/src/bindings_wasm.rs @@ -161,6 +161,22 @@ macro_rules! generate_common_methods { }; } +#[wasm_bindgen] +pub struct FerveoVariant {} + +#[wasm_bindgen] +impl FerveoVariant { + #[wasm_bindgen(js_name = "precomputed", getter)] + pub fn precomputed() -> String { + api::FerveoVariant::Precomputed.as_str().to_string() + } + + #[wasm_bindgen(js_name = "simple", getter)] + pub fn simple() -> String { + api::FerveoVariant::Simple.as_str().to_string() + } +} + #[derive(TryFromJsValue)] #[wasm_bindgen] #[derive(Clone, Debug, derive_more::AsRef, derive_more::From)] diff --git a/ferveo/src/lib.rs b/ferveo/src/lib.rs index 7e1b3657..036e2fca 100644 --- a/ferveo/src/lib.rs +++ b/ferveo/src/lib.rs @@ -101,6 +101,9 @@ pub enum Error { #[error("Invalid byte length. Expected {0}, got {1}")] InvalidByteLength(usize, usize), + + #[error("Invalid variant: {0}")] + InvalidVariant(String), } pub type Result = std::result::Result;