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;