Skip to content

Commit

Permalink
remove hacspec references from readme; fix lint
Browse files Browse the repository at this point in the history
  • Loading branch information
jvmncs committed Aug 8, 2022
1 parent 2e09d1d commit 96d3168
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 41 deletions.
32 changes: 16 additions & 16 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.PHONY: pydep
pydep:
pip install maturin~=0.13.0 pytest
pip install maturin~=0.13.0 pytest absl-py

.PHONY: pylib
pylib:
Expand Down
18 changes: 4 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,12 @@ py-hpke-spec
===============
The Hybrid Public Key Encryption (HPKE) standard in Python.

- [`hpke-spec`](https://github.com/cryspen/hpke-spec) = [HPKE](https://blog.cloudflare.com/hybrid-public-key-encryption/) :handshake: [`hacspec`](https://hacspec.github.io)
[`hpke-rs`](https://crates.io/crates/hpke-rs) :handshake: [`PyO3`](https://github.com/PyO3/pyo3)

- [`py-hpke-spec`](https://github.com/capeprivacy/py-hpke-spec) = [`hpke-spec`](https://github.com/cryspen/hpke-spec) :handshake: [`PyO3`](https://github.com/PyO3/pyo3)


This HPKE implementation is simply a thin Python wrapper around [`hpke-spec`](https://github.com/cryspen/hpke-spec), the hacspec implementation [written by Franziskus Kiefer](https://www.franziskuskiefer.de/p/tldr-hybrid-public-key-encryption/). This package mirrors the `hpke-spec` constructions as much as possible, to avoid any discrepancy from the HPKE standard.
This library provides Python bindings to the `hpke-rs` crate, which supports primitives from either [Rust Crypto](https://github.com/RustCrypto) or [EverCrypt](https://hacl-star.github.io/HaclValeEverCrypt.html).

## Features
The modes and features available match those found in the original `hpke-spec` code. For instance, SHA256 is the only hash algorithm implemented by the hacspec example crypto libs, and as a result some KEMs and KDFs from the original HPKE RFC are unsupported.
The modes and features available match those supported by `hpke-rs`.

- Modes
- [x] mode_base
Expand All @@ -33,16 +30,9 @@ The modes and features available match those found in the original `hpke-spec` c
- [x] HKDF-SHA384
- [x] HKDF-SHA512

## Why `hpke-spec`?

The `hpke-spec` library has two primary advantages:
- `hpke-spec` is written in [`hacspec`](https://hacspec.github.io/) which can be compiled into [F*](https://www.fstar-lang.org/) for formal verification.
- The cargo [documentation](https://tech.cryspen.com/hpke-spec/hpke/index.html) for `hpke-spec` is simply the text of the [HPKE RFC 9180](https://datatracker.ietf.org/doc/rfc9180/), with all the RFC's constructions linked directly to the hacspec code that implements it.

As a result, it's much more straightforward to evaluate `hpke-spec` for security and correctness. Indeed, both hacspec and RFC 9180 have received thorough vetting from cryptographers in [Project Everest](https://project-everest.github.io) and the [Internet Research Task Force](https://datatracker.ietf.org/doc/rfc9180/), respectively.

## Installation
Wheels for various platforms and architectures can be found on on [PyPI](https://pypi.org/project/hpke-spec/) or in the `wheelhouse.zip` archive from the [latest Github release](https://github.com/capeprivacy/py-hpke-spec/releases).
Wheels for various platforms and architectures can be found on [PyPI](https://pypi.org/project/hpke-spec/) or in the `wheelhouse.zip` archive from the [latest Github release](https://github.com/capeprivacy/py-hpke-spec/releases).

The library can also be installed from source with [`maturin`](https://github.com/PyO3/maturin) -- see below.

Expand Down
2 changes: 1 addition & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use pyo3::prelude::*;
#[pyclass]
#[pyo3(name = "Mode", module = "hpke")]
#[derive(Clone)]
#[allow(non_camel_case_types)]
#[allow(clippy::upper_case_acronyms, non_camel_case_types)]
pub(crate) enum PyMode {
BASE,
PSK,
Expand Down
1 change: 1 addition & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ create_exception!(
"A concurrency issue with an RwLock."
);

#[inline(always)]
pub(crate) fn handle_hpke_error(e: HpkeError) -> PyErr {
match e {
HpkeError::OpenError => OpenError::new_err("Error opening an HPKE ciphertext."),
Expand Down
18 changes: 9 additions & 9 deletions src/hpke.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,15 @@ impl PyHpke {
/// Generate a key-pair according to this Hpke config
fn generate_key_pair<'p>(&self, py: Python<'p>) -> PyResult<(&'p PyBytes, &'p PyBytes)> {
let cfg: Hpke = self.into();
let keypair = cfg
.generate_key_pair()
.map_err(|hpke_error| handle_hpke_error(hpke_error))?;
let keypair = cfg.generate_key_pair().map_err(handle_hpke_error)?;
let (sk, pk) = keypair.into_keys();
let sk_py = PyBytes::new(py, sk.as_slice());
let pk_py = PyBytes::new(py, pk.as_slice());
Ok((sk_py, pk_py))
}

/// Use this Hpke config for single-shot encryption
#[allow(clippy::too_many_arguments)]
#[args(psk = "None", psk_id = "None", sk_s = "None")]
fn seal<'p>(
&self,
Expand All @@ -74,8 +73,8 @@ impl PyHpke {
let info = info.as_bytes();
let aad = aad.as_bytes();
let plain_txt = plain_txt.as_bytes();
let psk = psk.and_then(|x| Some(x.as_bytes()));
let psk_id = psk_id.and_then(|x| Some(x.as_bytes()));
let psk = psk.map(|x| x.as_bytes());
let psk_id = psk_id.map(|x| x.as_bytes());

// perform single-shot seal
let (encap, cipher_txt) = match sk_s {
Expand All @@ -88,7 +87,7 @@ impl PyHpke {
cfg.seal(&pk_r, info, aad, plain_txt, psk, psk_id, Some(&sk))
}
}
.map_err(|hpke_error| handle_hpke_error(hpke_error))?;
.map_err(handle_hpke_error)?;

// convert return vals back to PyBytes
let encap_py = PyBytes::new(py, encap.as_slice());
Expand All @@ -97,6 +96,7 @@ impl PyHpke {
}

/// Use this Hpke config for single-shot decryption
#[allow(clippy::too_many_arguments)]
#[args(psk = "None", psk_id = "None", pk_s = "None")]
fn open<'p>(
&self,
Expand All @@ -118,8 +118,8 @@ impl PyHpke {
let info = info.as_bytes();
let aad = aad.as_bytes();
let cipher_txt = cipher_txt.as_bytes();
let psk = psk.and_then(|x| Some(x.as_bytes()));
let psk_id = psk_id.and_then(|x| Some(x.as_bytes()));
let psk = psk.map(|x| x.as_bytes());
let psk_id = psk_id.map(|x| x.as_bytes());

// perform single-shot open
let plain_txt = match pk_s {
Expand All @@ -130,7 +130,7 @@ impl PyHpke {
cfg.open(enc, &sk_r, info, aad, cipher_txt, psk, psk_id, Some(&pk))
}
}
.map_err(|hpke_error| handle_hpke_error(hpke_error))?;
.map_err(handle_hpke_error)?;

// convert return val back to PyBytes
let plain_txt_py = PyBytes::new(py, plain_txt.as_slice());
Expand Down

0 comments on commit 96d3168

Please sign in to comment.