Skip to content

Commit

Permalink
feat: add pack_bytes
Browse files Browse the repository at this point in the history
  • Loading branch information
olehmisar committed Oct 23, 2024
1 parent 8a02635 commit e4aaeae
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 1 deletion.
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Put this into your Nargo.toml.
If you are using Noir:

```toml
nodash = { git = "https://github.com/olehmisar/nodash/", tag = "v0.35.3" }
nodash = { git = "https://github.com/olehmisar/nodash/", tag = "v0.35.4" }
```

The version of nodash matches the version of Noir. The patch version may be different if a bugfix or a new feature is added for the same version of Noir. E.g., nodash@v0.35.0 and nodash@v0.35.1 are compatible with noir@v0.35.0.
Expand Down Expand Up @@ -137,3 +137,14 @@ use nodash::ArrayExtensions;

assert([1, 2, 3].pad_end::<5>(0) == [1, 2, 3, 0, 0]);
```

### `pack_bytes`

Packs `[u8; N]` into `[Field; N / 31 + 1]`. Useful, if you need to get a hash over bytes. I.e., `pedersen_hash(pack_bytes(bytes))` will be MUCH cheaper than `pedersen_hash(bytes)`.

```rs
use nodash::pack_bytes;

let bytes: [u8; 32] = [0; 32];
let packed = pack_bytes(bytes);
```
23 changes: 23 additions & 0 deletions src/array.nr
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,29 @@ impl<T, let N: u32> crate::ArrayExtensions<T, N> for [T; N] {
}
}

// TODO: write tests
pub fn pack_bytes<let N: u32>(bytes: [u8; N]) -> [Field; N / 31 + 1] {
let bytes_padded = bytes.pad_end::<(N / 31 + 1) * 31>(N / 31 + 1) * 31>( 0);
let mut res = [0 as Field; N / 31 + 1];
for i in 0..N / 31 + 1 {
let chunk = bytes_padded.slice::<31>(i * 31, i * 31 + 31);
res[i] = field_from_bytes(chunk);
}
res
}

// copied from https://github.com/AztecProtocol/aztec-packages/blob/a2ed567ad42b237088c110ce12ce8212d5099da2/noir-projects/noir-protocol-circuits/crates/types/src/utils/field.nr#L4
fn field_from_bytes<let N: u32>(bytes: [u8; N]) -> Field {
assert(bytes.len() < 32, "field_from_bytes: N must be less than 32");
let mut as_field = 0;
let mut offset = 1;
for i in 0..N {
as_field += (bytes[i] as Field) * offset;
offset *= 256;
}
as_field
}

mod tests {
#[test]
fn test_slice() {
Expand Down

0 comments on commit e4aaeae

Please sign in to comment.