Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore!: Add as_array and remove _slice variants of hash functions #4675

Merged
merged 7 commits into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions docs/docs/noir/concepts/data_types/slices.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,28 @@ fn main() {
assert(slice.len() == 2);
}
```

### as_array

Converts this slice into an array.

Make sure to specify the size of the resulting array.
Panics if the resulting array length is different than the slice's length.

```rust
fn as_array<N>(self) -> [T; N]
```

Example:

```rust
fn main() {
let slice = &[5, 6];

// Always specify the length of the resulting array!
let array: [Field; 2] = slice.as_array();

assert(array[0] == slice[0]);
assert(array[1] == slice[1]);
}
```
5 changes: 3 additions & 2 deletions docs/docs/noir/standard_library/containers/hashmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ Example:

```rust
// Create a mapping from Fields to u32s with a maximum length of 12
// using a pedersen hash
let mut map: HashMap<Field, u32, 12, BuildHasherDefault<Pedersen>> = HashMap::default();
// using a poseidon2 hasher
use dep::std::hash::poseidon2::Poseidon2Hasher;
let mut map: HashMap<Field, u32, 12, BuildHasherDefault<Poseidon2Hasher>> = HashMap::default();

map.insert(1, 2);
map.insert(3, 4);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import BlackBoxInfo from '@site/src/components/Notes/_blackbox.mdx';
## sha256

Given an array of bytes, returns the resulting sha256 hash.
See sha256_slice for a version that works directly on slices.

#include_code sha256 noir_stdlib/src/hash.nr rust

