From 55ae361f6bb63489ab80f7b8b495b4a737438580 Mon Sep 17 00:00:00 2001 From: LHerskind Date: Wed, 8 May 2024 10:13:34 +0000 Subject: [PATCH 1/5] initial update of padding and proper aes --- .../aztec-nr/aztec/src/encrypted_logs/body.nr | 73 +++++++++++-------- .../aztec/src/encrypted_logs/header.nr | 21 ++---- .../src/barretenberg/crypto/aes128/index.ts | 2 +- 3 files changed, 49 insertions(+), 47 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/encrypted_logs/body.nr b/noir-projects/aztec-nr/aztec/src/encrypted_logs/body.nr index 07bd08b46e3..4b1a86ee0fa 100644 --- a/noir-projects/aztec-nr/aztec/src/encrypted_logs/body.nr +++ b/noir-projects/aztec-nr/aztec/src/encrypted_logs/body.nr @@ -1,17 +1,18 @@ use crate::note::{note_interface::NoteInterface}; use dep::protocol_types::{grumpkin_private_key::GrumpkinPrivateKey, grumpkin_point::GrumpkinPoint}; -use crate::oracle::encryption::aes128_encrypt; +use dep::std::aes128::aes128_encrypt; +use dep::std::println; use crate::keys::point_to_symmetric_key::point_to_symmetric_key; -struct EncryptedLogBody { +struct EncryptedLogBody { storage_slot: Field, note_type_id: Field, note: Note, } -impl EncryptedLogBody { - pub fn new( +impl EncryptedLogBody { + pub fn new( storage_slot: Field, note_type_id: Field, note: Note @@ -19,25 +20,34 @@ impl EncryptedLogBody { Self { storage_slot, note_type_id, note } } - pub fn compute_ciphertext( + pub fn compute_ciphertext( self, secret: GrumpkinPrivateKey, - point: GrumpkinPoint - ) -> [u8; M] where Note: NoteInterface { + point: GrumpkinPoint, + serialized_note: [Field; N] + ) -> [u8] where Note: NoteInterface { // We need 32 bytes for every field in the note, and then we have 2 extra fields (storage_slot and note_type_id) - let serialized_note: [Field; N] = Note::serialize_content(self.note); + // let serialized_note: [Field; N] = self.note.serialize_content();// Note::serialize_content(self.note); // Work around not being able to use N directly beyond the size of the array above. let N_ = serialized_note.len(); - assert(N_ * 32 + 64 == M, "Invalid size of encrypted log body"); - - let mut buffer: [u8; M] = [0; M]; + // assert(N_ * 32 + 64 == M, "Invalid size of encrypted log body"); + let mut buffer_slice: [u8] = &[]; let storage_slot_bytes = self.storage_slot.to_be_bytes(32); let note_type_id_bytes = self.note_type_id.to_be_bytes(32); + + for i in 0..(N_ * 32 + 64) { + buffer_slice.push_back(0); + } + + // Cannot use N in here :( + //let mut buffer: [u8; N * 32 + 64] = [0; N * 32 + 64]; + +/* for i in 0..32 { - buffer[i] = storage_slot_bytes[i]; + buffer_slice.push_back(storage_slot_bytes[i]); buffer[32 + i] = note_type_id_bytes[i]; } @@ -46,7 +56,7 @@ impl EncryptedLogBody { for j in 0..32 { buffer[64 + i * 32 + j] = bytes[j]; } - } + }*/ let full_key = point_to_symmetric_key(secret, point); let mut sym_key = [0; 16]; @@ -57,15 +67,20 @@ impl EncryptedLogBody { iv[i] = full_key[i + 16]; } - aes128_encrypt(buffer, iv, sym_key) + aes128_encrypt(buffer_slice.as_array(), iv, sym_key) +/* + let mut return_slice: [u8] = &[]; + for i in 0..(ciphertext.len()) { + return_slice.push_back(ciphertext[i]); + } + + return_slice*/ } } -/* -// Test is semi broken, needs to be fixed along with #6172 mod test { use crate::encrypted_logs::body::EncryptedLogBody; - use dep::protocol_types::{address::AztecAddress, traits::Empty, constants::GENERATOR_INDEX__NOTE_NULLIFIER}; + use dep::protocol_types::{address::AztecAddress, traits::Empty, constants::GENERATOR_INDEX__NOTE_NULLIFIER, grumpkin_private_key::GrumpkinPrivateKey, grumpkin_point::GrumpkinPoint}; use crate::{ note::{note_header::NoteHeader, note_interface::NoteInterface, utils::compute_note_hash_for_consumption}, @@ -73,8 +88,6 @@ mod test { context::PrivateContext, hash::poseidon2_hash }; - use dep::protocol_types::{address::AztecAddress, grumpkin_private_key::GrumpkinPrivateKey, grumpkin_point::GrumpkinPoint}; - struct AddressNote { address: AztecAddress, owner: AztecAddress, @@ -82,9 +95,9 @@ mod test { header: NoteHeader, } - global BIB_BOB_ADDRESS_NOTE_LEN: Field = 3; + global ADDRESS_NOTE_LEN: Field = 3; - impl NoteInterface for AddressNote { + impl NoteInterface for AddressNote { fn compute_note_content_hash(self) -> Field {1} fn get_note_type_id() -> Field {2} @@ -99,9 +112,9 @@ mod test { fn broadcast(self, context: &mut PrivateContext, slot: Field) {} - fn serialize_content(self) -> [Field; BIB_BOB_ADDRESS_NOTE_LEN] { [self.address.to_field(), self.owner.to_field(), self.randomness]} + fn serialize_content(self) -> [Field; ADDRESS_NOTE_LEN] { [self.address.to_field(), self.owner.to_field(), self.randomness]} - fn deserialize_content(fields: [Field; BIB_BOB_ADDRESS_NOTE_LEN]) -> Self { + fn deserialize_content(fields: [Field; ADDRESS_NOTE_LEN]) -> Self { AddressNote { address: AztecAddress::from_field(fields[0]), owner: AztecAddress::from_field(fields[1]), randomness: fields[2], header: NoteHeader::empty() } } } @@ -113,7 +126,7 @@ mod test { // docs:end:address_note_def } - // @todo Issue(#6172) This is to be run as a test. But it is currently using the AES oracle so will fail there. + #[test] fn test_encrypted_log_body() { let note = AddressNote::new( AztecAddress::from_field(0x1), @@ -134,14 +147,10 @@ mod test { 0x1e96887b117afca01c00468264f4f80b5bb16d94c1808a448595f115556e5c8e ); - let ciphertext = body.compute_ciphertext(secret, point); + let ciphertext = body.compute_ciphertext(secret, point, note.serialize_content()); - let expected_body_ciphertext = [ - 131, 119, 105, 129, 244, 32, 151, 205, 12, 99, 93, 62, 10, 180, 72, 21, 36, 194, 14, 168, 0, 137, 126, 59, 151, 177, 136, 254, 153, 190, 92, 33, 40, 151, 178, 54, 34, 166, 124, 96, 117, 108, 168, 7, 147, 222, 81, 201, 254, 170, 244, 151, 60, 64, 226, 45, 156, 185, 53, 23, 121, 63, 243, 101, 134, 21, 167, 39, 226, 203, 162, 223, 28, 74, 244, 159, 54, 201, 192, 168, 19, 85, 103, 82, 148, 3, 153, 210, 89, 245, 171, 171, 12, 248, 40, 74, 199, 65, 96, 42, 84, 83, 48, 21, 188, 134, 45, 247, 134, 166, 109, 170, 68, 212, 99, 235, 74, 202, 162, 108, 130, 128, 122, 16, 79, 242, 30, 157, 26, 75, 57, 24, 18, 124, 217, 74, 155, 13, 171, 205, 194, 193, 103, 134, 224, 204, 46, 105, 135, 166, 192, 163, 186, 42, 71, 51, 156, 161, 8, 131 - ]; + let expected_body_ciphertext = [131,119,105,129,244,32,151,205,12,99,93,62,10,180,72,21,36,194,14,168,0,137,126,59,151,177,136,254,153,190,92,33,40,151,178,54,34,166,124,96,117,108,168,7,147,222,81,201,254,170,244,151,60,64,226,45,156,185,53,23,121,63,243,101,134,21,167,39,226,203,162,223,28,74,244,159,54,201,192,168,19,85,103,82,148,3,153,210,89,245,171,171,12,248,40,74,199,65,96,42,84,83,48,21,188,134,45,247,134,166,109,170,68,212,99,235,74,202,162,108,130,128,122,16,79,242,30,157,26,75,57,24,18,124,217,74,155,13,171,205,194,193,103,134,224,204,46,105,135,166,192,163,186,42,71,51,156,161,8,131,233,228,107,151,254,111,215,19,22,34,252,158,214,97,197,22]; - assert_eq(ciphertext, expected_body_ciphertext); + // assert_eq(ciphertext, expected_body_ciphertext); } -} - -*/ +} \ No newline at end of file diff --git a/noir-projects/aztec-nr/aztec/src/encrypted_logs/header.nr b/noir-projects/aztec-nr/aztec/src/encrypted_logs/header.nr index 03b5a33e3d1..9ca749384c1 100644 --- a/noir-projects/aztec-nr/aztec/src/encrypted_logs/header.nr +++ b/noir-projects/aztec-nr/aztec/src/encrypted_logs/header.nr @@ -1,8 +1,9 @@ use dep::protocol_types::{address::AztecAddress, grumpkin_private_key::GrumpkinPrivateKey, grumpkin_point::GrumpkinPoint}; -use crate::oracle::encryption::aes128_encrypt; use crate::keys::point_to_symmetric_key::point_to_symmetric_key; +use dep::std::aes128::aes128_encrypt; + struct EncryptedLogHeader { address: AztecAddress, } @@ -13,28 +14,22 @@ impl EncryptedLogHeader { } // @todo Issue(#5901) Figure out if we return the bytes or fields for the log - fn compute_ciphertext(self, secret: GrumpkinPrivateKey, point: GrumpkinPoint) -> [u8; 32] { + fn compute_ciphertext(self, secret: GrumpkinPrivateKey, point: GrumpkinPoint) -> [u8; 48] { let full_key = point_to_symmetric_key(secret, point); let mut sym_key = [0; 16]; let mut iv = [0; 16]; - let mut input = [0; 32]; - let input_slice = self.address.to_field().to_be_bytes(32); for i in 0..16 { sym_key[i] = full_key[i]; iv[i] = full_key[i + 16]; - - // We copy address on the following 2 lines in order to avoid having 2 loops - input[i] = input_slice[i]; - input[i + 16] = input_slice[i + 16]; } - // @todo Issue(#6172) This encryption is currently using an oracle. It is not actually constrained atm. - aes128_encrypt(input, iv, sym_key) + let input: [u8; 32] = self.address.to_field().to_be_bytes(32).as_array(); + aes128_encrypt(input, iv, sym_key).as_array() } } -// @todo Issue(#6172) This is to be run as a test. But it is currently using the AES oracle so will fail there. +#[test] fn test_encrypted_log_header() { let address = AztecAddress::from_field(0xdeadbeef); let header = EncryptedLogHeader::new(address); @@ -49,9 +44,7 @@ fn test_encrypted_log_header() { let ciphertext = header.compute_ciphertext(secret, point); - let expected_header_ciphertext = [ - 131, 119, 105, 129, 244, 32, 151, 205, 12, 99, 93, 62, 10, 180, 72, 21, 179, 36, 250, 95, 56, 167, 171, 16, 195, 164, 223, 57, 75, 5, 24, 119 - ]; + let expected_header_ciphertext = [131,119,105,129,244,32,151,205,12,99,93,62,10,180,72,21,179,36,250,95,56,167,171,16,195,164,223,57,75,5,24,119,198,34,99,189,193,183,227,43,79,204,214,89,221,153,246,64]; assert_eq(ciphertext, expected_header_ciphertext); } diff --git a/yarn-project/circuits.js/src/barretenberg/crypto/aes128/index.ts b/yarn-project/circuits.js/src/barretenberg/crypto/aes128/index.ts index cf3a8a5ddec..29456dff3a0 100644 --- a/yarn-project/circuits.js/src/barretenberg/crypto/aes128/index.ts +++ b/yarn-project/circuits.js/src/barretenberg/crypto/aes128/index.ts @@ -15,7 +15,7 @@ export class Aes128 { */ public encryptBufferCBC(data: Uint8Array, iv: Uint8Array, key: Uint8Array) { const rawLength = data.length; - const numPaddingBytes = rawLength % 16 != 0 ? 16 - (rawLength % 16) : 0; + const numPaddingBytes = 16 - (rawLength % 16); const paddingBuffer = Buffer.alloc(numPaddingBytes); // input num bytes needs to be a multiple of 16 // node uses PKCS#7-Padding scheme, where padding byte value = the number of padding bytes From 0fa345c5672809d79d9e3432d8ba4754399d25ab Mon Sep 17 00:00:00 2001 From: thunkar Date: Wed, 8 May 2024 10:54:45 +0000 Subject: [PATCH 2/5] plz don't kill me --- .../aztec-nr/aztec/src/encrypted_logs/body.nr | 66 ++++++++----------- noir/noir-repo/noir_stdlib/src/aes128.nr | 3 + 2 files changed, 32 insertions(+), 37 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/encrypted_logs/body.nr b/noir-projects/aztec-nr/aztec/src/encrypted_logs/body.nr index 4b1a86ee0fa..c962ec1ab57 100644 --- a/noir-projects/aztec-nr/aztec/src/encrypted_logs/body.nr +++ b/noir-projects/aztec-nr/aztec/src/encrypted_logs/body.nr @@ -1,18 +1,18 @@ use crate::note::{note_interface::NoteInterface}; use dep::protocol_types::{grumpkin_private_key::GrumpkinPrivateKey, grumpkin_point::GrumpkinPoint}; -use dep::std::aes128::aes128_encrypt; +use dep::std::aes128::aes128_encrypt_slice; use dep::std::println; use crate::keys::point_to_symmetric_key::point_to_symmetric_key; -struct EncryptedLogBody { +struct EncryptedLogBody { storage_slot: Field, note_type_id: Field, note: Note, } -impl EncryptedLogBody { - pub fn new( +impl EncryptedLogBody { + pub fn new( storage_slot: Field, note_type_id: Field, note: Note @@ -20,43 +20,37 @@ impl EncryptedLogBody { Self { storage_slot, note_type_id, note } } - pub fn compute_ciphertext( + pub fn compute_ciphertext( self, secret: GrumpkinPrivateKey, - point: GrumpkinPoint, - serialized_note: [Field; N] + point: GrumpkinPoint ) -> [u8] where Note: NoteInterface { // We need 32 bytes for every field in the note, and then we have 2 extra fields (storage_slot and note_type_id) - // let serialized_note: [Field; N] = self.note.serialize_content();// Note::serialize_content(self.note); + let serialized_note: [Field; N] = self.note.serialize_content(); // Note::serialize_content(self.note); - // Work around not being able to use N directly beyond the size of the array above. - let N_ = serialized_note.len(); - - // assert(N_ * 32 + 64 == M, "Invalid size of encrypted log body"); let mut buffer_slice: [u8] = &[]; let storage_slot_bytes = self.storage_slot.to_be_bytes(32); let note_type_id_bytes = self.note_type_id.to_be_bytes(32); - for i in 0..(N_ * 32 + 64) { - buffer_slice.push_back(0); + for _ in 0..(serialized_note.len() * 32 + 64) { + buffer_slice = buffer_slice.push_back(0); } - // Cannot use N in here :( - //let mut buffer: [u8; N * 32 + 64] = [0; N * 32 + 64]; + for i in 0..32 { + buffer_slice = buffer_slice.push_back(storage_slot_bytes[i]); + } -/* for i in 0..32 { - buffer_slice.push_back(storage_slot_bytes[i]); - buffer[32 + i] = note_type_id_bytes[i]; + buffer_slice = buffer_slice.push_back(note_type_id_bytes[i]); } - for i in 0..N_ { + for i in 0..serialized_note.len() { let bytes = serialized_note[i].to_be_bytes(32); for j in 0..32 { - buffer[64 + i * 32 + j] = bytes[j]; + buffer_slice = buffer_slice.push_back(bytes[j]); } - }*/ + } let full_key = point_to_symmetric_key(secret, point); let mut sym_key = [0; 16]; @@ -66,21 +60,16 @@ impl EncryptedLogBody { sym_key[i] = full_key[i]; iv[i] = full_key[i + 16]; } - - aes128_encrypt(buffer_slice.as_array(), iv, sym_key) -/* - let mut return_slice: [u8] = &[]; - for i in 0..(ciphertext.len()) { - return_slice.push_back(ciphertext[i]); - } - - return_slice*/ + aes128_encrypt_slice(buffer_slice, iv, sym_key) } } mod test { use crate::encrypted_logs::body::EncryptedLogBody; - use dep::protocol_types::{address::AztecAddress, traits::Empty, constants::GENERATOR_INDEX__NOTE_NULLIFIER, grumpkin_private_key::GrumpkinPrivateKey, grumpkin_point::GrumpkinPoint}; + use dep::protocol_types::{ + address::AztecAddress, traits::Empty, constants::GENERATOR_INDEX__NOTE_NULLIFIER, + grumpkin_private_key::GrumpkinPrivateKey, grumpkin_point::GrumpkinPoint + }; use crate::{ note::{note_header::NoteHeader, note_interface::NoteInterface, utils::compute_note_hash_for_consumption}, @@ -147,10 +136,13 @@ mod test { 0x1e96887b117afca01c00468264f4f80b5bb16d94c1808a448595f115556e5c8e ); - let ciphertext = body.compute_ciphertext(secret, point, note.serialize_content()); - - let expected_body_ciphertext = [131,119,105,129,244,32,151,205,12,99,93,62,10,180,72,21,36,194,14,168,0,137,126,59,151,177,136,254,153,190,92,33,40,151,178,54,34,166,124,96,117,108,168,7,147,222,81,201,254,170,244,151,60,64,226,45,156,185,53,23,121,63,243,101,134,21,167,39,226,203,162,223,28,74,244,159,54,201,192,168,19,85,103,82,148,3,153,210,89,245,171,171,12,248,40,74,199,65,96,42,84,83,48,21,188,134,45,247,134,166,109,170,68,212,99,235,74,202,162,108,130,128,122,16,79,242,30,157,26,75,57,24,18,124,217,74,155,13,171,205,194,193,103,134,224,204,46,105,135,166,192,163,186,42,71,51,156,161,8,131,233,228,107,151,254,111,215,19,22,34,252,158,214,97,197,22]; + let ciphertext = body.compute_ciphertext(secret, point); - // assert_eq(ciphertext, expected_body_ciphertext); + let expected_body_ciphertext = [ + 131, 119, 105, 129, 244, 32, 151, 205, 12, 99, 93, 62, 10, 180, 72, 21, 36, 194, 14, 168, 0, 137, 126, 59, 151, 177, 136, 254, 153, 190, 92, 33, 40, 151, 178, 54, 34, 166, 124, 96, 117, 108, 168, 7, 147, 222, 81, 201, 254, 170, 244, 151, 60, 64, 226, 45, 156, 185, 53, 23, 121, 63, 243, 101, 134, 21, 167, 39, 226, 203, 162, 223, 28, 74, 244, 159, 54, 201, 192, 168, 19, 85, 103, 82, 148, 3, 153, 210, 89, 245, 171, 171, 12, 248, 40, 74, 199, 65, 96, 42, 84, 83, 48, 21, 188, 134, 45, 247, 134, 166, 109, 170, 68, 212, 99, 235, 74, 202, 162, 108, 130, 128, 122, 16, 79, 242, 30, 157, 26, 75, 57, 24, 18, 124, 217, 74, 155, 13, 171, 205, 194, 193, 103, 134, 224, 204, 46, 105, 135, 166, 192, 163, 186, 42, 71, 51, 156, 161, 8, 131, 233, 228, 107, 151, 254, 111, 215, 19, 22, 34, 252, 158, 214, 97, 197, 22 + ]; + for i in 0..ciphertext.len() { + assert_eq(ciphertext[i], expected_body_ciphertext[i]); + } } -} \ No newline at end of file +} diff --git a/noir/noir-repo/noir_stdlib/src/aes128.nr b/noir/noir-repo/noir_stdlib/src/aes128.nr index e6e2a5e4997..cd61021a953 100644 --- a/noir/noir-repo/noir_stdlib/src/aes128.nr +++ b/noir/noir-repo/noir_stdlib/src/aes128.nr @@ -2,3 +2,6 @@ // docs:start:aes128 pub fn aes128_encrypt(input: [u8; N], iv: [u8; 16], key: [u8; 16]) -> [u8] {} // docs:end:aes128 + +#[foreign(aes128_encrypt)] +pub fn aes128_encrypt_slice(input: [u8], iv: [u8; 16], key: [u8; 16]) -> [u8] {} From 9c4d2bca6ca926aa73c96b9aa7cd99de881da7b0 Mon Sep 17 00:00:00 2001 From: David Banks <47112877+dbanks12@users.noreply.github.com> Date: Wed, 8 May 2024 06:24:32 -0400 Subject: [PATCH 3/5] initial update of padding and proper aes --- .../aztec-nr/aztec/src/encrypted_logs/body.nr | 15 +++++---------- .../aztec-nr/aztec/src/encrypted_logs/header.nr | 10 ++++++---- .../contracts/test_contract/src/main.nr | 10 +++++----- .../src/logs/encrypted_log_body.test.ts | 2 +- 4 files changed, 17 insertions(+), 20 deletions(-) diff --git a/noir-projects/aztec-nr/aztec/src/encrypted_logs/body.nr b/noir-projects/aztec-nr/aztec/src/encrypted_logs/body.nr index c962ec1ab57..4393d9da16c 100644 --- a/noir-projects/aztec-nr/aztec/src/encrypted_logs/body.nr +++ b/noir-projects/aztec-nr/aztec/src/encrypted_logs/body.nr @@ -2,7 +2,6 @@ use crate::note::{note_interface::NoteInterface}; use dep::protocol_types::{grumpkin_private_key::GrumpkinPrivateKey, grumpkin_point::GrumpkinPoint}; use dep::std::aes128::aes128_encrypt_slice; -use dep::std::println; use crate::keys::point_to_symmetric_key::point_to_symmetric_key; struct EncryptedLogBody { @@ -25,18 +24,13 @@ impl EncryptedLogBody { secret: GrumpkinPrivateKey, point: GrumpkinPoint ) -> [u8] where Note: NoteInterface { - // We need 32 bytes for every field in the note, and then we have 2 extra fields (storage_slot and note_type_id) - let serialized_note: [Field; N] = self.note.serialize_content(); // Note::serialize_content(self.note); + let serialized_note: [Field; N] = self.note.serialize_content(); let mut buffer_slice: [u8] = &[]; let storage_slot_bytes = self.storage_slot.to_be_bytes(32); let note_type_id_bytes = self.note_type_id.to_be_bytes(32); - for _ in 0..(serialized_note.len() * 32 + 64) { - buffer_slice = buffer_slice.push_back(0); - } - for i in 0..32 { buffer_slice = buffer_slice.push_back(storage_slot_bytes[i]); } @@ -112,7 +106,6 @@ mod test { pub fn new(address: AztecAddress, owner: AztecAddress, randomness: Field) -> Self { AddressNote { address, owner, randomness, header: NoteHeader::empty() } } - // docs:end:address_note_def } #[test] @@ -139,10 +132,12 @@ mod test { let ciphertext = body.compute_ciphertext(secret, point); let expected_body_ciphertext = [ - 131, 119, 105, 129, 244, 32, 151, 205, 12, 99, 93, 62, 10, 180, 72, 21, 36, 194, 14, 168, 0, 137, 126, 59, 151, 177, 136, 254, 153, 190, 92, 33, 40, 151, 178, 54, 34, 166, 124, 96, 117, 108, 168, 7, 147, 222, 81, 201, 254, 170, 244, 151, 60, 64, 226, 45, 156, 185, 53, 23, 121, 63, 243, 101, 134, 21, 167, 39, 226, 203, 162, 223, 28, 74, 244, 159, 54, 201, 192, 168, 19, 85, 103, 82, 148, 3, 153, 210, 89, 245, 171, 171, 12, 248, 40, 74, 199, 65, 96, 42, 84, 83, 48, 21, 188, 134, 45, 247, 134, 166, 109, 170, 68, 212, 99, 235, 74, 202, 162, 108, 130, 128, 122, 16, 79, 242, 30, 157, 26, 75, 57, 24, 18, 124, 217, 74, 155, 13, 171, 205, 194, 193, 103, 134, 224, 204, 46, 105, 135, 166, 192, 163, 186, 42, 71, 51, 156, 161, 8, 131, 233, 228, 107, 151, 254, 111, 215, 19, 22, 34, 252, 158, 214, 97, 197, 22 + 131, 119, 105, 129, 244, 32, 151, 205, 12, 99, 93, 62, 10, 180, 72, 21, 47, 232, 95, 17, 240, 230, 80, 129, 174, 158, 23, 76, 114, 185, 43, 18, 254, 148, 147, 230, 66, 216, 167, 62, 180, 213, 238, 33, 108, 29, 84, 139, 99, 206, 212, 253, 92, 116, 137, 31, 0, 104, 45, 91, 250, 109, 141, 114, 189, 53, 35, 60, 108, 156, 170, 206, 150, 114, 150, 187, 198, 13, 62, 153, 133, 13, 169, 167, 242, 221, 40, 168, 186, 203, 104, 82, 47, 238, 142, 179, 90, 37, 9, 70, 245, 176, 122, 247, 42, 87, 75, 7, 20, 89, 166, 123, 14, 26, 230, 156, 49, 94, 0, 94, 72, 58, 171, 239, 115, 174, 155, 7, 151, 17, 60, 206, 193, 134, 70, 87, 215, 88, 21, 194, 63, 26, 106, 105, 124, 213, 252, 152, 192, 71, 115, 13, 181, 5, 169, 15, 170, 196, 174, 228, 170, 192, 91, 76, 110, 220, 89, 47, 248, 144, 189, 251, 167, 149, 248, 226 ]; - for i in 0..ciphertext.len() { + + for i in 0..expected_body_ciphertext.len() { assert_eq(ciphertext[i], expected_body_ciphertext[i]); } + assert_eq(expected_body_ciphertext.len(), ciphertext.len()); } } diff --git a/noir-projects/aztec-nr/aztec/src/encrypted_logs/header.nr b/noir-projects/aztec-nr/aztec/src/encrypted_logs/header.nr index 9ca749384c1..04f6eb59691 100644 --- a/noir-projects/aztec-nr/aztec/src/encrypted_logs/header.nr +++ b/noir-projects/aztec-nr/aztec/src/encrypted_logs/header.nr @@ -2,7 +2,7 @@ use dep::protocol_types::{address::AztecAddress, grumpkin_private_key::GrumpkinP use crate::keys::point_to_symmetric_key::point_to_symmetric_key; -use dep::std::aes128::aes128_encrypt; +use dep::std::aes128::aes128_encrypt_slice; struct EncryptedLogHeader { address: AztecAddress, @@ -24,8 +24,8 @@ impl EncryptedLogHeader { iv[i] = full_key[i + 16]; } - let input: [u8; 32] = self.address.to_field().to_be_bytes(32).as_array(); - aes128_encrypt(input, iv, sym_key).as_array() + let input: [u8] = self.address.to_field().to_be_bytes(32); + aes128_encrypt_slice(input, iv, sym_key).as_array() } } @@ -44,7 +44,9 @@ fn test_encrypted_log_header() { let ciphertext = header.compute_ciphertext(secret, point); - let expected_header_ciphertext = [131,119,105,129,244,32,151,205,12,99,93,62,10,180,72,21,179,36,250,95,56,167,171,16,195,164,223,57,75,5,24,119,198,34,99,189,193,183,227,43,79,204,214,89,221,153,246,64]; + let expected_header_ciphertext = [ + 131, 119, 105, 129, 244, 32, 151, 205, 12, 99, 93, 62, 10, 180, 72, 21, 179, 36, 250, 95, 56, 167, 171, 16, 195, 164, 223, 57, 75, 5, 24, 119, 198, 34, 99, 189, 193, 183, 227, 43, 79, 204, 214, 89, 221, 153, 246, 64 + ]; assert_eq(ciphertext, expected_header_ciphertext); } diff --git a/noir-projects/noir-contracts/contracts/test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test_contract/src/main.nr index 5ab03eabf18..97210ff7b09 100644 --- a/noir-projects/noir-contracts/contracts/test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test_contract/src/main.nr @@ -337,7 +337,7 @@ contract Test { } #[aztec(private)] - fn encrypt(input: [u8; 64], iv: [u8; 16], key: [u8; 16]) -> [u8; 64] { + fn encrypt(input: [u8; 64], iv: [u8; 16], key: [u8; 16]) -> [u8; 80] { aes128_encrypt(input, iv, key) } @@ -347,20 +347,20 @@ contract Test { } #[aztec(private)] - fn compute_note_header_ciphertext(secret: GrumpkinPrivateKey, point: GrumpkinPoint) -> [u8; 32] { + fn compute_note_header_ciphertext(secret: GrumpkinPrivateKey, point: GrumpkinPoint) -> [u8; 48] { EncryptedLogHeader::new(context.this_address()).compute_ciphertext(secret, point) } - // 64 bytes + 32 * #fields = 96 bytes + // 64 bytes + 32 * #fields + 16 = 112 bytes #[aztec(private)] fn compute_note_body_ciphertext( secret: GrumpkinPrivateKey, point: GrumpkinPoint, storage_slot: Field, value: Field - ) -> [u8; 96] { + ) -> [u8; 112] { let note = TestNote::new(value); - EncryptedLogBody::new(storage_slot, TestNote::get_note_type_id(), note).compute_ciphertext(secret, point) + EncryptedLogBody::new(storage_slot, TestNote::get_note_type_id(), note).compute_ciphertext(secret, point).as_array() } #[aztec(public)] diff --git a/yarn-project/circuit-types/src/logs/encrypted_log_body.test.ts b/yarn-project/circuit-types/src/logs/encrypted_log_body.test.ts index 170c26078b5..db814bc0d98 100644 --- a/yarn-project/circuit-types/src/logs/encrypted_log_body.test.ts +++ b/yarn-project/circuit-types/src/logs/encrypted_log_body.test.ts @@ -47,7 +47,7 @@ describe('encrypt log body', () => { const noteTypeId = new Fr(1); const storageSlot = new Fr(2); - const body = new EncryptedLogBody(noteTypeId, storageSlot, note); + const body = new EncryptedLogBody(storageSlot, noteTypeId, note); const encrypted = body.computeCiphertext(ephSecretKey, viewingPubKey); From d22b55b6f109e4a054d5bca4e8395d85a818a96d Mon Sep 17 00:00:00 2001 From: LHerskind Date: Wed, 8 May 2024 13:24:42 +0000 Subject: [PATCH 4/5] chore: pad and unpad BB --- .../barretenberg/crypto/aes128/index.test.ts | 25 ++++++++++++++++--- .../src/barretenberg/crypto/aes128/index.ts | 10 ++++---- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/yarn-project/circuits.js/src/barretenberg/crypto/aes128/index.test.ts b/yarn-project/circuits.js/src/barretenberg/crypto/aes128/index.test.ts index 9b8afc328e2..933164c3dc7 100644 --- a/yarn-project/circuits.js/src/barretenberg/crypto/aes128/index.test.ts +++ b/yarn-project/circuits.js/src/barretenberg/crypto/aes128/index.test.ts @@ -9,14 +9,31 @@ describe('aes128', () => { aes128 = new Aes128(); }); + // PKCS#7 padding + const pad = (data: Buffer): Buffer => { + const rawLength = data.length; + const numPaddingBytes = 16 - (rawLength % 16); + const paddingBuffer = Buffer.alloc(numPaddingBytes); + paddingBuffer.fill(numPaddingBytes); + return Buffer.concat([data, paddingBuffer]); + }; + + // PKCS#7 padding removal + const removePadding = (paddedBuffer: Buffer): Buffer => { + const paddingToRemove = paddedBuffer[paddedBuffer.length - 1]; + return paddedBuffer.subarray(0, paddedBuffer.length - paddingToRemove); + }; + it('should correctly encrypt input', () => { const data = randomBytes(32); const key = randomBytes(16); const iv = randomBytes(16); + const paddedData = pad(data); + const cipher = createCipheriv('aes-128-cbc', key, iv); cipher.setAutoPadding(false); - const expected = Buffer.concat([cipher.update(data), cipher.final()]); + const expected = Buffer.concat([cipher.update(paddedData), cipher.final()]); const result: Buffer = aes128.encryptBufferCBC(data, iv, key); @@ -28,13 +45,15 @@ describe('aes128', () => { const key = randomBytes(16); const iv = randomBytes(16); + const paddedData = pad(data); + const cipher = createCipheriv('aes-128-cbc', key, iv); cipher.setAutoPadding(false); - const ciphertext = Buffer.concat([cipher.update(data), cipher.final()]); + const ciphertext = Buffer.concat([cipher.update(paddedData), cipher.final()]); const decipher = createDecipheriv('aes-128-cbc', key, iv); decipher.setAutoPadding(false); - const expected = Buffer.concat([decipher.update(ciphertext), decipher.final()]); + const expected = removePadding(Buffer.concat([decipher.update(ciphertext), decipher.final()])); const result: Buffer = aes128.decryptBufferCBC(ciphertext, iv, key); diff --git a/yarn-project/circuits.js/src/barretenberg/crypto/aes128/index.ts b/yarn-project/circuits.js/src/barretenberg/crypto/aes128/index.ts index 29456dff3a0..824e83b4b7e 100644 --- a/yarn-project/circuits.js/src/barretenberg/crypto/aes128/index.ts +++ b/yarn-project/circuits.js/src/barretenberg/crypto/aes128/index.ts @@ -17,11 +17,9 @@ export class Aes128 { const rawLength = data.length; const numPaddingBytes = 16 - (rawLength % 16); const paddingBuffer = Buffer.alloc(numPaddingBytes); - // input num bytes needs to be a multiple of 16 + // input num bytes needs to be a multiple of 16 and at least 1 byte // node uses PKCS#7-Padding scheme, where padding byte value = the number of padding bytes - if (numPaddingBytes != 0) { - paddingBuffer.fill(numPaddingBytes); - } + paddingBuffer.fill(numPaddingBytes); const input = Buffer.concat([data, paddingBuffer]); const api = BarretenbergSync.getSingleton(); @@ -39,8 +37,10 @@ export class Aes128 { */ public decryptBufferCBC(data: Uint8Array, iv: Uint8Array, key: Uint8Array) { const api = BarretenbergSync.getSingleton(); - return Buffer.from( + const paddedBuffer = Buffer.from( api.aesDecryptBufferCbc(new RawBuffer(data), new RawBuffer(iv), new RawBuffer(key), data.length), ); + const paddingToRemove = paddedBuffer[paddedBuffer.length - 1]; + return paddedBuffer.subarray(0, paddedBuffer.length - paddingToRemove); } } From 3d33fe37cae40425d10c3170c5eba88684c46977 Mon Sep 17 00:00:00 2001 From: Lasse Herskind <16536249+LHerskind@users.noreply.github.com> Date: Thu, 9 May 2024 08:04:40 +0100 Subject: [PATCH 5/5] Update yarn-project/circuits.js/src/barretenberg/crypto/aes128/index.test.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jan Beneš --- .../circuits.js/src/barretenberg/crypto/aes128/index.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/yarn-project/circuits.js/src/barretenberg/crypto/aes128/index.test.ts b/yarn-project/circuits.js/src/barretenberg/crypto/aes128/index.test.ts index 933164c3dc7..2f6ca3d5e94 100644 --- a/yarn-project/circuits.js/src/barretenberg/crypto/aes128/index.test.ts +++ b/yarn-project/circuits.js/src/barretenberg/crypto/aes128/index.test.ts @@ -20,6 +20,8 @@ describe('aes128', () => { // PKCS#7 padding removal const removePadding = (paddedBuffer: Buffer): Buffer => { + // We get padding length from the last byte - in PKCS#7 all the padded bytes contain padding length + // and there is always some padding. const paddingToRemove = paddedBuffer[paddedBuffer.length - 1]; return paddedBuffer.subarray(0, paddedBuffer.length - paddingToRemove); };