Skip to content

Commit 2fa77ea

Browse files
authored
Implement Sui DAA (#17523)
* implement sui daa * fix lint * fix lint * remove unneeded module use * fix * refactor for modularity * fix lint * generalize daa autheticate function
1 parent 84df755 commit 2fa77ea

File tree

15 files changed

+1610
-182
lines changed

15 files changed

+1610
-182
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

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

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@
55

66

77

8+
- [Constants](#@Constants_0)
89
- [Function `network_name`](#0x1_common_account_abstractions_utils_network_name)
910
- [Function `entry_function_name`](#0x1_common_account_abstractions_utils_entry_function_name)
11+
- [Function `construct_message`](#0x1_common_account_abstractions_utils_construct_message)
12+
- [Function `daa_authenticate`](#0x1_common_account_abstractions_utils_daa_authenticate)
1013

1114

1215
<pre><code><b>use</b> <a href="chain_id.md#0x1_chain_id">0x1::chain_id</a>;
@@ -18,6 +21,21 @@
1821

1922

2023

24+
<a id="@Constants_0"></a>
25+
26+
## Constants
27+
28+
29+
<a id="0x1_common_account_abstractions_utils_EMISSING_ENTRY_FUNCTION_PAYLOAD"></a>
30+
31+
Entry function payload is missing.
32+
33+
34+
<pre><code><b>const</b> <a href="common_account_abstractions_utils.md#0x1_common_account_abstractions_utils_EMISSING_ENTRY_FUNCTION_PAYLOAD">EMISSING_ENTRY_FUNCTION_PAYLOAD</a>: u64 = 1;
35+
</code></pre>
36+
37+
38+
2139
<a id="0x1_common_account_abstractions_utils_network_name"></a>
2240

2341
## Function `network_name`
@@ -90,6 +108,93 @@
90108

91109

92110

111+
</details>
112+
113+
<a id="0x1_common_account_abstractions_utils_construct_message"></a>
114+
115+
## Function `construct_message`
116+
117+
118+
119+
<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="common_account_abstractions_utils.md#0x1_common_account_abstractions_utils_construct_message">construct_message</a>(chain_name: &<a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;, account_address: &<a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;, domain: &<a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;, entry_function_name: &<a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;, digest_utf8: &<a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;): <a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;
120+
</code></pre>
121+
122+
123+
124+
<details>
125+
<summary>Implementation</summary>
126+
127+
128+
<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="common_account_abstractions_utils.md#0x1_common_account_abstractions_utils_construct_message">construct_message</a>(
129+
chain_name: &<a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;,
130+
account_address: &<a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;,
131+
domain: &<a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;,
132+
entry_function_name: &<a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;,
133+
digest_utf8: &<a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;,
134+
): <a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt; {
135+
<b>let</b> message = &<b>mut</b> <a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>[];
136+
message.append(*domain);
137+
message.append(b" wants you <b>to</b> sign in <b>with</b> your ");
138+
message.append(*chain_name);
139+
message.append(b" <a href="account.md#0x1_account">account</a>:\n");
140+
message.append(*account_address);
141+
message.append(b"\n\nPlease confirm you explicitly initiated this request from ");
142+
message.append(*domain);
143+
message.append(b".");
144+
message.append(b" You are approving <b>to</b> execute transaction ");
145+
message.append(*entry_function_name);
146+
message.append(b" on Aptos blockchain");
147+
<b>let</b> network_name = <a href="common_account_abstractions_utils.md#0x1_common_account_abstractions_utils_network_name">network_name</a>();
148+
message.append(b" (");
149+
message.append(network_name);
150+
message.append(b")");
151+
message.append(b".");
152+
message.append(b"\n\nNonce: ");
153+
message.append(*digest_utf8);
154+
*message
155+
}
156+
</code></pre>
157+
158+
159+
160+
</details>
161+
162+
<a id="0x1_common_account_abstractions_utils_daa_authenticate"></a>
163+
164+
## Function `daa_authenticate`
165+
166+
167+
168+
<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="common_account_abstractions_utils.md#0x1_common_account_abstractions_utils_daa_authenticate">daa_authenticate</a>(<a href="account.md#0x1_account">account</a>: <a href="../../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>, aa_auth_data: <a href="auth_data.md#0x1_auth_data_AbstractionAuthData">auth_data::AbstractionAuthData</a>, auth_fn: |<a href="auth_data.md#0x1_auth_data_AbstractionAuthData">auth_data::AbstractionAuthData</a>, &<a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;|): <a href="../../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>
169+
</code></pre>
170+
171+
172+
173+
<details>
174+
<summary>Implementation</summary>
175+
176+
177+
<pre><code><b>public</b>(<b>friend</b>) inline <b>fun</b> <a href="common_account_abstractions_utils.md#0x1_common_account_abstractions_utils_daa_authenticate">daa_authenticate</a>(
178+
<a href="account.md#0x1_account">account</a>: <a href="../../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>,
179+
aa_auth_data: AbstractionAuthData,
180+
auth_fn: |AbstractionAuthData, &<a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;|,
181+
): <a href="../../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a> {
182+
<b>let</b> maybe_entry_function_payload = <a href="transaction_context.md#0x1_transaction_context_entry_function_payload">transaction_context::entry_function_payload</a>();
183+
<b>if</b> (maybe_entry_function_payload.is_some()) {
184+
<b>let</b> entry_function_payload = maybe_entry_function_payload.destroy_some();
185+
<b>let</b> entry_function_name = <a href="common_account_abstractions_utils.md#0x1_common_account_abstractions_utils_entry_function_name">entry_function_name</a>(&entry_function_payload);
186+
187+
// call the passed-in function value
188+
auth_fn(aa_auth_data, &entry_function_name);
189+
<a href="account.md#0x1_account">account</a>
190+
} <b>else</b> {
191+
<b>abort</b>(<a href="common_account_abstractions_utils.md#0x1_common_account_abstractions_utils_EMISSING_ENTRY_FUNCTION_PAYLOAD">EMISSING_ENTRY_FUNCTION_PAYLOAD</a>)
192+
}
193+
}
194+
</code></pre>
195+
196+
197+
93198
</details>
94199

95200

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

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,16 @@ Issued At: <issued_at>
173173
## Constants
174174

175175

176+
<a id="0x1_ethereum_derivable_account_EMISSING_ENTRY_FUNCTION_PAYLOAD"></a>
177+
178+
Entry function payload is missing.
179+
180+
181+
<pre><code><b>const</b> <a href="ethereum_derivable_account.md#0x1_ethereum_derivable_account_EMISSING_ENTRY_FUNCTION_PAYLOAD">EMISSING_ENTRY_FUNCTION_PAYLOAD</a>: u64 = 2;
182+
</code></pre>
183+
184+
185+
176186
<a id="0x1_ethereum_derivable_account_EADDR_MISMATCH"></a>
177187

178188
Address mismatch.
@@ -203,16 +213,6 @@ Invalid signature type.
203213

204214

205215

206-
<a id="0x1_ethereum_derivable_account_EMISSING_ENTRY_FUNCTION_PAYLOAD"></a>
207-
208-
Entry function payload is missing.
209-
210-
211-
<pre><code><b>const</b> <a href="ethereum_derivable_account.md#0x1_ethereum_derivable_account_EMISSING_ENTRY_FUNCTION_PAYLOAD">EMISSING_ENTRY_FUNCTION_PAYLOAD</a>: u64 = 2;
212-
</code></pre>
213-
214-
215-
216216
<a id="0x1_ethereum_derivable_account_EUNEXPECTED_V"></a>
217217

218218
Unexpected v value.
@@ -341,7 +341,7 @@ We include the issued_at in the signature as it is a required field in the SIWE
341341
message.append(b"\nIssued At: ");
342342
message.append(*issued_at);
343343

344-
<b>let</b> msg_len = <a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector_length">vector::length</a>(message);
344+
<b>let</b> msg_len = message.length();
345345

346346
<b>let</b> prefix = b"\x19Ethereum Signed Message:\n";
347347
<b>let</b> msg_len_string = <a href="../../aptos-stdlib/doc/string_utils.md#0x1_string_utils_to_string">string_utils::to_string</a>(&msg_len); // returns <a href="../../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string">string</a>
@@ -376,27 +376,27 @@ We include the issued_at in the signature as it is a required field in the SIWE
376376

377377

378378
<pre><code><b>fun</b> <a href="ethereum_derivable_account.md#0x1_ethereum_derivable_account_recover_public_key">recover_public_key</a>(signature_bytes: &<a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;, message: &<a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;): <a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt; {
379-
<b>let</b> rs = <a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector_slice">vector::slice</a>(signature_bytes, 0, 64);
380-
<b>let</b> v = *<a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector_borrow">vector::borrow</a>(signature_bytes, 64);
379+
<b>let</b> rs = signature_bytes.slice(0, 64);
380+
<b>let</b> v = signature_bytes[64];
381381
<b>assert</b>!(v == 27 || v == 28, <a href="ethereum_derivable_account.md#0x1_ethereum_derivable_account_EUNEXPECTED_V">EUNEXPECTED_V</a>);
382382
<b>let</b> signature = <a href="../../aptos-stdlib/doc/secp256k1.md#0x1_secp256k1_ecdsa_signature_from_bytes">secp256k1::ecdsa_signature_from_bytes</a>(rs);
383383

384384
<b>let</b> maybe_recovered = <a href="../../aptos-stdlib/doc/secp256k1.md#0x1_secp256k1_ecdsa_recover">secp256k1::ecdsa_recover</a>(*message, v - 27, &signature);
385385

386386
<b>assert</b>!(
387-
<a href="../../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_is_some">option::is_some</a>(&maybe_recovered),
387+
maybe_recovered.is_some(),
388388
<a href="ethereum_derivable_account.md#0x1_ethereum_derivable_account_EINVALID_SIGNATURE">EINVALID_SIGNATURE</a>
389389
);
390390

391-
<b>let</b> pubkey = <a href="../../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_borrow">option::borrow</a>(&maybe_recovered);
391+
<b>let</b> pubkey = maybe_recovered.borrow();
392392

393393
<b>let</b> pubkey_bytes = <a href="../../aptos-stdlib/doc/secp256k1.md#0x1_secp256k1_ecdsa_raw_public_key_to_bytes">secp256k1::ecdsa_raw_public_key_to_bytes</a>(pubkey);
394394

395395
// Add 0x04 prefix <b>to</b> the <b>public</b> key, <b>to</b> match the
396396
// full uncompressed format from ethers.js
397397
<b>let</b> full_pubkey = &<b>mut</b> <a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>[];
398-
<a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector_push_back">vector::push_back</a>(full_pubkey, 4u8);
399-
<a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector_append">vector::append</a>(full_pubkey, pubkey_bytes);
398+
full_pubkey.push_back(4u8);
399+
full_pubkey.append(pubkey_bytes);
400400

401401
*full_pubkey
402402
}
@@ -436,13 +436,13 @@ We include the issued_at in the signature as it is a required field in the SIWE
436436
<b>let</b> public_key_bytes = <a href="ethereum_derivable_account.md#0x1_ethereum_derivable_account_recover_public_key">recover_public_key</a>(&abstract_signature.signature, &hashed_message);
437437

438438
// 1. Skip the 0x04 prefix (take the bytes after the first byte)
439-
<b>let</b> public_key_without_prefix = <a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector_slice">vector::slice</a>(&public_key_bytes, 1, <a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector_length">vector::length</a>(&public_key_bytes));
439+
<b>let</b> public_key_without_prefix = public_key_bytes.slice(1, public_key_bytes.length());
440440
// 2. Run Keccak256 on the <b>public</b> key (without the 0x04 prefix)
441441
<b>let</b> kexHash = <a href="../../aptos-stdlib/../move-stdlib/doc/hash.md#0x1_aptos_hash_keccak256">aptos_hash::keccak256</a>(public_key_without_prefix);
442442
// 3. Slice the last 20 bytes (this is the Ethereum <b>address</b>)
443-
<b>let</b> recovered_addr = <a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector_slice">vector::slice</a>(&kexHash, 12, 32);
443+
<b>let</b> recovered_addr = kexHash.slice(12, 32);
444444
// 4. Remove the 0x prefix from the utf8 <a href="account.md#0x1_account">account</a> <b>address</b>
445-
<b>let</b> ethereum_address_without_prefix = <a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector_slice">vector::slice</a>(&abstract_public_key.ethereum_address, 2, <a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector_length">vector::length</a>(&abstract_public_key.ethereum_address));
445+
<b>let</b> ethereum_address_without_prefix = abstract_public_key.ethereum_address.slice(2, abstract_public_key.ethereum_address.length());
446446

447447
<b>let</b> account_address_vec = base16_utf8_to_vec_u8(ethereum_address_without_prefix);
448448
// Verify that the recovered <b>address</b> matches the domain <a href="account.md#0x1_account">account</a> identity
@@ -471,15 +471,7 @@ Authorization function for domain account abstraction.
471471

472472

473473
<pre><code><b>public</b> <b>fun</b> <a href="ethereum_derivable_account.md#0x1_ethereum_derivable_account_authenticate">authenticate</a>(<a href="account.md#0x1_account">account</a>: <a href="../../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>, aa_auth_data: AbstractionAuthData): <a href="../../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a> {
474-
<b>let</b> maybe_entry_function_payload = <a href="transaction_context.md#0x1_transaction_context_entry_function_payload">transaction_context::entry_function_payload</a>();
475-
<b>if</b> (maybe_entry_function_payload.is_some()) {
476-
<b>let</b> entry_function_payload = maybe_entry_function_payload.destroy_some();
477-
<b>let</b> entry_function_name = entry_function_name(&entry_function_payload);
478-
<a href="ethereum_derivable_account.md#0x1_ethereum_derivable_account_authenticate_auth_data">authenticate_auth_data</a>(aa_auth_data, &entry_function_name);
479-
<a href="account.md#0x1_account">account</a>
480-
} <b>else</b> {
481-
<b>abort</b>(<a href="ethereum_derivable_account.md#0x1_ethereum_derivable_account_EMISSING_ENTRY_FUNCTION_PAYLOAD">EMISSING_ENTRY_FUNCTION_PAYLOAD</a>)
482-
}
474+
daa_authenticate(<a href="account.md#0x1_account">account</a>, aa_auth_data, |<a href="auth_data.md#0x1_auth_data">auth_data</a>, entry_name| <a href="ethereum_derivable_account.md#0x1_ethereum_derivable_account_authenticate_auth_data">authenticate_auth_data</a>(<a href="auth_data.md#0x1_auth_data">auth_data</a>, entry_name))
483475
}
484476
</code></pre>
485477

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ This is the reference documentation of the Aptos framework.
7373
- [`0x1::staking_proxy`](staking_proxy.md#0x1_staking_proxy)
7474
- [`0x1::state_storage`](state_storage.md#0x1_state_storage)
7575
- [`0x1::storage_gas`](storage_gas.md#0x1_storage_gas)
76+
- [`0x1::sui_derivable_account`](sui_derivable_account.md#0x1_sui_derivable_account)
7677
- [`0x1::system_addresses`](system_addresses.md#0x1_system_addresses)
7778
- [`0x1::timestamp`](timestamp.md#0x1_timestamp)
7879
- [`0x1::transaction_context`](transaction_context.md#0x1_transaction_context)

0 commit comments

Comments
 (0)