Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: passing partial note logs through transient storage #9356

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{
context::PrivateContext, encrypted_logs::payload::compute_encrypted_log,
context::PrivateContext, encrypted_logs::payload::compute_private_log_payload,
event::event_interface::EventInterface, keys::getters::get_ovsk_app, oracle::random::random,
};
use dep::protocol_types::{
Expand All @@ -8,7 +8,8 @@ use dep::protocol_types::{
public_keys::{IvpkM, OvpkM},
};

fn compute_raw_event_log<Event, let N: u32>(
/// Computes private event log payload and a log hash
fn compute_payload_and_hash<Event, let N: u32>(
context: PrivateContext,
event: Event,
randomness: Field,
Expand All @@ -22,13 +23,22 @@ where
{
let contract_address: AztecAddress = context.this_address();
let plaintext = event.private_to_be_bytes(randomness);
let encrypted_log: [u8; 416 + N * 32] =
compute_encrypted_log(contract_address, ovsk_app, ovpk, ivpk, recipient, plaintext);

// For event logs we never include public values prefix as there are never any public values
let encrypted_log: [u8; 416 + N * 32] = compute_private_log_payload(
contract_address,
ovsk_app,
ovpk,
ivpk,
recipient,
plaintext,
false,
);
let log_hash = sha256_to_field(encrypted_log);
(encrypted_log, log_hash)
}

unconstrained fn compute_raw_event_log_unconstrained<Event, let N: u32>(
unconstrained fn compute_payload_and_hash_unconstrained<Event, let N: u32>(
context: PrivateContext,
event: Event,
randomness: Field,
Expand All @@ -40,7 +50,7 @@ where
Event: EventInterface<N>,
{
let ovsk_app = get_ovsk_app(ovpk.hash());
compute_raw_event_log(context, event, randomness, ovsk_app, ovpk, ivpk, recipient)
compute_payload_and_hash(context, event, randomness, ovsk_app, ovpk, ivpk, recipient)
}

pub fn encode_and_encrypt_event<Event, let N: u32>(
Expand All @@ -60,7 +70,7 @@ where
let randomness = unsafe { random() };
let ovsk_app: Field = context.request_ovsk_app(ovpk.hash());
let (encrypted_log, log_hash) =
compute_raw_event_log(*context, e, randomness, ovsk_app, ovpk, ivpk, recipient);
compute_payload_and_hash(*context, e, randomness, ovsk_app, ovpk, ivpk, recipient);
context.emit_raw_event_log_with_masked_address(randomness, encrypted_log, log_hash);
}
}
Expand All @@ -81,7 +91,7 @@ where
// value generation.
let randomness = unsafe { random() };
let (encrypted_log, log_hash) = unsafe {
compute_raw_event_log_unconstrained(*context, e, randomness, ovpk, ivpk, recipient)
compute_payload_and_hash_unconstrained(*context, e, randomness, ovpk, ivpk, recipient)
};
context.emit_raw_event_log_with_masked_address(randomness, encrypted_log, log_hash);
}
Expand All @@ -103,7 +113,7 @@ where
|e: Event| {
let ovsk_app: Field = context.request_ovsk_app(ovpk.hash());
let (encrypted_log, log_hash) =
compute_raw_event_log(*context, e, randomness, ovsk_app, ovpk, ivpk, recipient);
compute_payload_and_hash(*context, e, randomness, ovsk_app, ovpk, ivpk, recipient);
context.emit_raw_event_log_with_masked_address(randomness, encrypted_log, log_hash);
}
}
Expand Down Expand Up @@ -134,7 +144,7 @@ where
// return the log from this function to the app, otherwise it could try to do stuff with it and then that might
// be wrong.
let (encrypted_log, log_hash) = unsafe {
compute_raw_event_log_unconstrained(*context, e, randomness, ovpk, ivpk, recipient)
compute_payload_and_hash_unconstrained(*context, e, randomness, ovpk, ivpk, recipient)
};
context.emit_raw_event_log_with_masked_address(randomness, encrypted_log, log_hash);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
context::PrivateContext,
encrypted_logs::payload::compute_encrypted_log,
encrypted_logs::payload::compute_private_log_payload,
keys::getters::get_ovsk_app,
note::{note_emission::NoteEmission, note_interface::NoteInterface},
};
Expand All @@ -11,14 +11,15 @@ use dep::protocol_types::{
public_keys::{IvpkM, OvpkM, PublicKeys},
};

fn compute_raw_note_log<Note, let N: u32>(
/// Computes private note log payload and a log hash
fn compute_payload_and_hash<Note, let N: u32>(
context: PrivateContext,
note: Note,
ovsk_app: Field,
ovpk: OvpkM,
ivpk: IvpkM,
recipient: AztecAddress,
) -> (u32, [u8; 416 + N * 32], Field)
) -> (u32, [u8; 417 + N * 32], Field)
nventuro marked this conversation as resolved.
Show resolved Hide resolved
where
Note: NoteInterface<N>,
{
Expand All @@ -33,25 +34,34 @@ where
let contract_address: AztecAddress = context.this_address();

let plaintext = note.to_be_bytes(storage_slot);
let encrypted_log: [u8; 416 + N * 32] =
compute_encrypted_log(contract_address, ovsk_app, ovpk, ivpk, recipient, plaintext);

// For note logs we always include public values prefix
let encrypted_log: [u8; 417 + N * 32] = compute_private_log_payload(
contract_address,
ovsk_app,
ovpk,
ivpk,
recipient,
plaintext,
true,
);
let log_hash = sha256_to_field(encrypted_log);

(note_hash_counter, encrypted_log, log_hash)
}

unconstrained fn compute_raw_note_log_unconstrained<Note, let N: u32>(
unconstrained fn compute_payload_and_hash_unconstrained<Note, let N: u32>(
context: PrivateContext,
note: Note,
ovpk: OvpkM,
ivpk: IvpkM,
recipient: AztecAddress,
) -> (u32, [u8; 416 + N * 32], Field)
) -> (u32, [u8; 417 + N * 32], Field)
where
Note: NoteInterface<N>,
{
let ovsk_app = get_ovsk_app(ovpk.hash());
compute_raw_note_log(context, note, ovsk_app, ovpk, ivpk, recipient)
compute_payload_and_hash(context, note, ovsk_app, ovpk, ivpk, recipient)
}

// This function seems to be affected by the following Noir bug:
Expand All @@ -70,7 +80,7 @@ where
let ovsk_app: Field = context.request_ovsk_app(ovpk.hash());

let (note_hash_counter, encrypted_log, log_hash) =
compute_raw_note_log(*context, e.note, ovsk_app, ovpk, ivpk, recipient);
compute_payload_and_hash(*context, e.note, ovsk_app, ovpk, ivpk, recipient);
context.emit_raw_note_log(note_hash_counter, encrypted_log, log_hash);
}
}
Expand Down Expand Up @@ -104,38 +114,9 @@ where
// for the log to be deleted when it shouldn't have (which is fine - they can already make the content be
// whatever), or cause for the log to not be deleted when it should have (which is also fine - it'll be a log
// for a note that doesn't exist).
let (note_hash_counter, encrypted_log, log_hash) =
unsafe { compute_raw_note_log_unconstrained(*context, e.note, ovpk, ivpk, recipient) };
let (note_hash_counter, encrypted_log, log_hash) = unsafe {
compute_payload_and_hash_unconstrained(*context, e.note, ovpk, ivpk, recipient)
};
context.emit_raw_note_log(note_hash_counter, encrypted_log, log_hash);
}
}

