Skip to content

Commit

Permalink
Merge pull request #107 from fjarri/evidence
Browse files Browse the repository at this point in the history
Support creating reencryption evidence
  • Loading branch information
fjarri authored Feb 16, 2023
2 parents 08f4ec9 + 17fedad commit 89aa0b6
Show file tree
Hide file tree
Showing 18 changed files with 837 additions and 53 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/umbral-pre.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
strategy:
matrix:
rust:
- 1.57.0 # MSRV
- 1.58.0 # MSRV
- stable
target:
- wasm32-unknown-unknown
Expand All @@ -47,7 +47,7 @@ jobs:
strategy:
matrix:
rust:
- 1.57.0 # MSRV
- 1.58.0 # MSRV
- stable
target:
- thumbv7em-none-eabi
Expand All @@ -67,7 +67,7 @@ jobs:
strategy:
matrix:
rust:
- 1.57.0 # MSRV
- 1.58.0 # MSRV
- stable
steps:
- uses: actions/checkout@v2
Expand All @@ -83,7 +83,7 @@ jobs:
matrix:
include:
- target: x86_64-unknown-linux-gnu
rust: 1.57.0 # MSRV
rust: 1.58.0 # MSRV
- target: x86_64-unknown-linux-gnu
rust: stable

Expand Down
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,18 @@ Under construction.

## [0.8.1] - 2023-01-17

### Changed

