Skip to content

Commit

Permalink
feat: Update the encrypted note log format (AztecProtocol#6411)
Browse files Browse the repository at this point in the history
Fixes AztecProtocol#5901. 

Uses the new format to match the keys and logs spec. The current
implementation here is still using a typescript implementation to
encrypt the data, mainly using the new flow.

The intention is that AztecProtocol#6408 and AztecProtocol#1139 can be addresses separately and
than we can just replace the import to use the constrained version
instead of the oracle at that point.

Note, that the outgoing logs are currently less than meaningful, as some
of the infrastructure is not yet in place to handle those nicely, see
AztecProtocol#6410 for more on that.

What was called the encrypted_log_payload in AztecProtocol#6348 have been moved into
the l1_payload, to better integrate with the rest of the setup.
  • Loading branch information
LHerskind authored May 18, 2024
1 parent 2202e8d commit e5cc9dc
Show file tree
Hide file tree
Showing 40 changed files with 505 additions and 608 deletions.
10 changes: 5 additions & 5 deletions l1-contracts/test/fixtures/empty_block_0.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"l2ToL1Messages": []
},
"block": {
"archive": "0x12a6236f076e51298ca7c5c4d0c9898239c5f829e1f2673a18a922d5ee50a4fd",
"archive": "0x0ed815d35918f1aabf391fa174a1d95476da157e40b7fc581b2c8f4cfd23e6b3",
"body": "0x00000000",
"txsEffectsHash": "0x002676dbd818b1ba16e11597cb5c07b06aa7771127b02a77d0c3a6039bb9fef1",
"decodedHeader": {
Expand All @@ -23,8 +23,8 @@
"chainId": 31337,
"timestamp": 0,
"version": 1,
"coinbase": "0xf98794b6b717c6c7d6806a8ebb8cb1327144f0c7",
"feeRecipient": "0x1eece2f228c0b199fee7bb461e152e69a6ddd096573bd8ea45a7df0e105439a4",
"coinbase": "0xbe70f89d75a00bd140342ebc63beb517cf9735bc",
"feeRecipient": "0x08eb6120958820f4b4fd61a9bcaa32c33349663034e1db315ba57c67d155b172",
"gasFees": {
"feePerDaGas": 0,
"feePerL2Gas": 0
Expand Down Expand Up @@ -55,8 +55,8 @@
}
}
},
"header": "0x067a48e3140b6f15d71751ededfa0cccde3d436bb71aa7fec226b0bfe51dc5cf000000010000000000000000000000000000000000000000000000000000000000000001002676dbd818b1ba16e11597cb5c07b06aa7771127b02a77d0c3a6039bb9fef100089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c0007638bb56b6dda2b64b8f76841114ac3a87a1820030e2e16772c4d294879c31864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f800000001016642d9ccd8346c403aa4c3fa451178b22534a27035cdaa6ec34ae53b29c50cb000000800bcfa3e9f1a8922ee92c6dc964d6595907c1804a86753774322b468f69d4f278000001000572c8db882674dd026b8877fbba1b700a4407da3ae9ce5fa43215a28163362b000000800000000000000000000000000000000000000000000000000000000000007a69000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000f98794b6b717c6c7d6806a8ebb8cb1327144f0c71eece2f228c0b199fee7bb461e152e69a6ddd096573bd8ea45a7df0e105439a400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"publicInputsHash": "0x0081ff51b8e6caf79d8d0616b407a5cf7c3d939bf568a94100d6e7b5dbaf2cff",
"header": "0x067a48e3140b6f15d71751ededfa0cccde3d436bb71aa7fec226b0bfe51dc5cf000000010000000000000000000000000000000000000000000000000000000000000001002676dbd818b1ba16e11597cb5c07b06aa7771127b02a77d0c3a6039bb9fef100089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c0007638bb56b6dda2b64b8f76841114ac3a87a1820030e2e16772c4d294879c31864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f800000001016642d9ccd8346c403aa4c3fa451178b22534a27035cdaa6ec34ae53b29c50cb000000800bcfa3e9f1a8922ee92c6dc964d6595907c1804a86753774322b468f69d4f278000001000572c8db882674dd026b8877fbba1b700a4407da3ae9ce5fa43215a28163362b000000800000000000000000000000000000000000000000000000000000000000007a69000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000be70f89d75a00bd140342ebc63beb517cf9735bc08eb6120958820f4b4fd61a9bcaa32c33349663034e1db315ba57c67d155b17200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"publicInputsHash": "0x00e9c95b88dbc49351e6a0a9b660918147d3c69410df4fba105c047a4f253a47",
"numTxs": 0
}
}
14 changes: 7 additions & 7 deletions l1-contracts/test/fixtures/empty_block_1.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"l2ToL1Messages": []
},
"block": {
"archive": "0x19d445841fdaa62cfa9752aae068322e538729535b9fc4e195fd4e7b010f2e91",
"archive": "0x18c171439670152671eb523cdf11eb61a45c27b7685ad86a7229fbe635e9ea18",
"body": "0x00000000",
"txsEffectsHash": "0x002676dbd818b1ba16e11597cb5c07b06aa7771127b02a77d0c3a6039bb9fef1",
"decodedHeader": {
Expand All @@ -21,18 +21,18 @@
"globalVariables": {
"blockNumber": 2,
"chainId": 31337,
"timestamp": 1715940661,
"timestamp": 1716042415,
"version": 1,
"coinbase": "0xf98794b6b717c6c7d6806a8ebb8cb1327144f0c7",
"feeRecipient": "0x1eece2f228c0b199fee7bb461e152e69a6ddd096573bd8ea45a7df0e105439a4",
"coinbase": "0xbe70f89d75a00bd140342ebc63beb517cf9735bc",
"feeRecipient": "0x08eb6120958820f4b4fd61a9bcaa32c33349663034e1db315ba57c67d155b172",
"gasFees": {
"feePerDaGas": 0,
"feePerL2Gas": 0
}
},
"lastArchive": {
"nextAvailableLeafIndex": 2,
"root": "0x12a6236f076e51298ca7c5c4d0c9898239c5f829e1f2673a18a922d5ee50a4fd"
"root": "0x0ed815d35918f1aabf391fa174a1d95476da157e40b7fc581b2c8f4cfd23e6b3"
},
"stateReference": {
"l1ToL2MessageTree": {
Expand All @@ -55,8 +55,8 @@
}
}
},
"header": "0x12a6236f076e51298ca7c5c4d0c9898239c5f829e1f2673a18a922d5ee50a4fd000000020000000000000000000000000000000000000000000000000000000000000001002676dbd818b1ba16e11597cb5c07b06aa7771127b02a77d0c3a6039bb9fef100089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c0007638bb56b6dda2b64b8f76841114ac3a87a1820030e2e16772c4d294879c31864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f800000002016642d9ccd8346c403aa4c3fa451178b22534a27035cdaa6ec34ae53b29c50cb000001000bcfa3e9f1a8922ee92c6dc964d6595907c1804a86753774322b468f69d4f278000001800572c8db882674dd026b8877fbba1b700a4407da3ae9ce5fa43215a28163362b000000c00000000000000000000000000000000000000000000000000000000000007a69000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000066472d35f98794b6b717c6c7d6806a8ebb8cb1327144f0c71eece2f228c0b199fee7bb461e152e69a6ddd096573bd8ea45a7df0e105439a400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"publicInputsHash": "0x008568ca7fc6464f9cb6588e7215e14e0eb49c96dd210a849a0d3369d185c261",
"header": "0x0ed815d35918f1aabf391fa174a1d95476da157e40b7fc581b2c8f4cfd23e6b3000000020000000000000000000000000000000000000000000000000000000000000001002676dbd818b1ba16e11597cb5c07b06aa7771127b02a77d0c3a6039bb9fef100089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c0007638bb56b6dda2b64b8f76841114ac3a87a1820030e2e16772c4d294879c31864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f800000002016642d9ccd8346c403aa4c3fa451178b22534a27035cdaa6ec34ae53b29c50cb000001000bcfa3e9f1a8922ee92c6dc964d6595907c1804a86753774322b468f69d4f278000001800572c8db882674dd026b8877fbba1b700a4407da3ae9ce5fa43215a28163362b000000c00000000000000000000000000000000000000000000000000000000000007a6900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000006648baafbe70f89d75a00bd140342ebc63beb517cf9735bc08eb6120958820f4b4fd61a9bcaa32c33349663034e1db315ba57c67d155b17200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"publicInputsHash": "0x0033d4785f37dafeeb7e50eeef42002f0af7d1d62913119754b81cfe7ebc5217",
"numTxs": 0
}
}
10 changes: 5 additions & 5 deletions l1-contracts/test/fixtures/mixed_block_0.json

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions l1-contracts/test/fixtures/mixed_block_1.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion noir-projects/aztec-nr/address-note/src/address_note.nr
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ impl NoteInterface<ADDRESS_NOTE_LEN> for AddressNote {
// Broadcasts the note as an encrypted log on L1.
fn broadcast(self, context: &mut PrivateContext, slot: Field, ivpk_m: GrumpkinPoint) {
// docs:start:encrypted
context.emit_note_encrypted_log(
context.encrypt_and_emit_note(
(*context).this_address(),
slot,
Self::get_note_type_id(),
Expand Down
69 changes: 34 additions & 35 deletions noir-projects/aztec-nr/aztec/src/context/private_context.nr
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
use crate::{
context::{inputs::PrivateContextInputs, interface::ContextInterface},
messaging::process_l1_to_l2_message,
hash::{hash_args_array, ArgsHasher, compute_encrypted_log_hash, compute_unencrypted_log_hash},
hash::{hash_args_array, ArgsHasher, compute_unencrypted_log_hash},
note::{note_interface::NoteInterface, utils::compute_note_hash_for_insertion},
oracle::{
nullifier_keys::get_nullifier_key_validation_request, arguments, returns,
call_private_function::call_private_function_internal, header::get_header_at,
logs::emit_encrypted_log, logs_traits::{LensForEncryptedLog, ToBytesForUnencryptedLog},
logs::{emit_encrypted_log, emit_encrypted_note_log, compute_encrypted_log},
logs_traits::{LensForEncryptedLog, ToBytesForUnencryptedLog},
enqueue_public_function_call::{
enqueue_public_function_call_internal, set_public_teardown_function_call_internal,
parse_public_call_stack_item_from_oracle
}
}
};
use dep::protocol_types::{
hash::sha256_to_field,
abis::{
function_selector::FunctionSelector, max_block_number::MaxBlockNumber,
nullifier_key_validation_request::NullifierKeyValidationRequest,
Expand Down Expand Up @@ -281,42 +283,34 @@ impl PrivateContext {
let side_effect = LogHash { value: log_hash, counter, length: len };
self.unencrypted_logs_hashes.push(side_effect);
}
// TODO(1139): Convert to generic input once we encrypt inside the circuit
pub fn emit_encrypted_log<N, M, L>(

pub fn encrypt_and_emit_log<N, M>(
&mut self,
contract_address: AztecAddress,
storage_slot: Field,
note_type_id: Field,
ivpk_m: GrumpkinPoint,
preimage: [Field; N]
) where [Field; N]: LensForEncryptedLog<N, M, L> {
// TODO(1139): perform encryption in the circuit
// The oracle call should come last, but we require the encrypted value for now
) where [Field; N]: LensForEncryptedLog<N, M> {
// We are currently just encrypting it EXACTLY the same way as if it was a note.
let counter = self.next_counter();
let encrypted_log: [Field; M] = emit_encrypted_log(
contract_address,
storage_slot,
note_type_id,
ivpk_m,
preimage,
counter
);
// = 32*all fields + bytes for encryption (112) + processed log len (4)
let len = 112 + 32 * (N + 3) + 4;
let log_hash = compute_encrypted_log_hash(encrypted_log);
let encrypted_log: [u8; M] = compute_encrypted_log(contract_address, storage_slot, note_type_id, ivpk_m, preimage);
emit_encrypted_log(encrypted_log, counter);
let len = 32 + 32 + 64 + 48 + 48 + 176 + 64 + (preimage.len() as Field * 32) + 16 + 4;
let log_hash = sha256_to_field(encrypted_log);
let side_effect = LogHash { value: log_hash, counter, length: len };
self.encrypted_logs_hashes.push(side_effect);
}

pub fn emit_note_encrypted_log<Note, N, M, L>(
pub fn encrypt_and_emit_note<Note, N, M>(
&mut self,
contract_address: AztecAddress,
storage_slot: Field,
note_type_id: Field,
encryption_pub_key: GrumpkinPoint,
ivpk_m: GrumpkinPoint,
note: Note
) where Note: NoteInterface<N>, [Field; N]: LensForEncryptedLog<N, M, L> {
let note_hash = compute_note_hash_for_insertion(note);
) where Note: NoteInterface<N>, [Field; N]: LensForEncryptedLog<N, M> {
let note_hash: Field = compute_note_hash_for_insertion(note);
let note_exists_index = find_index(
self.new_note_hashes.storage,
|n: NoteHash| n.value == note_hash
Expand All @@ -327,19 +321,24 @@ impl PrivateContext {
let note_hash_counter = self.new_note_hashes.storage[note_exists_index].counter;
let preimage = note.serialize_content();
let counter = self.next_counter();
// TODO(1139): perform encryption in the circuit
// The oracle call should come last, but we require the encrypted value for now
let encrypted_log: [Field; M] = emit_encrypted_log(
contract_address,
storage_slot,
note_type_id,
encryption_pub_key,
preimage,
counter
);
// = 32*all fields + bytes for encryption (112) + processed log len (4)
let len = 112 + 32 * (preimage.len() as Field + 3) + 4;
let log_hash = compute_encrypted_log_hash(encrypted_log);

// TODO(#1139 | #6408): perform encryption in the circuit
let encrypted_log: [u8; M] = compute_encrypted_log(contract_address, storage_slot, note_type_id, ivpk_m, preimage);
emit_encrypted_note_log(note_hash, encrypted_log, counter);

// Current unoptimized size of the encrypted log
// incoming_tag (32 bytes)
// outgoing_tag (32 bytes)
// eph_pk (64 bytes)
// incoming_header (48 bytes)
// outgoing_header (48 bytes)
// outgoing_body (176 bytes)
// incoming_body_fixed (64 bytes)
// incoming_body_variable (N * 32 bytes + 16 bytes padding)
// len of processed log (4 bytes)
let len = 32 + 32 + 64 + 48 + 48 + 176 + 64 + (preimage.len() as Field * 32) + 16 + 4;

let log_hash = sha256_to_field(encrypted_log);
let side_effect = NoteLogHash { value: log_hash, counter, length: len, note_hash_counter };
self.note_encrypted_logs_hashes.push(side_effect);
}
Expand Down
56 changes: 0 additions & 56 deletions noir-projects/aztec-nr/aztec/src/hash.nr
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,6 @@ pub fn compute_secret_hash(secret: Field) -> Field {
pedersen_hash([secret], GENERATOR_INDEX__SECRET_HASH)
}

pub fn compute_encrypted_log_hash<N, M, L>(encrypted_log: [Field; M]) -> Field where [Field; N]: LensForEncryptedLog<N, M, L> {
let mut bytes = [0; L];
// Note that bytes.append(encrypted_log[i].to_be_bytes(31)) results in bound error
for i in 0..M - 1 {
let to_add = encrypted_log[i].to_be_bytes(31);
for j in 0..31 {
bytes[i*31 + j] = to_add[j];
}
}
// can't assign as L - not in scope error for: L-31*(M-1)
let num_bytes = bytes.len() as u32 - 31 * (M - 1);
let to_add_final = encrypted_log[M - 1].to_be_bytes(num_bytes);
for j in 0..num_bytes {
bytes[(M-1)*31 + j] = to_add_final[j];
}
sha256_to_field(bytes)
}

pub fn compute_unencrypted_log_hash<T, N, M>(
contract_address: AztecAddress,
event_selector: Field,
Expand Down Expand Up @@ -167,44 +149,6 @@ fn compute_var_args_hash() {
assert(hash == 0x05a1023fef839ac88731f49ae983e172c1b600a3c8f3393ad0ac25d819ac0f0f);
}

#[test]
fn compute_enc_log_hash_304() {
let input = [
0x0000000000000000000000000000000000000000000000000000000000000000,
0x0021a0d4aa9989656b592187cf6da1965df53ab2ff2277421e663465cf20d3e9,
0x00c3969cc350f3474f8187a33ac1317181961f5f94043b07ce888d85a5d20cb5,
0x0058198041ed1547b056955b5141a5a8a1551b0c8d094255ec9daaf3604d9348,
0x00247ad96df2e4d984cf795ed7316234743a681f824a45c46253de8bfde48850,
0x007fc251f4ce44f4e9aba3dbf6567228be28fac85660156f2825ddb0b0577457,
0x009315851323c6bc2aaa42e23fe5f3be97208f2d8167eafdfc5742d94f2f4dd4,
0x00b938289e563b0fe01982cd9b8d9e33e3069046768ad01c0fb05e429e7b7909,
0x00fbcc257a3211f705b471eee763b0f43876a2b2178fab6d2b09bd2b7e086584,
0x000000000000008c3289b5793b7448f4d45ecde039d004b6f037cad10b5c2336
];
let hash = compute_encrypted_log_hash(input);
assert(hash == 0x001e3c013994947fe28957a876bf1b2c3a69ac69cc92909efd4f2ae9b972f893);
}

#[test]
fn compute_enc_log_hash_368() {
let input = [
0x0000000000000000000000000000000000000000000000000000000000000000,
0x002190697d2a50e229a7a077e0951073f7d51e46679f10466153c308b63b1ea9,
0x00543e346facc6799b94514c9d461bcc836c04b083b13c2e4544a39130473c1e,
0x000df76d59526f8f953bcc7d9f77cdaefd36435931f0d7348f794bc275b42ded,
0x00a6d390ee1723af7f7ac1ae4fc81a266b2370fe07040a36d06dbe242e02413e,
0x00acbce15b6af1fbe94bd0f7b70f11768265dff77bfe63398f2a053efdfdf26d,
0x00b8b131b9f42c689beb095ba4f4a836d4d15c9068d0422e9add6ca82b786329,
0x00661a6a654b38f0f97d404ef5553e0efea9ed670561ae86685b31bbb2824fac,
0x00113a6b58edfaec0065b365f66ba8d8aa68254b8690035e8d671a17a843f0a1,
0x0023f2d2eae8c4449bac8f268a3e62a3faace1fe1401f0efdc8b0ccfbc8fb271,
0x00cf6603f8c61993dd2f662c719671c61727a2f4e925fb988b23d31feccd77d9,
0x0000000000a402a84b7294671799c38dd805f6a827a3a12633fdf91a57debe1f
];
let hash = compute_encrypted_log_hash(input);
assert(hash == 0x00a0d651ac0cbc01b72430fa6a05d91738595af6e0229347b4c9968223387aeb);
}

#[test]
fn compute_unenc_log_hash_array() {
let contract_address = AztecAddress::from_field(0x233a3e0df23b2b15b324194cb4a151f26c0b7333250781d34cc269d85dc334c6);
Expand Down
46 changes: 27 additions & 19 deletions noir-projects/aztec-nr/aztec/src/oracle/logs.nr
Original file line number Diff line number Diff line change
@@ -1,32 +1,40 @@
use dep::protocol_types::{address::AztecAddress, grumpkin_point::GrumpkinPoint};

// TODO(1139): Should take encrypted data.
// Currently returns encrypted data to be hashed
// = 112 + 32 * (N + 3) bytes = N + 7 fields
// = 480 + 32 * N bytes
#[oracle(emitEncryptedNoteLog)]
fn emit_encrypted_note_log_oracle<M>(_note_hash: Field, _encrypted_note: [u8; M], _counter: u32) {}

unconstrained pub fn emit_encrypted_note_log<M>(
note_hash: Field,
encrypted_note: [u8; M],
counter: u32
) {
emit_encrypted_note_log_oracle(note_hash, encrypted_note, counter)
}

#[oracle(emitEncryptedLog)]
fn emit_encrypted_log_oracle<N, M>(
fn emit_encrypted_log_oracle<M>(_encrypted_note: [u8; M], _counter: u32) {}

unconstrained pub fn emit_encrypted_log<M>(encrypted_note: [u8; M], counter: u32) {
emit_encrypted_log_oracle(encrypted_note, counter)
}

// = 480 + 32 * N bytes
#[oracle(computeEncryptedLog)]
fn compute_encrypted_log_oracle<N, M>(
_contract_address: AztecAddress,
_storage_slot: Field,
_note_type_id: Field,
_encryption_pub_key: GrumpkinPoint,
_preimage: [Field; N],
_counter: u32
) -> [Field; M] {}
_preimage: [Field; N]
) -> [u8; M] {}

unconstrained pub fn emit_encrypted_log<N, M>(
unconstrained pub fn compute_encrypted_log<N, M>(
contract_address: AztecAddress,
storage_slot: Field,
note_type_id: Field,
ivpk_m: GrumpkinPoint,
preimage: [Field; N],
counter: u32
) -> [Field; M] {
emit_encrypted_log_oracle(
contract_address,
storage_slot,
note_type_id,
ivpk_m,
preimage,
counter
)
preimage: [Field; N]
) -> [u8; M] {
compute_encrypted_log_oracle(contract_address, storage_slot, note_type_id, ivpk_m, preimage)
}
Loading

0 comments on commit e5cc9dc

Please sign in to comment.