Skip to content

Commit

Permalink
Merge pull request #562 from Chia-Network/bls-pybinding
Browse files Browse the repository at this point in the history
Restructure chia-bls modules and use pybindings modules
  • Loading branch information
Rigidity authored Jun 5, 2024
2 parents a521169 + 683c93e commit 8e58cd8
Show file tree
Hide file tree
Showing 17 changed files with 329 additions and 342 deletions.
3 changes: 1 addition & 2 deletions crates/chia-bls/benches/derive_key.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use chia_bls::derivable_key::DerivableKey;
use chia_bls::secret_key::SecretKey;
use chia_bls::{DerivableKey, SecretKey};
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use rand::rngs::StdRng;
use rand::{Rng, SeedableRng};
Expand Down
5 changes: 2 additions & 3 deletions crates/chia-bls/benches/parse.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use chia_bls::secret_key::SecretKey;
use chia_bls::signature::sign;
use chia_bls::PublicKey;
use chia_bls::sign;
use chia_bls::Signature;
use chia_bls::{PublicKey, SecretKey};
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use rand::rngs::StdRng;
use rand::{Rng, SeedableRng};
Expand Down
3 changes: 1 addition & 2 deletions crates/chia-bls/benches/sign.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use chia_bls::secret_key::SecretKey;
use chia_bls::signature::sign;
use chia_bls::{sign, SecretKey};
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use rand::rngs::StdRng;
use rand::{Rng, SeedableRng};
Expand Down
5 changes: 2 additions & 3 deletions crates/chia-bls/benches/verify.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use chia_bls::signature;
use chia_bls::{
aggregate_verify, aggregate_verify_gt, hash_to_g2, sign, GTElement, PublicKey, SecretKey,
Signature,
Expand Down Expand Up @@ -51,12 +50,12 @@ fn verify_benchmark(c: &mut Criterion) {

c.bench_function("verify, small msg", |b| {
b.iter(|| {
assert!(signature::verify(&sig_small, &pk, black_box(&msg_small)));
assert!(chia_bls::verify(&sig_small, &pk, black_box(&msg_small)));
});
});
c.bench_function("verify, 4kiB msg", |b| {
b.iter(|| {
assert!(signature::verify(&sig_large, &pk, black_box(&msg_large)));
assert!(chia_bls::verify(&sig_large, &pk, black_box(&msg_large)));
});
});
}
Expand Down
5 changes: 2 additions & 3 deletions crates/chia-bls/fuzz/fuzz_targets/blspy-fidelity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@
use libfuzzer_sys::fuzz_target;
use pyo3::prelude::*;

use chia_bls::derivable_key::DerivableKey;
use chia_bls::secret_key::SecretKey;
use chia_bls::signature::{aggregate, sign};
use chia_bls::{aggregate, sign};
use chia_bls::{DerivableKey, SecretKey};
use pyo3::types::{PyBytes, PyList, PyTuple};

fn to_bytes(obj: &Bound<'_, PyAny>) -> Vec<u8> {
Expand Down
6 changes: 2 additions & 4 deletions crates/chia-bls/fuzz/fuzz_targets/derive.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
#![no_main]
use libfuzzer_sys::fuzz_target;

use chia_bls::derivable_key::DerivableKey;
use chia_bls::public_key::PublicKey;
use chia_bls::secret_key::SecretKey;
use chia_bls::signature::{sign, verify};
use chia_bls::{sign, verify};
use chia_bls::{DerivableKey, PublicKey, SecretKey};

fuzz_target!(|data: &[u8]| {
if data.len() < 32 {
Expand Down
File renamed without changes.
4 changes: 0 additions & 4 deletions crates/chia-bls/src/derivable_key.rs

This file was deleted.

6 changes: 5 additions & 1 deletion crates/chia-bls/src/derive_keys.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
use crate::derivable_key::DerivableKey;
use crate::secret_key::SecretKey;

pub trait DerivableKey {
#[must_use]
fn derive_unhardened(&self, idx: u32) -> Self;
}

fn derive_path_unhardened<Key: DerivableKey>(key: &Key, path: &[u32]) -> Key {
let mut derived = key.derive_unhardened(path[0]);
for idx in &path[1..] {
Expand Down
13 changes: 8 additions & 5 deletions crates/chia-bls/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,14 @@ impl From<Error> for chia_traits::Error {
}

#[cfg(feature = "py-bindings")]
use pyo3::PyErr;
mod pybindings {
use super::*;

#[cfg(feature = "py-bindings")]
impl From<Error> for PyErr {
fn from(err: Error) -> PyErr {
pyo3::exceptions::PyValueError::new_err(format!("BLS Error {err:?}"))
use pyo3::{exceptions::PyValueError, PyErr};

impl From<Error> for PyErr {
fn from(err: Error) -> PyErr {
PyValueError::new_err(format!("BLS Error {err:?}"))
}
}
}
139 changes: 68 additions & 71 deletions crates/chia-bls/src/gtelement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,11 @@ use std::io::Cursor;
use std::mem::MaybeUninit;
use std::ops::{Mul, MulAssign};

#[cfg(feature = "py-bindings")]
use chia_py_streamable_macro::PyStreamable;
#[cfg(feature = "py-bindings")]
use chia_traits::from_json_dict::FromJsonDict;
#[cfg(feature = "py-bindings")]
use chia_traits::to_json_dict::ToJsonDict;
#[cfg(feature = "py-bindings")]
use pyo3::exceptions::PyValueError;
#[cfg(feature = "py-bindings")]
use pyo3::types::PyAnyMethods;
#[cfg(feature = "py-bindings")]
use pyo3::{pyclass, pymethods, IntoPy, PyAny, PyObject, PyResult, Python};

#[cfg_attr(feature = "py-bindings", pyclass, derive(PyStreamable))]
#[cfg_attr(
feature = "py-bindings",
pyo3::pyclass,
derive(chia_py_streamable_macro::PyStreamable)
)]
#[derive(Clone)]
pub struct GTElement(pub(crate) blst_fp12);

Expand Down Expand Up @@ -50,28 +41,6 @@ impl GTElement {
}
}
}
#[cfg(feature = "py-bindings")]
#[pymethods]
impl GTElement {
#[classattr]
#[pyo3(name = "SIZE")]
const PY_SIZE: usize = Self::SIZE;

fn __str__(&self) -> String {
hex::encode(self.to_bytes())
}

#[must_use]
pub fn __mul__(&self, rhs: &Self) -> Self {
let mut ret = self.clone();
ret *= rhs;
ret
}

pub fn __imul__(&mut self, rhs: &Self) {
*self *= rhs;
}
}

impl PartialEq for GTElement {
fn eq(&self, other: &Self) -> bool {
Expand Down Expand Up @@ -106,41 +75,6 @@ impl Mul<&GTElement> for &GTElement {
}
}

#[cfg(feature = "py-bindings")]
impl ToJsonDict for GTElement {
fn to_json_dict(&self, py: Python<'_>) -> PyResult<PyObject> {
let bytes = self.to_bytes();
Ok(hex::encode(bytes).into_py(py))
}
}

#[cfg(feature = "py-bindings")]
impl FromJsonDict for GTElement {
fn from_json_dict(o: &pyo3::Bound<'_, PyAny>) -> PyResult<Self> {
let s: String = o.extract()?;
if !s.starts_with("0x") {
return Err(PyValueError::new_err(
"bytes object is expected to start with 0x",
));
}
let s = &s[2..];
let buf = match hex::decode(s) {
Err(_) => {
return Err(PyValueError::new_err("invalid hex"));
}
Ok(v) => v,
};
if buf.len() != Self::SIZE {
return Err(PyValueError::new_err(format!(
"GTElement, invalid length {} expected {}",
buf.len(),
Self::SIZE
)));
}
Ok(Self::from_bytes(buf.as_slice().try_into().unwrap()))
}
}

impl fmt::Debug for GTElement {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_fmt(format_args!(
Expand All @@ -166,3 +100,66 @@ impl Streamable for GTElement {
))
}
}

#[cfg(feature = "py-bindings")]
mod pybindings {
use super::*;

use chia_traits::{FromJsonDict, ToJsonDict};
use pyo3::{exceptions::PyValueError, prelude::*};

#[pymethods]
impl GTElement {
#[classattr]
#[pyo3(name = "SIZE")]
const PY_SIZE: usize = Self::SIZE;

fn __str__(&self) -> String {
hex::encode(self.to_bytes())
}

#[must_use]
pub fn __mul__(&self, rhs: &Self) -> Self {
let mut ret = self.clone();
ret *= rhs;
ret
}

pub fn __imul__(&mut self, rhs: &Self) {
*self *= rhs;
}
}

impl ToJsonDict for GTElement {
fn to_json_dict(&self, py: Python<'_>) -> PyResult<PyObject> {
let bytes = self.to_bytes();
Ok(hex::encode(bytes).into_py(py))
}
}

impl FromJsonDict for GTElement {
fn from_json_dict(o: &Bound<'_, PyAny>) -> PyResult<Self> {
let s: String = o.extract()?;
if !s.starts_with("0x") {
return Err(PyValueError::new_err(
"bytes object is expected to start with 0x",
));
}
let s = &s[2..];
let buf = match hex::decode(s) {
Err(_) => {
return Err(PyValueError::new_err("invalid hex"));
}
Ok(v) => v,
};
if buf.len() != Self::SIZE {
return Err(PyValueError::new_err(format!(
"GTElement, invalid length {} expected {}",
buf.len(),
Self::SIZE
)));
}
Ok(Self::from_bytes(buf.as_slice().try_into().unwrap()))
}
}
}
25 changes: 14 additions & 11 deletions crates/chia-bls/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
#![allow(unsafe_code)]

pub mod cached_bls;
pub mod derivable_key;
pub mod derive_keys;
pub mod error;
pub mod gtelement;
pub mod mnemonic;
pub mod public_key;
pub mod secret_key;
pub mod signature;
mod bls_cache;
mod derive_keys;
mod error;
mod gtelement;
mod mnemonic;
mod public_key;
mod secret_key;
mod signature;

pub use cached_bls::BlsCache;
pub use derivable_key::DerivableKey;
#[cfg(feature = "py-bindings")]
mod parse_hex;

pub use bls_cache::BlsCache;
pub use derive_keys::*;
pub use error::{Error, Result};
pub use gtelement::GTElement;
pub use mnemonic::*;
pub use public_key::{hash_to_g1, hash_to_g1_with_dst, PublicKey};
pub use secret_key::SecretKey;
pub use signature::{
Expand Down
45 changes: 45 additions & 0 deletions crates/chia-bls/src/parse_hex.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use pyo3::{
exceptions::{PyTypeError, PyValueError},
prelude::*,
};

pub fn parse_hex_string(o: &Bound<'_, PyAny>, len: usize, name: &str) -> PyResult<Vec<u8>> {
if let Ok(s) = o.extract::<String>() {
let s = if let Some(st) = s.strip_prefix("0x") {
st
} else {
&s[..]
};
let buf = match hex::decode(s) {
Err(_) => {
return Err(PyValueError::new_err("invalid hex"));
}
Ok(v) => v,
};
if buf.len() == len {
Ok(buf)
} else {
Err(PyValueError::new_err(format!(
"{}, invalid length {} expected {}",
name,
buf.len(),
len
)))
}
} else if let Ok(buf) = o.extract::<Vec<u8>>() {
if buf.len() == len {
Ok(buf)
} else {
Err(PyValueError::new_err(format!(
"{}, invalid length {} expected {}",
name,
buf.len(),
len
)))
}
} else {
Err(PyTypeError::new_err(format!(
"invalid input type for {name}"
)))
}
}
Loading

0 comments on commit 8e58cd8

Please sign in to comment.