Skip to content

draft: aztec-nr review#21213

Draft
LeilaWang wants to merge 1 commit intonextfrom
lw/aztec_nr_review
Draft

draft: aztec-nr review#21213
LeilaWang wants to merge 1 commit intonextfrom
lw/aztec_nr_review

Conversation

@LeilaWang
Copy link
Contributor

Please read contributing guidelines and remove this line.

For audit-related pull requests, please use the audit PR template.

Copy link
Contributor

@nventuro nventuro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for the comments! Replied to most of them, for some I'll be opening PRs soon, for others only ~1 week from now as we want to not cause a lot of API breakage right now, but we'll definitely get to them before March is over.

I do have some follow-up questions in some of these.

Thanks again!

// If it's used for hashing with sha256 (as suggested in DAppPayload.to_be_bytes()), it could save quite a bit
// of gates.
// But the code doesn't seem to be used anywhere. Hashing of the payload uses serialize() and poseidon instead.
// Do we want to keep this?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will remove in the next pass, thanks.

@@ -1,2 +1,3 @@
// TODO: Can be deleted. Not used anywhere.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will also remove, thanks.

// incremented by the next_counter function every time a side effect is emitted.
// This was added because the code below used to be:
// `self.min_revertible_side_effect_counter = self.side_effect_counter;`
// which made it necessary to increment the side effect counter manually.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Are there downsides to unnecessarily incrementing these counters?

// We hash the entire padded log to ensure a user cannot pass a shorter length and so emit incorrect shorter
// bytecode.
let log_hash = poseidon2_hash(log_to_emit);
let log_hash = compute_contract_class_log_hash(log_to_emit);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should actualyl get rid of this function, it doesn't make sense for PrivateFunction to hold a fn that is only used by a protocol contract.

But are you saying this is wrong? If so, why? The protocol contracts don't use this version of the library, the use the aztec-sub-lib copy of it.

@@ -1108,6 +1116,9 @@ impl PrivateContext {
args_hash: Field,
is_static_call: bool,
) -> ReturnsHash {
// Q: It can be misleading to make a static call when the caller specifically requests a non-static call
// (`is_static_call == false`). Although this is not allowed and will cause the kernel to fail.
// But rather than altering the user's intent, throw an error from the simulator might be better?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, there's a planned refactor to call interfaces. In practice this ends up not happening as users don't construct these calls manually, but we should still fix the plumbing here.

@@ -83,6 +83,7 @@ impl<Context> SingleUseClaim<Context> {
/// [`SingleUseClaim::assert_claimed`] and [`SingleUseClaim::has_claimed`] to coherently write and read state.
fn compute_nullifier(self, owner_nhk_app: Field) -> Field {
// TODO(F-180): make sure we follow the nullifier convention
// Q: The separator should be DOM_SEP__NULLIFIER?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should actually be its own new separator, since __NULLIFIER is for note nullifiers and takes a note hash, which this doesn't. I addressed this yesterday in #21189

@@ -46,6 +46,8 @@ pub fn fields_from_bytes<let N: u32>(bytes: BoundedVec<u8, N>) -> BoundedVec<Fie
let p = std::field::modulus_be_bytes();

// Since input length is a multiple of 32, we can simply process all chunks fully
// TODO: Should be `for i in 0..N / 32 { if i < bytes.len() / 32 { ... } }` instead.
// This hasn't caused any problem because it's only used in an unconstrained fn at the moment.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. This function is due a small rework, as the name doesn't clearly explain what it is it does (it's not 'conversion'), we'll make it unconstrained as part of that.

for i in 0..N {
if idx == 32 {
randomness = random().to_be_bytes();
idx = 1; // Skip the first byte as it's biased (not uniformly distributed over 0-255).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We got rid of this entire file as this function was bad, replaced for the new poseidon masking mechanism

@@ -50,6 +50,8 @@ impl NoteHash for UintNote {

// Then compute the completion note hash. In a real partial note this step would be performed in public.
partial_note.compute_complete_note_hash(self.value)

// Q: The partial note and the complete note probably shouldn't use the same domain separator?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is the followup work to be done in #21189 - we need new domseps, and we need to change how the final note hash is computed (so that it guarantees separation by storage slot).

Partial note hash construction is about to get reworked, which is why this looks wrong now.

@@ -225,6 +227,7 @@ impl PartialUintNote {
// contract that emitted the nullifier) as it checks the value directly against the nullifier tree and all the
// nullifiers in the tree are siloed by the protocol.
let siloed_validity_commitment = compute_siloed_nullifier(context.this_address(), validity_commitment);
// Q: Why not use context.assert_nullifier_exists()?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unclear, that function may not have been nicely exposed at the time. Agreed that this is better, thanks. Possibly done this way because the author was porting the public case, and had settled nullifiers in mind.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants