Skip to content

Commit

Permalink
Merge afa345f into b39f1db
Browse files Browse the repository at this point in the history
  • Loading branch information
MirandaWood authored May 2, 2024
2 parents b39f1db + afa345f commit ecae76f
Show file tree
Hide file tree
Showing 61 changed files with 1,222 additions and 608 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,9 @@ In the future we will allow emitting arbitrary information.
(If you currently emit arbitrary information, PXE will fail to decrypt, process and store this data, so it will not be queryable).
:::

### Import library

To emit encrypted logs first import the `emit_encrypted_log` utility function which wraps an [oracle](../oracles/main.md):

#include_code encrypted_import /noir-projects/aztec-nr/address-note/src/address_note.nr rust

### Call emit_encrypted_log

After importing, you can call the function:
To emit encrypted logs you don't need to import any library. You call the context method `emit_encrypted_log`:

#include_code encrypted /noir-projects/aztec-nr/address-note/src/address_note.nr rust

Expand Down
16 changes: 15 additions & 1 deletion docs/docs/misc/migration_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,20 @@ keywords: [sandbox, cli, aztec, notes, migration, updating, upgrading]

Aztec is in full-speed development. Literally every version breaks compatibility with the previous ones. This page attempts to target errors and difficulties you might encounter when upgrading, and how to resolve them.

## 0.38.0

### [Aztec.nr] Emmiting encrypted logs

The `emit_encrypted_log` function is now a context method.

```diff
- use dep::aztec::log::emit_encrypted_log;
- use dep::aztec::logs::emit_encrypted_log;

- emit_encrypted_log(context, log1);
+ context.emit_encrypted_log(log1);
```

## 0.36.0

