Skip to content

Commit

Permalink
Merge branch 'long_lived/initial_datalayer' into merkle_blob
Browse files Browse the repository at this point in the history
  • Loading branch information
altendky committed Dec 18, 2024
2 parents 05196e4 + 070826c commit f227fb0
Show file tree
Hide file tree
Showing 19 changed files with 748 additions and 3 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build-crate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
run: cargo fmt --all -- --files-with-diff --check

- name: Clippy
run: cargo clippy --workspace --all-features --all-targets
run: cargo clippy --workspace --all-features --all-targets -- -D warnings

- name: Install cargo-machete
run: cargo install cargo-machete
Expand Down
16 changes: 16 additions & 0 deletions Cargo.lock

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

9 changes: 8 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ implicit_hasher = "allow"

[dependencies]
chia-bls = { workspace = true, optional = true }
chia-secp = { workspace = true, optional = true }
chia-client = { workspace = true, optional = true }
chia-consensus = { workspace = true, optional = true }
chia-datalayer = { workspace = true, optional = true }
Expand All @@ -72,6 +73,7 @@ ignored = ["clvmr"]
[features]
default = [
"bls",
"secp",
"client",
"consensus",
"datalayer",
Expand All @@ -84,7 +86,8 @@ default = [
"clvm-utils"
]

bls = ["dep:chia-bls"]
bls = ["dep:chia-bls", "clvm-traits/chia-bls"]
secp = ["dep:chia-secp", "clvm-traits/chia-secp"]
client = ["dep:chia-client"]
consensus = ["dep:chia-consensus"]
datalayer = ["dep:chia-datalayer"]
Expand All @@ -109,6 +112,7 @@ chia-client = { path = "./crates/chia-client", version = "0.16.0" }
chia-consensus = { path = "./crates/chia-consensus", version = "0.16.0" }
chia-datalayer = { path = "./crates/chia-datalayer", version = "0.16.0" }
chia-protocol = { path = "./crates/chia-protocol", version = "0.16.0" }
chia-secp = { path = "./crates/chia-secp", version = "0.16.0" }
chia-ssl = { path = "./crates/chia-ssl", version = "0.11.0" }
chia-traits = { path = "./crates/chia-traits", version = "0.15.0" }
chia-puzzles = { path = "./crates/chia-puzzles", version = "0.16.0" }
Expand Down Expand Up @@ -159,6 +163,9 @@ blocking-threadpool = "1.0.1"
libfuzzer-sys = "0.4"
wasm-bindgen = "0.2.95"
openssl = "0.10.68"
k256 = "0.13.4"
p256 = "0.13.2"
rand_chacha = "0.3.1"
open = "5.3.0"
url = "2.5.2"
percent-encoding = "2.3.1"
9 changes: 9 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Security Policy

## Reporting a Vulnerability

Please report security concerns to https://hackerone.com/chia_network.

If your security issue is established to be valid, we will reach out immediately to establish
communication channels and compensate the issue reporter for responsibly reporting security bugs via
our bug bounty program.
2 changes: 1 addition & 1 deletion crates/chia-consensus/src/spendbundle_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ ff01\
#[case] sk_hex: &str,
) {
let sk = SecretKey::from_bytes(&<[u8; 32]>::from_hex(sk_hex).unwrap()).unwrap();
let sol_bytes: Vec<u8> = hex::decode(solution).unwrap().to_vec();
let sol_bytes = hex::decode(solution).unwrap();
let full_puz = Bytes32::new(tree_hash_atom(&[1_u8]).to_bytes());
let test_coin = Coin::new(
hex!("4444444444444444444444444444444444444444444444444444444444444444").into(),
Expand Down
27 changes: 27 additions & 0 deletions crates/chia-secp/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[package]
name = "chia-secp"
version = "0.16.0"
edition = "2021"
license = "Apache-2.0"
description = "Secp256k1 and secp256r1 types for Chia"
authors = ["Brandon Haggstrom <[email protected]>"]
homepage = "https://github.com/Chia-Network/chia_rs"
repository = "https://github.com/Chia-Network/chia_rs"

[lints]
workspace = true

[features]
arbitrary = ["dep:arbitrary"]

[dependencies]
arbitrary = { workspace = true, optional = true }
k256 = { workspace = true }
p256 = { workspace = true }
hex = { workspace = true }
chia-sha2= { workspace = true }

[dev-dependencies]
rand = { workspace = true }
rand_chacha = { workspace = true }
anyhow = { workspace = true }
103 changes: 103 additions & 0 deletions crates/chia-secp/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
mod secp256k1;
mod secp256r1;

pub use secp256k1::*;
pub use secp256r1::*;

#[cfg(test)]
mod tests {
use rand::{Rng, SeedableRng};
use rand_chacha::ChaCha8Rng;

use super::*;

#[test]
fn test_secp256k1_key() -> anyhow::Result<()> {
let mut rng = ChaCha8Rng::seed_from_u64(1337);

let sk = K1SecretKey::from_bytes(&rng.gen())?;
assert_eq!(
hex::encode(sk.to_bytes()),
"ae491886341a539a1ccfaffcc9c78650ad1adc6270620c882b8d29bf6b9bc4cd"
);
assert_eq!(format!("{sk:?}"), "K1SecretKey(...)");

let pk = sk.public_key();
assert_eq!(
hex::encode(pk.to_bytes()),
"02827cdbbed87e45683d448be2ea15fb72ba3732247bda18474868cf5456123fb4"
);
assert_eq!(
format!("{pk:?}"),
"K1PublicKey(02827cdbbed87e45683d448be2ea15fb72ba3732247bda18474868cf5456123fb4)"
);
assert_eq!(
format!("{pk}"),
"02827cdbbed87e45683d448be2ea15fb72ba3732247bda18474868cf5456123fb4"
);

let message_hash: [u8; 32] = rng.gen();
let sig = sk.sign_prehashed(&message_hash)?;
assert_eq!(
hex::encode(sig.to_bytes()),
"6f07897d1d28b8698af5dec5ca06907b1304b227dc9f740b8c4065cf04d5e8653ae66aa17063e7120ee7f22fae54373b35230e259244b90400b65cf00d86c591"
);
assert_eq!(
format!("{sig:?}"),
"K1Signature(6f07897d1d28b8698af5dec5ca06907b1304b227dc9f740b8c4065cf04d5e8653ae66aa17063e7120ee7f22fae54373b35230e259244b90400b65cf00d86c591)"
);
assert_eq!(
format!("{sig}"),
"6f07897d1d28b8698af5dec5ca06907b1304b227dc9f740b8c4065cf04d5e8653ae66aa17063e7120ee7f22fae54373b35230e259244b90400b65cf00d86c591"
);

assert!(pk.verify_prehashed(&message_hash, &sig));

Ok(())
}

#[test]
fn test_secp256r1_key() -> anyhow::Result<()> {
let mut rng = ChaCha8Rng::seed_from_u64(1337);

let sk = R1SecretKey::from_bytes(&rng.gen())?;
assert_eq!(
hex::encode(sk.to_bytes()),
"ae491886341a539a1ccfaffcc9c78650ad1adc6270620c882b8d29bf6b9bc4cd"
);
assert_eq!(format!("{sk:?}"), "R1SecretKey(...)");

let pk = sk.public_key();
assert_eq!(
hex::encode(pk.to_bytes()),
"037dc85102f5eb7867b9580fea8b242c774173e1a47db320c798242d3a7a7579e4"
);
assert_eq!(
format!("{pk:?}"),
"R1PublicKey(037dc85102f5eb7867b9580fea8b242c774173e1a47db320c798242d3a7a7579e4)"
);
assert_eq!(
format!("{pk}"),
"037dc85102f5eb7867b9580fea8b242c774173e1a47db320c798242d3a7a7579e4"
);

let message_hash: [u8; 32] = rng.gen();
let sig = sk.sign_prehashed(&message_hash)?;
assert_eq!(
hex::encode(sig.to_bytes()),
"550e83da8cf9b2d407ed093ae213869ebd7ceaea603920f87d535690e52b40537915d8fe3d5a96c87e700c56dc638c32f7a2954f2ba409367d1a132000cc2228"
);
assert_eq!(
format!("{sig:?}"),
"R1Signature(550e83da8cf9b2d407ed093ae213869ebd7ceaea603920f87d535690e52b40537915d8fe3d5a96c87e700c56dc638c32f7a2954f2ba409367d1a132000cc2228)"
);
assert_eq!(
format!("{sig}"),
"550e83da8cf9b2d407ed093ae213869ebd7ceaea603920f87d535690e52b40537915d8fe3d5a96c87e700c56dc638c32f7a2954f2ba409367d1a132000cc2228"
);

assert!(pk.verify_prehashed(&message_hash, &sig));

Ok(())
}
}
7 changes: 7 additions & 0 deletions crates/chia-secp/src/secp256k1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
mod public_key;
mod secret_key;
mod signature;

pub use public_key::*;
pub use secret_key::*;
pub use signature::*;
59 changes: 59 additions & 0 deletions crates/chia-secp/src/secp256k1/public_key.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use std::fmt;
use std::hash::{Hash, Hasher};

use chia_sha2::Sha256;
use k256::ecdsa::signature::hazmat::PrehashVerifier;
use k256::ecdsa::{Error, VerifyingKey};

use super::K1Signature;

#[derive(Clone, Copy, PartialEq, Eq)]
pub struct K1PublicKey(pub(crate) VerifyingKey);

impl Hash for K1PublicKey {
fn hash<H: Hasher>(&self, state: &mut H) {
self.to_bytes().hash(state);
}
}

impl fmt::Debug for K1PublicKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "K1PublicKey({self})")
}
}