Expand All @@ -28,18 +27,9 @@ fn main() {

<BlackBoxInfo />

## sha256_slice

A version of sha256 specialized to slices:

#include_code sha256_slice noir_stdlib/src/hash.nr rust

<BlackBoxInfo />

## blake2s

Given an array of bytes, returns an array with the Blake2 hash
See blake2s_slice for a version that works directly on slices.

#include_code blake2s noir_stdlib/src/hash.nr rust

Expand All @@ -54,18 +44,9 @@ fn main() {

<BlackBoxInfo />

## blake2s_slice

A version of blake2s specialized to slices:

#include_code blake2s_slice noir_stdlib/src/hash.nr rust

<BlackBoxInfo />

## blake3

Given an array of bytes, returns an array with the Blake3 hash
See blake3_slice for a version that works directly on slices.

#include_code blake3 noir_stdlib/src/hash.nr rust

Expand All @@ -80,18 +61,9 @@ fn main() {

<BlackBoxInfo />

## blake3_slice

A version of blake3 specialized to slices:

#include_code blake3_slice noir_stdlib/src/hash.nr rust

<BlackBoxInfo />

## pedersen_hash

Given an array of Fields, returns the Pedersen hash.
See pedersen_hash_slice for a version that works directly on slices.

#include_code pedersen_hash noir_stdlib/src/hash.nr rust

Expand All @@ -101,18 +73,9 @@ example:

<BlackBoxInfo />

## pedersen_hash_slice

Given a slice of Fields, returns the Pedersen hash.

#include_code pedersen_hash_slice noir_stdlib/src/hash.nr rust

<BlackBoxInfo />

## pedersen_commitment

Given an array of Fields, returns the Pedersen commitment.
See pedersen_commitment_slice for a version that works directly on slices.

#include_code pedersen_commitment noir_stdlib/src/hash.nr rust

Expand All @@ -122,20 +85,11 @@ example:

<BlackBoxInfo />

## pedersen_commitment_slice

Given a slice of Fields, returns the Pedersen commitment.

#include_code pedersen_commitment_slice noir_stdlib/src/hash.nr rust

<BlackBoxInfo />

## keccak256

Given an array of bytes (`u8`), returns the resulting keccak hash as an array of
32 bytes (`[u8; 32]`). Specify a message_size to hash only the first
`message_size` bytes of the input. See keccak256_slice for a version that works
directly on slices.
`message_size` bytes of the input.

#include_code keccak256 noir_stdlib/src/hash.nr rust

Expand All @@ -145,15 +99,6 @@ example:

<BlackBoxInfo />

## keccak256_slice

Given a slice of bytes (`u8`), returns the resulting keccak hash as an array of
32 bytes (`[u8; 32]`).

#include_code keccak256_slice noir_stdlib/src/hash.nr rust

<BlackBoxInfo />

## poseidon

Given an array of Fields, returns a new Field with the Poseidon Hash. Mind that you need to specify
Expand Down
81 changes: 15 additions & 66 deletions noir_stdlib/src/hash.nr
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
mod poseidon;
mod mimc;
mod poseidon2;
mod pedersen;

use crate::default::Default;
use crate::uint128::U128;
Expand All @@ -12,36 +11,18 @@ pub fn sha256<N>(input: [u8; N]) -> [u8; 32]
// docs:end:sha256
{}

#[foreign(sha256)]
// docs:start:sha256_slice
pub fn sha256_slice(input: [u8]) -> [u8; 32]
// docs:end:sha256_slice
{}

#[foreign(blake2s)]
// docs:start:blake2s
pub fn blake2s<N>(input: [u8; N]) -> [u8; 32]
// docs:end:blake2s
{}

#[foreign(blake2s)]
// docs:start:blake2s_slice
pub fn blake2s_slice(input: [u8]) -> [u8; 32]
// docs:end:blake2s_slice
{}

#[foreign(blake3)]
// docs:start:blake3
pub fn blake3<N>(input: [u8; N]) -> [u8; 32]
// docs:end:blake3
{}

#[foreign(blake3)]
// docs:start:blake3_slice
pub fn blake3_slice(input: [u8]) -> [u8; 32]
// docs:end:blake3_slice
{}

// docs:start:pedersen_commitment
struct PedersenPoint {
x : Field,
Expand All @@ -53,60 +34,33 @@ pub fn pedersen_commitment<N>(input: [Field; N]) -> PedersenPoint {
pedersen_commitment_with_separator(input, 0)
}

// docs:start:pedersen_commitment_slice
pub fn pedersen_commitment_slice(input: [Field]) -> PedersenPoint {
pedersen_commitment_with_separator_slice(input, 0)
}
// docs:end:pedersen_commitment_slice

#[foreign(pedersen_commitment)]
pub fn __pedersen_commitment_with_separator<N>(input: [Field; N], separator: u32) -> [Field; 2] {}

#[foreign(pedersen_commitment)]
pub fn __pedersen_commitment_with_separator_slice(input: [Field], separator: u32) -> [Field; 2] {}

pub fn pedersen_commitment_with_separator<N>(input: [Field; N], separator: u32) -> PedersenPoint {
let values = __pedersen_commitment_with_separator(input, separator);
PedersenPoint { x: values[0], y: values[1] }
}

pub fn pedersen_commitment_with_separator_slice(input: [Field], separator: u32) -> PedersenPoint {
let values = __pedersen_commitment_with_separator_slice(input, separator);
PedersenPoint { x: values[0], y: values[1] }
}

// docs:start:pedersen_hash
pub fn pedersen_hash<N>(input: [Field; N]) -> Field
// docs:end:pedersen_hash
{
pedersen_hash_with_separator(input, 0)
}

// docs:start:pedersen_hash_slice
pub fn pedersen_hash_slice(input: [Field]) -> Field
// docs:end:pedersen_hash_slice
{
pedersen_hash_with_separator_slice(input, 0)
}

#[foreign(pedersen_hash)]
pub fn pedersen_hash_with_separator<N>(input: [Field; N], separator: u32) -> Field {}

#[foreign(pedersen_hash)]
pub fn pedersen_hash_with_separator_slice(input: [Field], separator: u32) -> Field {}

pub fn hash_to_field(inputs: [Field]) -> Field {
let mut inputs_as_bytes = &[];
let mut sum = 0;

for input in inputs {
let input_bytes = input.to_le_bytes(32);
for i in 0..32 {
inputs_as_bytes = inputs_as_bytes.push_back(input_bytes[i]);
}
let input_bytes: [u8; 32] = input.to_le_bytes(32).as_array();
sum += crate::field::bytes32_to_field(blake2s(input_bytes));
}

let hashed_input = blake2s_slice(inputs_as_bytes);
crate::field::bytes32_to_field(hashed_input)
sum
}

#[foreign(keccak256)]
Expand All @@ -115,12 +69,6 @@ pub fn keccak256<N>(input: [u8; N], message_size: u32) -> [u8; 32]
// docs:end:keccak256
{}

#[foreign(keccak256)]
// docs:start:keccak256_slice
pub fn keccak256_slice(input: [u8], message_size: u32) -> [u8; 32]
// docs:end:keccak256_slice
{}

#[foreign(poseidon2_permutation)]
pub fn poseidon2_permutation<N>(_input: [Field; N], _state_length: u32) -> [Field; N] {}

Expand All @@ -140,7 +88,7 @@ trait Hash{
trait Hasher{
fn finish(self) -> Field;

fn write(&mut self, input: [Field]);
jfecher marked this conversation as resolved.
Show resolved Hide resolved
fn write(&mut self, input: Field);
}

// BuildHasher is a factory trait, responsible for production of specific Hasher.
Expand Down Expand Up @@ -170,49 +118,49 @@ where

impl Hash for Field {
fn hash<H>(self, state: &mut H) where H: Hasher{
H::write(state, &[self]);
H::write(state, self);
}
}

impl Hash for u8 {
fn hash<H>(self, state: &mut H) where H: Hasher{
H::write(state, &[self as Field]);
H::write(state, self as Field);
}
}

impl Hash for u32 {
fn hash<H>(self, state: &mut H) where H: Hasher{
H::write(state, &[self as Field]);
H::write(state, self as Field);
}
}

impl Hash for u64 {
fn hash<H>(self, state: &mut H) where H: Hasher{
H::write(state, &[self as Field]);
H::write(state, self as Field);
}
}

impl Hash for i8 {
fn hash<H>(self, state: &mut H) where H: Hasher{
H::write(state, &[self as Field]);
H::write(state, self as Field);
}
}

impl Hash for i32 {
fn hash<H>(self, state: &mut H) where H: Hasher{
H::write(state, &[self as Field]);
H::write(state, self as Field);
}
}

impl Hash for i64 {
fn hash<H>(self, state: &mut H) where H: Hasher{
H::write(state, &[self as Field]);
H::write(state, self as Field);
}
}

impl Hash for bool {
fn hash<H>(self, state: &mut H) where H: Hasher{
H::write(state, &[self as Field]);
H::write(state, self as Field);
}
}

Expand All @@ -222,7 +170,8 @@ impl Hash for () {

impl Hash for U128 {
fn hash<H>(self, state: &mut H) where H: Hasher{
H::write(state, &[self.lo as Field, self.hi as Field]);
H::write(state, self.lo as Field);
H::write(state, self.hi as Field);
}
}

Expand Down
Loading
Loading