Skip to content

Commit 1c8e940

Browse files
committed
fix: zero padding/length region in digest_var
`digest_var` copied the BoundedVec's entire backing store (`for i in 0..N`) into the padded message, then only overwrote the 0x80 marker and the length bytes. Bytes in the backing store beyond `len()` are unconstrained witness data, so any non-zero value there landed in the SHA padding region and silently altered the digest — the padding region was only ever zero by convention, never by constraint. Gate the copy on `i < msg_length` so the padding/length region is forced to zero regardless of the witness, matching noir-lang/sha256 v0.3.0 which already ignores input bytes past the message length. Adds a regression test (`test_dirty_padding_ignored`) that hashes "abc" from a BoundedVec whose tail is filled with 0xff via `from_parts_unchecked`; it fails on the old code and passes with the fix.
1 parent e92ffb4 commit 1c8e940

1 file changed

Lines changed: 20 additions & 3 deletions

File tree

src/lib.nr

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,13 +140,13 @@ fn digest_var<let N: u32, let IS_SHA512: u8>(msg: BoundedVec<u8, N>) -> [u8; 64]
140140
* SHA512_BLOCK_SIZE
141141
];
142142

143+
let msg_length = msg.len();
144+
143145
let msg_text = msg.storage();
144146
for i in 0..N {
145-
padded_msg[i] = msg_text[i];
147+
padded_msg[i] = if i < msg_length { msg_text[i] } else { 0 };
146148
}
147149

148-
let msg_length = msg.len();
149-
150150
let num_used_blocks =
151151
(msg_length + SHA512_LENGTH_PARAMETER_BYTES + SHA512_BLOCK_SIZE) / SHA512_BLOCK_SIZE;
152152

@@ -285,6 +285,23 @@ pub mod sha512 {
285285
assert_eq(result_var, expected);
286286
}
287287

288+
#[test]
289+
fn test_dirty_padding_ignored() {
290+
let mut dirty: [u8; 256] = [0xff; 256];
291+
dirty[0] = 0x61; // 'a'
292+
dirty[1] = 0x62; // 'b'
293+
dirty[2] = 0x63; // 'c'
294+
let result_var = sha512_var(BoundedVec::<u8, 256>::from_parts_unchecked(dirty, 3));
295+
let expected: [u8; 64] = [
296+
0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20,
297+
0x41, 0x31, 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2, 0x0a, 0x9e, 0xee, 0xe6,
298+
0x4b, 0x55, 0xd3, 0x9a, 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba,
299+
0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd, 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
300+
0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f,
301+
];
302+
assert_eq(result_var, expected);
303+
}
304+
288305
}
289306

290307
pub mod sha384 {

0 commit comments

Comments
 (0)