impl fmt::Display for K1PublicKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", hex::encode(self.to_bytes()))
}
}

#[cfg(feature = "arbitrary")]
impl<'a> arbitrary::Arbitrary<'a> for K1PublicKey {
fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
Self::from_bytes(&u.arbitrary()?).map_err(|_| arbitrary::Error::IncorrectFormat)
}
}

impl K1PublicKey {
pub const SIZE: usize = 33;

pub fn to_bytes(&self) -> [u8; Self::SIZE] {
self.0.to_encoded_point(true).as_ref().try_into().unwrap()
}

pub fn from_bytes(bytes: &[u8; Self::SIZE]) -> Result<Self, Error> {
Ok(Self(VerifyingKey::from_sec1_bytes(bytes)?))
}

pub fn verify_prehashed(&self, message_hash: &[u8; 32], signature: &K1Signature) -> bool {
self.0.verify_prehash(message_hash, &signature.0).is_ok()
}

pub fn fingerprint(&self) -> u32 {
let mut hasher = Sha256::new();
hasher.update(self.to_bytes());
let hash = hasher.finalize();
u32::from_be_bytes(hash[0..4].try_into().unwrap())
}
}
50 changes: 50 additions & 0 deletions crates/chia-secp/src/secp256k1/secret_key.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use std::{
fmt,
hash::{Hash, Hasher},
};

