Skip to content

Commit dc5e0e6

Browse files
committed
feat(authwit): introduce hand-written AuthRegistryInterface for public flow
1 parent 8e7c296 commit dc5e0e6

3 files changed

Lines changed: 95 additions & 24 deletions

File tree

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
use crate::context::calls::{PublicCall, PublicStaticCall};
2+
use crate::protocol::{abis::function_selector::FunctionSelector, address::AztecAddress, traits::ToField};
3+
4+
/// Hand-written interface stub for the `AuthRegistry` canonical contract.
5+
///
6+
/// The `AuthRegistry` contract records public authentication witnesses
7+
/// (`set_authorized`, `set_reject_all`) and atomically consumes them at
8+
/// the consumer (`consume`). Consumer code in aztec-nr's `authwit::public`
9+
/// module calls into the registry via this interface.
10+
///
11+
/// The selectors are derived with `comptime { FunctionSelector::from_signature(...) }`,
12+
/// which matches exactly what the `#[aztec]` macro generates for the real contract.
13+
pub struct AuthRegistryInterface {
14+
pub target_contract: AztecAddress,
15+
}
16+
17+
impl AuthRegistryInterface {
18+
pub fn at(target_contract: AztecAddress) -> Self {
19+
Self { target_contract }
20+
}
21+
22+
pub fn _set_authorized(
23+
self,
24+
approver: AztecAddress,
25+
message_hash: Field,
26+
authorize: bool,
27+
) -> PublicCall<15, 3, ()> {
28+
let selector = comptime { FunctionSelector::from_signature("_set_authorized((Field),Field,bool)") };
29+
PublicCall::new(
30+
self.target_contract,
31+
selector,
32+
"_set_authorized",
33+
[approver.to_field(), message_hash, authorize as Field],
34+
)
35+
}
36+
37+
pub fn consume(self, on_behalf_of: AztecAddress, inner_hash: Field) -> PublicCall<7, 2, Field> {
38+
let selector = comptime { FunctionSelector::from_signature("consume((Field),Field)") };
39+
PublicCall::new(
40+
self.target_contract,
41+
selector,
42+
"consume",
43+
[on_behalf_of.to_field(), inner_hash],
44+
)
45+
}
46+
47+
pub fn is_consumable(self, on_behalf_of: AztecAddress, message_hash: Field) -> PublicStaticCall<13, 2, bool> {
48+
let selector = comptime { FunctionSelector::from_signature("is_consumable((Field),Field)") };
49+
PublicStaticCall::new(
50+
self.target_contract,
51+
selector,
52+
"is_consumable",
53+
[on_behalf_of.to_field(), message_hash],
54+
)
55+
}
56+
57+
pub fn is_reject_all(self, on_behalf_of: AztecAddress) -> PublicStaticCall<13, 1, bool> {
58+
let selector = comptime { FunctionSelector::from_signature("is_reject_all((Field))") };
59+
PublicStaticCall::new(
60+
self.target_contract,
61+
selector,
62+
"is_reject_all",
63+
[on_behalf_of.to_field()],
64+
)
65+
}
66+
67+
pub fn set_authorized(self, message_hash: Field, authorize: bool) -> PublicCall<14, 2, ()> {
68+
let selector = comptime { FunctionSelector::from_signature("set_authorized(Field,bool)") };
69+
PublicCall::new(
70+
self.target_contract,
71+
selector,
72+
"set_authorized",
73+
[message_hash, authorize as Field],
74+
)
75+
}
76+
77+
pub fn set_reject_all(self, reject: bool) -> PublicCall<14, 1, ()> {
78+
let selector = comptime { FunctionSelector::from_signature("set_reject_all(bool)") };
79+
PublicCall::new(
80+
self.target_contract,
81+
selector,
82+
"set_reject_all",
83+
[reject as Field],
84+
)
85+
}
86+
}

noir-projects/aztec-nr/aztec/src/authwit/mod.nr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Authorization.
22

33
pub mod account;
4+
pub mod auth_registry_interface;
45
pub mod authorization_interface;
56
mod authorization_selector;
67
pub use authorization_selector::AuthorizationSelector;

noir-projects/aztec-nr/aztec/src/authwit/public.nr

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
use crate::{authwit::utils::{compute_inner_authwit_hash, IS_VALID_SELECTOR}, context::{gas::GasOpts, PublicContext}};
2-
use crate::protocol::{abis::function_selector::FunctionSelector, address::AztecAddress, traits::ToField};
1+
use crate::authwit::auth_registry_interface::AuthRegistryInterface;
2+
use crate::authwit::utils::{compute_inner_authwit_hash, IS_VALID_SELECTOR};
3+
use crate::context::PublicContext;
4+
use crate::protocol::{address::AztecAddress, traits::ToField};
35
use standard_addresses::AUTH_REGISTRY_ADDRESS;
46

57
/// Public-flow authwit helpers.
@@ -86,14 +88,8 @@ pub unconstrained fn assert_inner_hash_valid_authwit_public(
8688
on_behalf_of: AztecAddress,
8789
inner_hash: Field,
8890
) {
89-
let results: [Field] = context.call_public_function(
90-
AUTH_REGISTRY_ADDRESS,
91-
comptime { FunctionSelector::from_signature("consume((Field),Field)") },
92-
[on_behalf_of.to_field(), inner_hash],
93-
GasOpts::default(),
94-
);
95-
assert(results.len() == 1, "Invalid response from registry");
96-
assert(results[0] == IS_VALID_SELECTOR, "Message not authorized by account");
91+
let result = AuthRegistryInterface::at(AUTH_REGISTRY_ADDRESS).consume(on_behalf_of, inner_hash).call(context);
92+
assert(result == IS_VALID_SELECTOR, "Message not authorized by account");
9793
}
9894

9995
/// Helper function to set the authorization status of a message hash
@@ -103,13 +99,7 @@ pub unconstrained fn assert_inner_hash_valid_authwit_public(
10399
/// @param message_hash The hash of the message to authorize @param authorize True if the message should be authorized,
104100
/// false if it should be revoked
105101
pub unconstrained fn set_authorized(context: PublicContext, message_hash: Field, authorize: bool) {
106-
let res = context.call_public_function(
107-
AUTH_REGISTRY_ADDRESS,
108-
comptime { FunctionSelector::from_signature("set_authorized(Field,bool)") },
109-
[message_hash, authorize as Field],
110-
GasOpts::default(),
111-
);
112-
assert(res.len() == 0);
102+
AuthRegistryInterface::at(AUTH_REGISTRY_ADDRESS).set_authorized(message_hash, authorize).call(context);
113103
}
114104

115105
/// Helper function to reject all authwits
@@ -118,11 +108,5 @@ pub unconstrained fn set_authorized(context: PublicContext, message_hash: Field,
118108
///
119109
/// @param reject True if all authwits should be rejected, false otherwise
120110
pub unconstrained fn set_reject_all(context: PublicContext, reject: bool) {
121-
let res = context.call_public_function(
122-
AUTH_REGISTRY_ADDRESS,
123-
comptime { FunctionSelector::from_signature("set_reject_all(bool)") },
124-
[reject as Field],
125-
GasOpts::default(),
126-
);
127-
assert(res.len() == 0);
111+
AuthRegistryInterface::at(AUTH_REGISTRY_ADDRESS).set_reject_all(reject).call(context);
128112
}

0 commit comments

Comments
 (0)