Skip to content

Commit e4aaeae

Browse files
committed
feat: add pack_bytes
1 parent 8a02635 commit e4aaeae

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

README.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Put this into your Nargo.toml.
99
If you are using Noir:
1010

1111
```toml
12-
nodash = { git = "https://github.com/olehmisar/nodash/", tag = "v0.35.3" }
12+
nodash = { git = "https://github.com/olehmisar/nodash/", tag = "v0.35.4" }
1313
```
1414

1515
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., [email protected] and [email protected] are compatible with [email protected].
@@ -137,3 +137,14 @@ use nodash::ArrayExtensions;
137137

138138
assert([1, 2, 3].pad_end::<5>(0) == [1, 2, 3, 0, 0]);
139139
```
140+
141+
### `pack_bytes`
142+
143+
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)`.
144+
145+
```rs
146+
use nodash::pack_bytes;
147+
148+
let bytes: [u8; 32] = [0; 32];
149+
let packed = pack_bytes(bytes);
150+
```

src/array.nr

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,29 @@ impl<T, let N: u32> crate::ArrayExtensions<T, N> for [T; N] {
3939
}
4040
}
4141

42+
// TODO: write tests
43+
pub fn pack_bytes<let N: u32>(bytes: [u8; N]) -> [Field; N / 31 + 1] {
44+
let bytes_padded = bytes.pad_end::<(N / 31 + 1) * 31>(N / 31 + 1) * 31>( 0);
45+
let mut res = [0 as Field; N / 31 + 1];
46+
for i in 0..N / 31 + 1 {
47+
let chunk = bytes_padded.slice::<31>(i * 31, i * 31 + 31);
48+
res[i] = field_from_bytes(chunk);
49+
}
50+
res
51+
}
52+
53+
// copied from https://github.com/AztecProtocol/aztec-packages/blob/a2ed567ad42b237088c110ce12ce8212d5099da2/noir-projects/noir-protocol-circuits/crates/types/src/utils/field.nr#L4
54+
fn field_from_bytes<let N: u32>(bytes: [u8; N]) -> Field {
55+
assert(bytes.len() < 32, "field_from_bytes: N must be less than 32");
56+
let mut as_field = 0;
57+
let mut offset = 1;
58+
for i in 0..N {
59+
as_field += (bytes[i] as Field) * offset;
60+
offset *= 256;
61+
}
62+
as_field
63+
}
64+
4265
mod tests {
4366
#[test]
4467
fn test_slice() {

0 commit comments

Comments
 (0)