- Bumped MSRV to 1.58. (#[107])


### Added

- Added `Signature::to_be_bytes()`, `Capsule::to_bytes_simple()`, and `CapsuleFrag::to_bytes_simple()` to use in Ethereum contracts. ([#115])
- Added `ReencryptionEvidence` structure that can be used in e.g. Ethereum contracts to verify the reencryption validity (see its docstring for the list of checks). (#[107])
- Made `Parameters` and `CurvePoint` public (necessary for the evidence to work). Made `Parameters::u` public, and added a public `CurvePoint::coordinates()` method. (#[107])
- Made `hash_to_cfrag_verification()` public. (#[107])
- Added `VerifiedCapsuleFrag::to_bytes_simple()`. (#[107])


### Fixed
Expand All @@ -23,6 +32,7 @@ Under construction.


[#115]: https://github.com/nucypher/rust-umbral/pull/115
[#107]: https://github.com/nucypher/rust-umbral/pull/107


## [0.8.0] - 2023-01-15
Expand Down
3 changes: 3 additions & 0 deletions umbral-pre-python/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ fn _umbral(py: Python, m: &PyModule) -> PyResult<()> {
m.add_class::<VerifiedKeyFrag>()?;
m.add_class::<CapsuleFrag>()?;
m.add_class::<VerifiedCapsuleFrag>()?;
m.add_class::<Parameters>()?;
m.add_class::<ReencryptionEvidence>()?;
m.add_class::<CurvePoint>()?;
m.add("VerificationError", py.get_type::<VerificationError>())?;
register_encrypt(m)?;
register_decrypt_original(m)?;
Expand Down
3 changes: 3 additions & 0 deletions umbral-pre-python/umbral_pre/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
CapsuleFrag,
VerifiedCapsuleFrag,
VerificationError,
ReencryptionEvidence,
CurvePoint,
Parameters,
encrypt,
decrypt_original,
decrypt_reencrypted,
Expand Down
57 changes: 57 additions & 0 deletions umbral-pre-python/umbral_pre/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,9 @@ class VerifiedCapsuleFrag:
def unverify(self) -> CapsuleFrag:
...

def to_bytes_simple(self) -> bytes:
...


def reencrypt(capsule: Capsule, kfrag: VerifiedKeyFrag) -> VerifiedCapsuleFrag:
...
Expand All @@ -193,3 +196,57 @@ def decrypt_reencrypted(
ciphertext: bytes,
) -> Optional[bytes]:
...


class CurvePoint:

def coordinates(self) -> Tuple[bytes, bytes]:
...


class Parameters:

def __init__(self) -> None:
...

u: CurvePoint


class ReencryptionEvidence:

def __init__(
self,
capsule: Capsule,
vcfrag: VerifiedCapsuleFrag,
verifying_pk: PublicKey,
delegating_pk: PublicKey,
receiving_pk: PublicKey,
):
...

def __bytes__(self) -> bytes:
...

@staticmethod
def from_bytes(data: bytes) -> ReencryptionEvidence:
...

e: CurvePoint
ez: CurvePoint
e1: CurvePoint
e1h: CurvePoint
e2: CurvePoint

v: CurvePoint
vz: CurvePoint
v1: CurvePoint
v1h: CurvePoint
v2: CurvePoint

uz: CurvePoint
u1: CurvePoint
u1h: CurvePoint
u2: CurvePoint

kfrag_validity_message_hash: bytes
kfrag_signature_v: bool
165 changes: 162 additions & 3 deletions umbral-pre/src/bindings_python.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use crate as umbral_pre;
use crate::{curve::ScalarSize, DefaultDeserialize, DefaultSerialize, SecretBox};

fn map_py_value_err<T: fmt::Display>(err: T) -> PyErr {
PyValueError::new_err(format!("{}", err))
PyValueError::new_err(format!("{err}"))
}

fn to_bytes<T, U>(obj: &T) -> PyResult<PyObject>
Expand Down Expand Up @@ -347,7 +347,7 @@ impl KeyFrag {
delegating_pk.map(|pk| &pk.backend),
receiving_pk.map(|pk| &pk.backend),
)
.map_err(|(err, _kfrag)| VerificationError::new_err(format!("{}", err)))
.map_err(|(err, _kfrag)| VerificationError::new_err(format!("{err}")))
.map(VerifiedKeyFrag::from)
}

Expand Down Expand Up @@ -461,7 +461,7 @@ impl CapsuleFrag {
&delegating_pk.backend,
&receiving_pk.backend,
)
.map_err(|(err, _cfrag)| VerificationError::new_err(format!("{}", err)))
.map_err(|(err, _cfrag)| VerificationError::new_err(format!("{err}")))
.map(VerifiedCapsuleFrag::from)
}

Expand Down Expand Up @@ -527,6 +527,11 @@ impl VerifiedCapsuleFrag {
fn __bytes__(&self) -> PyResult<PyObject> {
to_bytes(self)
}

fn to_bytes_simple(&self) -> PyObject {
let serialized = self.backend.to_bytes_simple();
Python::with_gil(|py| PyBytes::new(py, &serialized).into())
}
}

#[pyfunction]
Expand Down Expand Up @@ -584,3 +589,157 @@ pub fn register_reencrypt(m: &PyModule) -> PyResult<()> {
pub fn register_decrypt_reencrypted(m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(decrypt_reencrypted, m)?)
}

#[pyclass(module = "umbral")]
#[derive(Clone, derive_more::AsRef, derive_more::From, derive_more::Into)]
pub struct Parameters {
backend: umbral_pre::Parameters,
}

impl Default for Parameters {
fn default() -> Self {
Self::new()
}
}

#[pymethods]
impl Parameters {
#[new]
pub fn new() -> Self {
umbral_pre::Parameters::new().into()
}

#[getter]
fn u(&self) -> CurvePoint {
self.backend.u.into()
}
}

#[pyclass(module = "umbral")]
#[derive(Clone, derive_more::AsRef, derive_more::From, derive_more::Into)]
pub struct CurvePoint {
backend: umbral_pre::CurvePoint,
}

#[pymethods]
impl CurvePoint {
#[getter]
fn coordinates(&self) -> Option<(PyObject, PyObject)> {
let coords = self.backend.coordinates();
Python::with_gil(|py| -> Option<(PyObject, PyObject)> {
coords.map(|(x, y)| {
(
PyBytes::new(py, x.as_ref()).into(),
PyBytes::new(py, y.as_ref()).into(),
)
})
})
}
}

#[pyclass(module = "umbral")]
#[derive(Clone, derive_more::AsRef, derive_more::From, derive_more::Into)]
pub struct ReencryptionEvidence {
backend: umbral_pre::ReencryptionEvidence,
}

#[pymethods]
impl ReencryptionEvidence {
#[new]
pub fn new(
capsule: &Capsule,
vcfrag: &VerifiedCapsuleFrag,
verifying_pk: &PublicKey,
delegating_pk: &PublicKey,
receiving_pk: &PublicKey,
) -> Self {
umbral_pre::ReencryptionEvidence::new(
&capsule.backend.clone(),
&vcfrag.backend.clone(),
&verifying_pk.backend.clone(),
&delegating_pk.backend.clone(),
&receiving_pk.backend.clone(),
)
.into()
}

#[staticmethod]
pub fn from_bytes(data: &[u8]) -> PyResult<Self> {
from_bytes::<_, umbral_pre::ReencryptionEvidence>(data)
}

fn __bytes__(&self) -> PyResult<PyObject> {
to_bytes(self)
}

#[getter]
fn e(&self) -> CurvePoint {
self.backend.e.into()
}
#[getter]
fn ez(&self) -> CurvePoint {
self.backend.ez.into()
}
#[getter]
fn e1(&self) -> CurvePoint {
self.backend.e1.into()
}
#[getter]
fn e1h(&self) -> CurvePoint {
self.backend.e1h.into()
}
#[getter]
fn e2(&self) -> CurvePoint {
self.backend.e2.into()
}

#[getter]
fn v(&self) -> CurvePoint {
self.backend.v.into()
}
#[getter]
fn vz(&self) -> CurvePoint {
self.backend.vz.into()
}
#[getter]
fn v1(&self) -> CurvePoint {
self.backend.v1.into()
}
#[getter]
fn v1h(&self) -> CurvePoint {
self.backend.v1h.into()
}
#[getter]
fn v2(&self) -> CurvePoint {
self.backend.v2.into()
}

#[getter]
fn uz(&self) -> CurvePoint {
self.backend.uz.into()
}
#[getter]
fn u1(&self) -> CurvePoint {
self.backend.u1.into()
}
#[getter]
fn u1h(&self) -> CurvePoint {
self.backend.u1h.into()
}
#[getter]
fn u2(&self) -> CurvePoint {
self.backend.u2.into()
}

#[getter]
fn kfrag_validity_message_hash(&self) -> PyObject {
Python::with_gil(|py| -> PyObject {
PyBytes::new(py, self.backend.kfrag_validity_message_hash.as_ref()).into()
})
}

#[getter]
fn kfrag_signature_v(&self) -> bool {
self.backend.kfrag_signature_v
}
}
Loading

0 comments on commit 89aa0b6

Please sign in to comment.