nventuro marked this conversation as resolved.
Show resolved Hide resolved
/// Encrypts a partial log and emits it. Takes recipient keys on the input and encrypts both the outgoing and incoming
/// logs for the recipient. This is necessary because in the partial notes flow the outgoing always has to be the same
/// as the incoming to not leak any information (typically the `from` party finalizing the partial note in public does
/// not know who the recipient is).
pub fn encrypt_and_emit_partial_log<let M: u32>(
context: &mut PrivateContext,
log_plaintext: [u8; M],
recipient_keys: PublicKeys,
recipient: AztecAddress,
) {
let ovsk_app: Field = context.request_ovsk_app(recipient_keys.ovpk_m.hash());

let encrypted_log: [u8; 352 + M] = compute_encrypted_log(
context.this_address(),
ovsk_app,
recipient_keys.ovpk_m,
recipient_keys.ivpk_m,
recipient,
log_plaintext,
);
let log_hash = sha256_to_field(encrypted_log);

// Unfortunately we need to push a dummy note hash to the context here because a note log requires having
// a counter that corresponds to a note hash in the same call.
let note_hash_counter = context.side_effect_counter;
context.push_note_hash(5);

context.emit_raw_note_log(note_hash_counter, encrypted_log, log_hash);
}
33 changes: 24 additions & 9 deletions noir-projects/aztec-nr/aztec/src/encrypted_logs/payload.nr
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@ use crate::{
utils::point::point_to_bytes,
};

