Skip to content

Commit 957be7c

Browse files
authored
update KeylessConfiguration comments (#18221)
1 parent 92c0534 commit 957be7c

File tree

2 files changed

+135
-8
lines changed

2 files changed

+135
-8
lines changed

aptos-move/framework/aptos-framework/doc/keyless_account.md

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,50 +148,110 @@ The 288-byte Groth16 verification key (VK) for the ZK relation that implements k
148148
<dd>
149149
An override <code>aud</code> for the identity of a recovery service, which will help users recover their keyless accounts
150150
associated with dapps or wallets that have disappeared.
151-
IMPORTANT: This recovery service **cannot** on its own take over user accounts; a user must first sign in
151+
IMPORTANT: This recovery service **cannot**, on its own, take over user accounts: a user must first sign in
152152
via OAuth in the recovery service in order to allow it to rotate any of that user's keyless accounts.
153+
154+
Furthermore, the ZKP eventually expires, so there is a limited window within which a malicious recovery
155+
service could rotate accounts. In the future, we can make this window arbitrarily small by further lowering
156+
the maximum expiration horizon for ZKPs used for recovery, instead of relying on the <code>max_exp_horizon_secs</code>
157+
value in this resource.
158+
159+
If changed: There is no prover service support yet for recovery mode => ZKPs with override aud's enabled
160+
will not be served by the prover service => as long as training wheels are "on," such recovery ZKPs will
161+
never arrive on chain.
162+
(Once support is implemented in the prover service, in an abundance of caution, the training wheel check
163+
should only pass if the override aud in the public statement matches one in this list. Therefore, changes
164+
to this value should be picked up automatically by the prover service.)
153165
</dd>
154166
<dt>
155167
<code>max_signatures_per_txn: u16</code>
156168
</dt>
157169
<dd>
158170
No transaction can have more than this many keyless signatures.
171+
172+
If changed: Only affects the Aptos validators; prover service not impacted.
159173
</dd>
160174
<dt>
161175
<code>max_exp_horizon_secs: u64</code>
162176
</dt>
163177
<dd>
164-
How far in the future from the JWT issued at time the EPK expiry can be set.
178+
How far in the future from the JWT's issued-at-time can the EPK expiration date be set?
179+
Specifically, validators enforce that the ZKP's expiration horizon is less than this <code>max_exp_horizon_secs</code>
180+
value.
181+
182+
If changed: Only affects the Aptos validators; prover service not impacted.
165183
</dd>
166184
<dt>
167185
<code>training_wheels_pubkey: <a href="../../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_Option">option::Option</a>&lt;<a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;&gt;</code>
168186
</dt>
169187
<dd>
170-
The training wheels PK, if training wheels are on
188+
The training wheels PK, if training wheels are on.
189+
190+
If changed: Prover service has to be re-deployed with the associated training wheel SK.
171191
</dd>
172192
<dt>
173193
<code>max_commited_epk_bytes: u16</code>
174194
</dt>
175195
<dd>
176196
The max length of an ephemeral public key supported in our circuit (93 bytes)
197+
198+
Note: Currently, the circuit derives the JWT's nonce field by hashing the EPK as:
199+
```
200+
Poseidon_6(
201+
epk_0, epk_1, epk_2,
202+
max_commited_epk_bytes,
203+
exp_date,
204+
epk_blinder
205+
)
206+
```
207+
and the public inputs hash by hashing the EPK with other inputs as:
208+
```
209+
Poseidon_14(
210+
epk_0, epk_1, epk_2,
211+
max_commited_epk_bytes,
212+
[...]
213+
)
214+
```
215+
where <code>max_committed_epk_byte</code> is passed in as one of the witnesses to the circuit. As a result, (some)
216+
changes to this field could technically be handled by the same circuit: e.g., if we let the epk_i chunks
217+
exceed 31 bytes, but no more than 32, then <code>max_commited_epk_bytes</code> could now be in (93, 96]. Whether such a
218+
restricted set of changes is useful remains unclear. Therefore, the verdict will be that...
219+
220+
If changed: (Likely) requires a circuit change because over-decreasing (or increasing) it leads to fewer (or
221+
more) EPK chunks. This would break the current way the circuit hashes the nonce and the public inputs.
222+
=> prover service redeployment.
177223
</dd>
178224
<dt>
179225
<code>max_iss_val_bytes: u16</code>
180226
</dt>
181227
<dd>
182228
The max length of the value of the JWT's <code>iss</code> field supported in our circuit (e.g., <code>"https://accounts.google.com"</code>)
229+
230+
If changed: Requires a circuit change because the <code>iss</code> field value is hashed inside the circuit as
231+
<code>HashBytesToFieldWithLen(MAX_ISS_VALUE_LEN)(iss_value, iss_value_len)</code> where <code>MAX_ISS_VALUE_LEN</code> is a
232+
circuit constant hard-coded to <code>max_iss_val_bytes</code> (i.e., to 120) => prover service redeployment..
183233
</dd>
184234
<dt>
185235
<code>max_extra_field_bytes: u16</code>
186236
</dt>
187237
<dd>
188238
The max length of the JWT field name and value (e.g., <code>"max_age":"18"</code>) supported in our circuit
239+
240+
If changed: Requires a circuit change because the extra field key-value pair is hashed inside the circuit as
241+
<code>HashBytesToFieldWithLen(MAX_EXTRA_FIELD_KV_PAIR_LEN)(extra_field, extra_field_len)</code> where
242+
<code>MAX_EXTRA_FIELD_KV_PAIR_LEN</code> is a circuit constant hard-coded to <code>max_extra_field_bytes</code> (i.e., to 350)
243+
=> prover service redeployment.
189244
</dd>
190245
<dt>
191246
<code>max_jwt_header_b64_bytes: u32</code>
192247
</dt>
193248
<dd>
194-
The max length of the base64url-encoded JWT header in bytes supported in our circuit
249+
The max length of the base64url-encoded JWT header in bytes supported in our circuit.
250+
251+
If changed: Requires a circuit change because the JWT header is hashed inside the circuit as
252+
<code>HashBytesToFieldWithLen(MAX_B64U_JWT_HEADER_W_DOT_LEN)(b64u_jwt_header_w_dot, b64u_jwt_header_w_dot_len)</code>
253+
where <code>MAX_B64U_JWT_HEADER_W_DOT_LEN</code> is a circuit constant hard-coded to <code>max_jwt_header_b64_bytes</code>
254+
(i.e., to 350) => prover service redeployment.
195255
</dd>
196256
</dl>
197257

aptos-move/framework/aptos-framework/sources/keyless_account.move

Lines changed: 71 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,22 +48,89 @@ module aptos_framework::keyless_account {
4848
struct Configuration has key, store, drop, copy {
4949
/// An override `aud` for the identity of a recovery service, which will help users recover their keyless accounts
5050
/// associated with dapps or wallets that have disappeared.
51-
/// IMPORTANT: This recovery service **cannot** on its own take over user accounts; a user must first sign in
51+
/// IMPORTANT: This recovery service **cannot**, on its own, take over user accounts: a user must first sign in
5252
/// via OAuth in the recovery service in order to allow it to rotate any of that user's keyless accounts.
53+
///
54+
/// Furthermore, the ZKP eventually expires, so there is a limited window within which a malicious recovery
55+
/// service could rotate accounts. In the future, we can make this window arbitrarily small by further lowering
56+
/// the maximum expiration horizon for ZKPs used for recovery, instead of relying on the `max_exp_horizon_secs`
57+
/// value in this resource.
58+
///
59+
/// If changed: There is no prover service support yet for recovery mode => ZKPs with override aud's enabled
60+
/// will not be served by the prover service => as long as training wheels are "on," such recovery ZKPs will
61+
/// never arrive on chain.
62+
/// (Once support is implemented in the prover service, in an abundance of caution, the training wheel check
63+
/// should only pass if the override aud in the public statement matches one in this list. Therefore, changes
64+
/// to this value should be picked up automatically by the prover service.)
5365
override_aud_vals: vector<String>,
66+
5467
/// No transaction can have more than this many keyless signatures.
68+
///
69+
/// If changed: Only affects the Aptos validators; prover service not impacted.
5570
max_signatures_per_txn: u16,
56-
/// How far in the future from the JWT issued at time the EPK expiry can be set.
71+
72+
/// How far in the future from the JWT's issued-at-time can the EPK expiration date be set?
73+
/// Specifically, validators enforce that the ZKP's expiration horizon is less than this `max_exp_horizon_secs`
74+
/// value.
75+
///
76+
/// If changed: Only affects the Aptos validators; prover service not impacted.
5777
max_exp_horizon_secs: u64,
58-
/// The training wheels PK, if training wheels are on
78+
79+
/// The training wheels PK, if training wheels are on.
80+
///
81+
/// If changed: Prover service has to be re-deployed with the associated training wheel SK.
5982
training_wheels_pubkey: Option<vector<u8>>,
83+
6084
/// The max length of an ephemeral public key supported in our circuit (93 bytes)
85+
///
86+
/// Note: Currently, the circuit derives the JWT's nonce field by hashing the EPK as:
87+
/// ```
88+
/// Poseidon_6(
89+
/// epk_0, epk_1, epk_2,
90+
/// max_commited_epk_bytes,
91+
/// exp_date,
92+
/// epk_blinder
93+
/// )
94+
/// ```
95+
/// and the public inputs hash by hashing the EPK with other inputs as:
96+
/// ```
97+
/// Poseidon_14(
98+
/// epk_0, epk_1, epk_2,
99+
/// max_commited_epk_bytes,
100+
/// [...]
101+
/// )
102+
/// ```
103+
/// where `max_committed_epk_byte` is passed in as one of the witnesses to the circuit. As a result, (some)
104+
/// changes to this field could technically be handled by the same circuit: e.g., if we let the epk_i chunks
105+
/// exceed 31 bytes, but no more than 32, then `max_commited_epk_bytes` could now be in (93, 96]. Whether such a
106+
/// restricted set of changes is useful remains unclear. Therefore, the verdict will be that...
107+
///
108+
/// If changed: (Likely) requires a circuit change because over-decreasing (or increasing) it leads to fewer (or
109+
/// more) EPK chunks. This would break the current way the circuit hashes the nonce and the public inputs.
110+
/// => prover service redeployment.
61111
max_commited_epk_bytes: u16,
112+
62113
/// The max length of the value of the JWT's `iss` field supported in our circuit (e.g., `"https://accounts.google.com"`)
114+
///
115+
/// If changed: Requires a circuit change because the `iss` field value is hashed inside the circuit as
116+
/// `HashBytesToFieldWithLen(MAX_ISS_VALUE_LEN)(iss_value, iss_value_len)` where `MAX_ISS_VALUE_LEN` is a
117+
/// circuit constant hard-coded to `max_iss_val_bytes` (i.e., to 120) => prover service redeployment..
63118
max_iss_val_bytes: u16,
119+
64120
/// The max length of the JWT field name and value (e.g., `"max_age":"18"`) supported in our circuit
121+
///
122+
/// If changed: Requires a circuit change because the extra field key-value pair is hashed inside the circuit as
123+
/// `HashBytesToFieldWithLen(MAX_EXTRA_FIELD_KV_PAIR_LEN)(extra_field, extra_field_len)` where
124+
/// `MAX_EXTRA_FIELD_KV_PAIR_LEN` is a circuit constant hard-coded to `max_extra_field_bytes` (i.e., to 350)
125+
/// => prover service redeployment.
65126
max_extra_field_bytes: u16,
66-
/// The max length of the base64url-encoded JWT header in bytes supported in our circuit
127+
128+
/// The max length of the base64url-encoded JWT header in bytes supported in our circuit.
129+
///
130+
/// If changed: Requires a circuit change because the JWT header is hashed inside the circuit as
131+
/// `HashBytesToFieldWithLen(MAX_B64U_JWT_HEADER_W_DOT_LEN)(b64u_jwt_header_w_dot, b64u_jwt_header_w_dot_len)`
132+
/// where `MAX_B64U_JWT_HEADER_W_DOT_LEN` is a circuit constant hard-coded to `max_jwt_header_b64_bytes`
133+
/// (i.e., to 350) => prover service redeployment.
67134
max_jwt_header_b64_bytes: u32,
68135
}
69136

0 commit comments

Comments
 (0)