Skip to content

Commit

Permalink
Pedersen hash (#12)
Browse files Browse the repository at this point in the history
  • Loading branch information
pefontana authored Nov 7, 2023
1 parent 01b222e commit 8476f50
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 4 deletions.
2 changes: 2 additions & 0 deletions crates/starknet-types-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ readme = "README.md"
bitvec = { version = "1.0.1", default-features = false }
serde = { version = "1.0.163", optional = true, default-features = false }
lambdaworks-math = { git = "https://github.com/lambdaclass/lambdaworks.git", rev = "f940e14ed17370d29fe129951448037d11b65ce8", default-features = false}
lambdaworks-crypto = { git = "https://github.com/lambdaclass/lambdaworks.git", rev = "f940e14ed17370d29fe129951448037d11b65ce8", default-features = false, optional = true}


arbitrary = { version = "1.3.0", optional = true, default-features = false }
Expand All @@ -22,6 +23,7 @@ num-traits = { version = "0.2.16", default-features = false }
[features]
default = ["std", "serde", "curve"]
curve = []
hash = ["dep:lambdaworks-crypto"]
std = []
alloc = ["serde?/alloc"]
arbitrary = ["std", "dep:arbitrary"]
Expand Down
28 changes: 24 additions & 4 deletions crates/starknet-types-core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,26 @@ Core types representation for Starknet.

The `starknet-types-core` crate provides:
* The universal `Felt` (Field Element) type for Cairo and STARK proofs. It was created to reduce the fragmentation in the Starknet Rust ecosystem by providing a standardized representation of the `Felt` type.
* The `AffinePoint` and `ProjectivePoint` structs, which represent points on the Stark curve for performing elliptic curve operations.

## Features

- Standardized `Felt` type: Simplify your codebase by using our standardized `Felt` type.
- Optimized for performance: The `Felt` type has been optimized for high-performance applications.
### Always on
- Standardized `Felt` type: Simplify your codebase by using our standardized `Felt` type. Optimized for performance: The `Felt` type has been optimized for high-performance applications.
- No_std support ✅

### Serde
- Provides a Serialization and Deserialization implementations for the `Felt` type
- No_std support ✅

### Arbitrary
- Provides an Arbitrary implementations for the `Felt` type

### Curve
- Add the `AffinePoint` and `ProjectivePoint` structs, which represent points on the Stark curve for performing elliptic curve operations.
- No_std support ✅

### Hash
- Implements Pedersen hashing for Felts and Felts array

## Examples

Expand All @@ -29,7 +43,13 @@ Include `starknet-types-core` in your library by adding the following to your `C

```toml
[dependencies]
starknet-types-core = { version = "0.0.3", git = "https://github.com/starknet-io/types-rs" }
starknet-types-core = { version = "0.0.3", git = "https://github.com/starknet-io/types-rs", default-features = false, features = [
"alloc",
"serde",
"arbitrary",
"curve",
"hash",
] }
```

## Build from source
Expand Down
5 changes: 5 additions & 0 deletions crates/starknet-types-core/src/hash/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
mod pedersen;
mod traits;

pub use self::pedersen::*;
pub use self::traits::*;
65 changes: 65 additions & 0 deletions crates/starknet-types-core/src/hash/pedersen.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
use crate::felt::Felt;
use lambdaworks_crypto::hash::pedersen::Pedersen as PedersenLambdaworks;
use lambdaworks_math::field::{
element::FieldElement, fields::fft_friendly::stark_252_prime_field::Stark252PrimeField,
};

use super::traits::StarkHash;

pub struct Pedersen;

impl StarkHash for Pedersen {
/// Computes the Pedersen hash of two Felts, as defined
/// in <https://docs.starknet.io/documentation/architecture_and_concepts/Hashing/hash-functions/#pedersen_hash.>
fn hash(felt_0: &Felt, felt_1: &Felt) -> Felt {
let pedersen = PedersenLambdaworks::default();

let hash = pedersen.hash(&felt_0.0, &felt_1.0);

Felt(hash)
}

/// Computes the Pedersen hash of an array of Felts, as defined
/// in <https://docs.starknet.io/documentation/architecture_and_concepts/Hashing/hash-functions/#array_hashing.>
fn hash_array(felts: &[Felt]) -> Felt {
let pedersen = PedersenLambdaworks::default();
let data_len = Felt::from(felts.len());
let current_hash: FieldElement<Stark252PrimeField> = felts.iter().fold(
FieldElement::<Stark252PrimeField>::zero(),
|current_hash, felt| pedersen.hash(&current_hash, &felt.0),
);
Felt(pedersen.hash(&current_hash, &data_len.0))
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_pedersen_hash() {
let x =
Felt::from_hex("0x03d937c035c878245caf64531a5756109c53068da139362728feb561405371cb")
.unwrap();
let y =
Felt::from_hex("0x0208a0a10250e382e1e4bbe2880906c2791bf6275695e02fbbc6aeff9cd8b31a")
.unwrap();

assert_eq!(
Pedersen::hash(&x, &y),
Felt::from_hex("0x030e480bed5fe53fa909cc0f8c4d99b8f9f2c016be4c41e13a4848797979c662")
.unwrap()
);
}

#[test]
fn test_pedersen_hash_array() {
let a = Felt::from_hex("0xaa").unwrap();
let b = Felt::from_hex("0xbb").unwrap();
let c = Felt::from_hex("0xcc").unwrap();
let expected =
Felt::from_hex("0x10808e8929644950878c4f71326e47c6b584d9cfea2de0415daf8def0f5e89f")
.unwrap();
assert_eq!(Pedersen::hash_array(&[a, b, c]), expected);
}
}
10 changes: 10 additions & 0 deletions crates/starknet-types-core/src/hash/traits.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use crate::felt::Felt;

pub trait StarkHash {
/// Computes the hash of two Felt
fn hash(felt_0: &Felt, felt_1: &Felt) -> Felt;

/// Computes the hash of an array of Felts,
/// as defined in <https://docs.starknet.io/documentation/architecture_and_concepts/Hashing/hash-functions/#array_hashing.>
fn hash_array(felts: &[Felt]) -> Felt;
}
3 changes: 3 additions & 0 deletions crates/starknet-types-core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(feature = "curve")]
pub mod curve;
#[cfg(feature = "hash")]
pub mod hash;

pub mod felt;
#[cfg(test)]
mod felt_arbitrary;

0 comments on commit 8476f50

Please sign in to comment.