use k256::ecdsa::{Error, SigningKey};

use super::{K1PublicKey, K1Signature};

#[derive(Clone, PartialEq, Eq)]
pub struct K1SecretKey(SigningKey);

impl Hash for K1SecretKey {
fn hash<H: Hasher>(&self, state: &mut H) {
self.to_bytes().hash(state);
}
}

impl fmt::Debug for K1SecretKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "K1SecretKey(...)")
}
}

#[cfg(feature = "arbitrary")]
impl<'a> arbitrary::Arbitrary<'a> for K1SecretKey {
fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
Self::from_bytes(&u.arbitrary()?).map_err(|_| arbitrary::Error::IncorrectFormat)
}
}

impl K1SecretKey {
pub fn to_bytes(&self) -> [u8; 32] {
self.0.to_bytes().into()
}

pub fn from_bytes(bytes: &[u8; 32]) -> Result<Self, Error> {
Ok(Self(SigningKey::from_bytes(bytes.into())?))
}

pub fn public_key(&self) -> K1PublicKey {
K1PublicKey(*self.0.verifying_key())
}

pub fn sign_prehashed(&self, message_hash: &[u8; 32]) -> Result<K1Signature, Error> {
Ok(K1Signature(
self.0.sign_prehash_recoverable(message_hash)?.0,
))
}
}
Loading

0 comments on commit f227fb0

Please sign in to comment.