### `FieldNote` removed
Expand Down Expand Up @@ -171,7 +185,7 @@ Note that gas limits are not yet enforced. For now, it is suggested you use `dep

Note that this is not required when enqueuing a public function from a private one, since top-level enqueued public functions will always consume all gas available for the transaction, as it is not possible to handle any out-of-gas errors.

### [Aztec.nr] Emmiting unencrypted logs
### [Aztec.nr] Emitting unencrypted logs

The `emit_unencrypted_logs` function is now a context method.

Expand Down
17 changes: 5 additions & 12 deletions docs/docs/protocol-specs/logs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Logs on Aztec are similar to logs on Ethereum, enabling smart contracts to conve

### Hash Function

The protocol uses **SHA256** as the hash function for logs, and then reduces the 256-bit result to 253 bits for representation as a field element.
The protocol uses **SHA256** as the hash function for logs, and then reduces the 256-bit result to 248 bits for representation as a field element.

<!-- TODO: explicitly detail how the truncation is being done, so that we can check that it is secure. -->

Expand Down Expand Up @@ -227,10 +227,7 @@ Following the iterations for all private or public calls, the tail kernel circui

2. Accumulate all the hashes and output the final hash to the public inputs:

- _`accumulated_logs_hash = hash(logs_hash_a, logs_hash_b)`_
- For tail public kernel circuit, it begins with _`accumulated_logs_hash = hash(accumulated_logs_hash, logs_hash_a)`_ if the _accumulated_logs_hash_ outputted from the tail private kernel circuit is not empty.
- _`accumulated_logs_hash = hash(accumulated_logs_hash, logs_hash_c)`_
- Repeat the process until all _logs_hashes_ are collectively hashed.
- `accumulated_logs_hash = hash(log_hash[0], log_hash[1], ..., log_hash[N - 1])` for N logs.

### Encoding

Expand Down Expand Up @@ -273,11 +270,9 @@ After successfully decrypting an encrypted log, one can use the _randomness_ in
- _`log_hash_a = hash(log_hash_a, contract_address_tag_a)`_
- Repeat the process for all _log_hashes_ in the transaction.

2. Accumulate all the hashes and outputs the final hash to the public inputs:
2. Accumulate all the hashes in the tail and outputs the final hash to the public inputs:

- _`accumulated_logs_hash = hash(log_hash_a, log_hash_b)`_
- _`accumulated_logs_hash = hash(accumulated_logs_hash, log_hash_c)`_
- Repeat the process until all _logs_hashes_ are collectively hashed.
- `accumulated_logs_hash = hash(log_hash[0], log_hash[1], ..., log_hash[N - 1])` for N logs, with hashes defined above.

### Encoding

Expand Down Expand Up @@ -310,9 +305,7 @@ As each encrypted note preimage can be associated with a note in the same transa

The kernel circuit simply accumulates all the hashes:

- _`accumulated_logs_hash = hash(log_hash_a, log_hash_b)`_
- _`accumulated_logs_hash = hash(accumulated_logs_hash, log_hash_c)`_
- Repeat the process until all _logs_hashes_ are collectively hashed.
- `accumulated_logs_hash = hash(log_hash[0], log_hash[1], ..., log_hash[N - 1])` for N logs.

### Encoding

Expand Down
19 changes: 16 additions & 3 deletions l1-contracts/src/core/libraries/decoders/TxsDecoder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ library TxsDecoder {
uint256 remainingLogsLength = read4(_body, offset);
offset += 0x4;

bytes32 kernelPublicInputsLogsHash; // The hash on the output of kernel iteration
bytes memory flattenedLogHashes; // The hash input

// Iterate until all the logs were processed
while (remainingLogsLength > 0) {
Expand All @@ -245,13 +245,26 @@ library TxsDecoder {
bytes32 singleLogHash = Hash.sha256ToField(slice(_body, offset, singleCallLogsLength));
offset += singleCallLogsLength;

kernelPublicInputsLogsHash =
Hash.sha256ToField(bytes.concat(kernelPublicInputsLogsHash, singleLogHash));
flattenedLogHashes = bytes.concat(flattenedLogHashes, singleLogHash);

privateCircuitPublicInputLogsLength -= (singleCallLogsLength + 0x4);
}
}

// Not having a 0 value hash for empty logs causes issues with empty txs used for padding.
if (flattenedLogHashes.length == 0) {
return (0, offset);
}

// padded to MAX_LOGS * 32 bytes
// NB: this assumes MAX_ENCRYPTED_LOGS_PER_TX == MAX_UNENCRYPTED_LOGS_PER_TX
flattenedLogHashes = bytes.concat(
flattenedLogHashes,
new bytes(Constants.MAX_ENCRYPTED_LOGS_PER_TX * 32 - flattenedLogHashes.length)
);

bytes32 kernelPublicInputsLogsHash = Hash.sha256ToField(flattenedLogHashes);

return (kernelPublicInputsLogsHash, offset);
}

Expand Down
27 changes: 13 additions & 14 deletions l1-contracts/test/decoders/Decoders.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,11 @@ pragma solidity >=0.8.18;
import {DecoderBase} from "./Base.sol";

import {Hash} from "../../src/core/libraries/Hash.sol";
import {DataStructures} from "../../src/core/libraries/DataStructures.sol";

import {HeaderLibHelper} from "./helpers/HeaderLibHelper.sol";
import {TxsDecoderHelper} from "./helpers/TxsDecoderHelper.sol";
import {HeaderLib} from "../../src/core/libraries/HeaderLib.sol";

import {TxsDecoder} from "../../src/core/libraries/decoders/TxsDecoder.sol";

import {AvailabilityOracle} from "../../src/core/availability_oracle/AvailabilityOracle.sol";
import {Constants} from "../../src/core/libraries/ConstantsGen.sol";

/**
* Blocks are generated using the `integration_l1_publisher.test.ts` tests.
Expand Down Expand Up @@ -196,13 +192,12 @@ contract DecodersTest is DecoderBase {
abi.encodePacked(hex"0000000c00000008", hex"00000004", firstFunctionCallLogs);
(bytes32 logsHash, uint256 bytesAdvanced) = txsHelper.computeKernelLogsHash(encodedLogs);

// Zero because this is the first iteration
bytes32 previousKernelPublicInputsLogsHash = bytes32(0);
bytes32 privateCircuitPublicInputsLogsHashFirstCall = Hash.sha256ToField(firstFunctionCallLogs);

bytes32 referenceLogsHash = Hash.sha256ToField(
abi.encodePacked(
previousKernelPublicInputsLogsHash, privateCircuitPublicInputsLogsHashFirstCall
privateCircuitPublicInputsLogsHashFirstCall,
new bytes(Constants.MAX_ENCRYPTED_LOGS_PER_TX * 32 - 32)
)
);

Expand All @@ -229,15 +224,16 @@ contract DecodersTest is DecoderBase {
);
(bytes32 logsHash, uint256 bytesAdvanced) = txsHelper.computeKernelLogsHash(encodedLogs);

bytes32 referenceLogsHashFromIteration1 =
Hash.sha256ToField(abi.encodePacked(bytes32(0), Hash.sha256ToField(firstFunctionCallLogs)));
bytes32 referenceLogsHashFromIteration1 = Hash.sha256ToField(firstFunctionCallLogs);

bytes32 privateCircuitPublicInputsLogsHashSecondCall =
Hash.sha256ToField(secondFunctionCallLogs);

bytes32 referenceLogsHashFromIteration2 = Hash.sha256ToField(
abi.encodePacked(
referenceLogsHashFromIteration1, privateCircuitPublicInputsLogsHashSecondCall
referenceLogsHashFromIteration1,
privateCircuitPublicInputsLogsHashSecondCall,
new bytes(Constants.MAX_ENCRYPTED_LOGS_PER_TX * 32 - 64)
)
);

Expand Down Expand Up @@ -269,16 +265,19 @@ contract DecodersTest is DecoderBase {
);
(bytes32 logsHash, uint256 bytesAdvanced) = txsHelper.computeKernelLogsHash(encodedLogs);

bytes32 referenceLogsHashFromIteration1 =
Hash.sha256ToField(abi.encodePacked(bytes32(0), Hash.sha256ToField(firstFunctionCallLogs)));
bytes32 referenceLogsHashFromIteration1 = Hash.sha256ToField(firstFunctionCallLogs);

// Note: as of resolving #5017, we now hash logs inside the circuits
// Following the YP, we skip any zero length logs, hence no use of secondFunctionCallLogs here

bytes32 privateCircuitPublicInputsLogsHashThirdCall = Hash.sha256ToField(thirdFunctionCallLogs);

bytes32 referenceLogsHashFromIteration3 = Hash.sha256ToField(
abi.encodePacked(referenceLogsHashFromIteration1, privateCircuitPublicInputsLogsHashThirdCall)
abi.encodePacked(
referenceLogsHashFromIteration1,
privateCircuitPublicInputsLogsHashThirdCall,
new bytes(Constants.MAX_ENCRYPTED_LOGS_PER_TX * 32 - 64)
)
);

assertEq(bytesAdvanced, encodedLogs.length, "Advanced by an incorrect number of bytes");
Expand Down
6 changes: 1 addition & 5 deletions noir-projects/aztec-nr/address-note/src/address_note.nr
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
// docs:start:encrypted_import
use dep::aztec::log::emit_encrypted_log;
// docs:end:encrypted_import
use dep::aztec::{
protocol_types::{address::AztecAddress, traits::Empty, constants::GENERATOR_INDEX__NOTE_NULLIFIER},
note::{note_header::NoteHeader, note_interface::NoteInterface, utils::compute_note_hash_for_consumption},
Expand Down Expand Up @@ -45,8 +42,7 @@ impl NoteInterface<ADDRESS_NOTE_LEN> for AddressNote {
fn broadcast(self, context: &mut PrivateContext, slot: Field) {
let encryption_pub_key = get_public_key(self.owner);
// docs:start:encrypted
emit_encrypted_log(
context,
context.emit_encrypted_log(
(*context).this_address(),
slot,
Self::get_note_type_id(),
Expand Down
2 changes: 1 addition & 1 deletion noir-projects/aztec-nr/aztec/src/context/avm_context.nr
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ impl PublicContextInterface for AvmContext {
nullifier_exists(unsiloed_nullifier, address.to_field()) == 1
}

fn emit_unencrypted_log<T>(&mut self, log: T) {
fn emit_unencrypted_log<T,N,M>(&mut self, log: T) {
let event_selector = 5; // Matches current PublicContext.
self.emit_unencrypted_log(event_selector, log);
}
Expand Down
2 changes: 1 addition & 1 deletion noir-projects/aztec-nr/aztec/src/context/interface.nr
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ trait PublicContextInterface {
fn fee_per_l2_gas(self) -> Field;
fn message_portal(&mut self, recipient: EthAddress, content: Field);
fn consume_l1_to_l2_message(&mut self, content: Field, secret: Field, sender: EthAddress, leaf_index: Field);
fn emit_unencrypted_log<T>(&mut self, log: T);
fn emit_unencrypted_log<T,N,M>(&mut self, log: T);
fn call_public_function<RETURNS_COUNT>(
self: &mut Self,
contract_address: AztecAddress,
Expand Down
Loading

0 comments on commit ecae76f

Please sign in to comment.