pub fn compute_encrypted_log<let P: u32, let M: u32>(
fn compute_private_log_payload<let P: u32, let M: u32>(
contract_address: AztecAddress,
ovsk_app: Field,
ovpk: OvpkM,
ivpk: IvpkM,
recipient: AztecAddress,
plaintext: [u8; P],
include_public_values_prefix: bool,
) -> [u8; M] {
let (eph_sk, eph_pk) = generate_ephemeral_key_pair();

Expand All @@ -41,27 +42,39 @@ pub fn compute_encrypted_log<let P: u32, let M: u32>(
eph_pk,
);

// If we include the prefix for number of public values, we need to add 1 byte to the offset
let mut offset = if include_public_values_prefix { 1 } else { 0 };

let mut encrypted_bytes: [u8; M] = [0; M];
// @todo We ignore the tags for now
offset += 64;

let eph_pk_bytes = point_to_bytes(eph_pk);
for i in 0..32 {
encrypted_bytes[64 + i] = eph_pk_bytes[i];
encrypted_bytes[offset + i] = eph_pk_bytes[i];
}

offset += 32;
for i in 0..48 {
encrypted_bytes[96 + i] = incoming_header_ciphertext[i];
encrypted_bytes[144 + i] = outgoing_header_ciphertext[i];
encrypted_bytes[offset + i] = incoming_header_ciphertext[i];
encrypted_bytes[offset + 48 + i] = outgoing_header_ciphertext[i];
}

offset += 48 * 2;
for i in 0..144 {
encrypted_bytes[192 + i] = outgoing_body_ciphertext[i];
encrypted_bytes[offset + i] = outgoing_body_ciphertext[i];
}

offset += 144;
// Then we fill in the rest as the incoming body ciphertext
let size = M - 336;
let size = M - offset;
assert_eq(size, incoming_body_ciphertext.len(), "ciphertext length mismatch");
for i in 0..size {
encrypted_bytes[336 + i] = incoming_body_ciphertext[i];
encrypted_bytes[offset + i] = incoming_body_ciphertext[i];
}

// Current unoptimized size of the encrypted log
// empty_prefix (1 byte)
// incoming_tag (32 bytes)
// outgoing_tag (32 bytes)
// eph_pk (32 bytes)
Expand Down Expand Up @@ -160,7 +173,8 @@ pub fn compute_outgoing_body_ciphertext(

mod test {
use crate::encrypted_logs::payload::{
compute_encrypted_log, compute_incoming_body_ciphertext, compute_outgoing_body_ciphertext,
compute_incoming_body_ciphertext, compute_outgoing_body_ciphertext,
compute_private_log_payload,
};
use dep::protocol_types::{
address::AztecAddress,
Expand Down Expand Up @@ -210,13 +224,14 @@ mod test {
0x25afb798ea6d0b8c1618e50fdeafa463059415013d3b7c75d46abf5e242be70c,
);

let log: [u8; 448] = compute_encrypted_log(
let log: [u8; 448] = compute_private_log_payload(
contract_address,
ovsk_app,
ovpk_m,
ivpk_m,
recipient,
plaintext,
false,
);

// The following value was generated by `tagged_log.test.ts`
Expand Down
Loading
Loading