Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add passkey authenticator to sui #18126

Merged
merged 17 commits into from
Jul 10, 2024
Merged

feat: add passkey authenticator to sui #18126

merged 17 commits into from
Jul 10, 2024

Conversation

joyqvq
Copy link
Contributor

@joyqvq joyqvq commented Jun 7, 2024

Description

implementation for sui-foundation/sips#9

Test plan

added unit tests and e2e tests. also tested with real passkey result from frontend

credential id (base64): 9Aj01fIn/T555beIoJ7swA87mLc=

pubkey (hex): 03e61ebc6b1796021e33fd3937298f2c460e77e5bb7fbeb3c42f7e0f11f67792cb

sui address: 0xb88d3e91880e6befc13881a4a7d5b4d2dfa402ae2b149cd9b36d6e084ba25925

tx bytes: AAAAALiNPpGIDmvvwTiBpKfVtNLfpAKuKxSc2bNtbghLolklAfuV/HGZhQdRfe9WXfY8A7b76qucni1/FFaa7LlYHgcGAgAAAAAAAAAgUuv6miRJNCj1OhyRzP5sZyrIU1DSRTLrXfvbmp9cuuu4jT6RiA5r78E4gaSn1bTS36QCrisUnNmzbW4IS6JZJegDAAAAAAAAgIQeAAAAAAAA

tx digest (hex): 000000f1b6d366d79ae9d2d98da7909b8fa4d856f64c4b9663a1d875d7823f5e8585e4

authenticatorData (hex): 49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d97631d00000000

clientDataJSON: `{"type":"webauthn.get","challenge":"AAAA8bbTZtea6dLZjaeQm4-k2Fb2TEuWY6HYddeCP16FheQ","origin":"http://localhost:5173","crossOrigin":false}`

r1 signature (hex): 02ecbbf52b29ec5d306501d00f175bd084d909a4f9a92318cf3df1fa3a86028cbe2dcc606a99f69817991bab559b744039c21b417c988056969b8fec78d17bad7c03e61ebc6b1796021e33fd3937298f2c460e77e5bb7fbeb3c42f7e0f11f67792cb

encoded sui signature (base64): BiVJlg3liA6MaHQ0Fw9kdmBbj+SuuaKGMseZXPO6gx2XYx0AAAAAigF7InR5cGUiOiJ3ZWJhdXRobi5nZXQiLCJjaGFsbGVuZ2UiOiJBQUFBOGJiVFp0ZWE2ZExaamFlUW00LWsyRmIyVEV1V1k2SFlkZGVDUDE2RmhlUSIsIm9yaWdpbiI6Imh0dHA6Ly9sb2NhbGhvc3Q6NTE3MyIsImNyb3NzT3JpZ2luIjpmYWxzZX1iAuy79Ssp7F0wZQHQDxdb0ITZCaT5qSMYzz3x+jqGAoy+Lcxgapn2mBeZG6tVm3RAOcIbQXyYgFaWm4/seNF7rXwD5h68axeWAh4z/Tk3KY8sRg535bt/vrPEL34PEfZ3kss=

encoded webuahthn signature length: 278

signature verified: true

localnet onchain verified, digest: DSt3BdgByH5WgKuysdwPMLrCtH2HZhvtzGNBJarBA7VR

Release notes

Check each box that your changes affect. If none of the boxes relate to your changes, release notes aren't required.

For each box you select, include information after the relevant heading that describes the impact of your changes that a user might notice and any actions they must take to implement updates.

  • Protocol:
  • Nodes (Validators and Full nodes):
  • Indexer:
  • JSON-RPC:
  • GraphQL:
  • CLI:
  • Rust SDK:

Copy link

vercel bot commented Jun 7, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
sui-docs ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jul 10, 2024 3:12pm
3 Skipped Deployments
Name Status Preview Comments Updated (UTC)
multisig-toolkit ⬜️ Ignored (Inspect) Visit Preview Jul 10, 2024 3:12pm
sui-kiosk ⬜️ Ignored (Inspect) Visit Preview Jul 10, 2024 3:12pm
sui-typescript-docs ⬜️ Ignored (Inspect) Visit Preview Jul 10, 2024 3:12pm

Copy link
Contributor

@benr-ml benr-ml left a comment

Choose a reason for hiding this comment

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

Let's control the rollout of this feature with a protocol config.

Cargo.toml Show resolved Hide resolved
crates/sui-types/src/passkey_authenticator.rs Outdated Show resolved Hide resolved
crates/sui-types/src/passkey_authenticator.rs Outdated Show resolved Hide resolved
crates/sui-types/src/passkey_authenticator.rs Outdated Show resolved Hide resolved
})?;
if author
!= SuiAddress::from(
&PublicKey::try_from_bytes(
Copy link
Contributor

Choose a reason for hiding this comment

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

do we want it to be derived exactly like any r1 account? what are the pros and cons of not having it as a different account?

crates/sui-types/src/passkey_authenticator.rs Outdated Show resolved Hide resolved
@joyqvq
Copy link
Contributor Author

joyqvq commented Jun 10, 2024

addressed comments.

todo: add protocol config for devnet only(when review is stable to avoid merge conflicts)

open q for meeting:

  1. define it as r1 type at deser? how to make jsonschema work - done, requires a default impl for r1 pk and sig in fastcrypto
  2. any enforcing checks on origin? - no need
  3. derive address from pk or differently? - use passkey flag instead
  4. go over test cases, todo: add them to transaction_tests - done. serde test and a few hardcoded test cases needs to be in unit test, everything else in e2e test.

@@ -2465,7 +2465,8 @@ impl VersionedProtocolMessage for SenderSignedData {
}
GenericSignature::Signature(_)
| GenericSignature::MultiSigLegacy(_)
| GenericSignature::ZkLoginAuthenticator(_) => (),
| GenericSignature::ZkLoginAuthenticator(_)
| GenericSignature::PasskeyAuthenticator(_) => (),
Copy link
Contributor

Choose a reason for hiding this comment

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

we need to check for a protocol flag here, as the comments say (btw can you remove the comment about the code doing nothing, since checks have been added since that comment was written)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

    fn check_user_signature_protocol_compatibility(&self, config: &ProtocolConfig) -> SuiResult {
        if !config.zklogin_auth() && self.has_zklogin_sig() {
            return Err(SuiError::UnsupportedFeatureError {
                error: "zklogin is not enabled on this network".to_string(),
            });
        }

looks like we check this at a different place too, maybe we should keep them all at the same place?

Copy link
Contributor

Choose a reason for hiding this comment

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

Seems like we should be calling check_user_signature_protocol_compatibility inside here, and then call this function from validity_check()?
I have meant to continue working on the validity check refactoring but got distracted, will continue looking as we ll

Copy link
Contributor

Choose a reason for hiding this comment

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

btw I am refactoring this part in #18342

use fastcrypto::traits::VerifyingKey;
use fastcrypto::{error::FastCryptoError, traits::ToFromBytes};
use once_cell::sync::OnceCell;
use passkey::types::webauthn::{ClientDataType, CollectedClientData};
Copy link
Contributor

Choose a reason for hiding this comment

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

Question: Given all we're using the passkey library for is these data types could we either:

  1. only depend on the passkey_types crate and not the whole passkey top level crate
  2. or can we just reimplement these types here so we don't need to depend on them at all?

I think 1 is probably the safest option and we could start there.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

revised, only passkey-types is included in deps. passkey-authenticator and passkey-client are included for dev-deps for e2e tests and unit tests

Comment on lines 303 to 314
/// Compute the hash(tx_data) from the intent msg.
pub fn to_tx_digest<T: Serialize>(intent_msg: &IntentMessage<T>) -> [u8; DefaultHash::OUTPUT_SIZE] {
let mut hasher = DefaultHash::default();
bcs::serialize_into(&mut hasher, &intent_msg.value)
.expect("Message serialization should not fail");
hasher.finalize().digest
}
Copy link
Contributor

Choose a reason for hiding this comment

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

So this is actually incorrect as its not properly taking into account the salt "TransactionData::" that is required for actually computing the transaction digest. this means the output of this function and Transaction::digest will differ.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good point, revised to signing digest

Comment on lines 303 to 314
/// Compute the hash(tx_data) from the intent msg.
pub fn to_signing_digest<T: Serialize>(
intent_msg: &IntentMessage<T>,
) -> [u8; DefaultHash::OUTPUT_SIZE] {
let mut hasher = DefaultHash::default();
bcs::serialize_into(&mut hasher, &intent_msg.value)
.expect("Message serialization should not fail");
hasher.finalize().digest
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I thought we agreed on this being the Transaction Digest? I don't see the value in encoding the challenge with (Intent | non tx digest) over hash(Intent | non tx digest) in this case. The value that was being provided with this sending (Intent | digest) was that we could match the digest to the transaction digest that is well known.

Copy link
Contributor Author

@joyqvq joyqvq Jul 9, 2024

Choose a reason for hiding this comment

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

i misunderstood before - since it will end up diverging with the original signing digest i thought we were ok with signing_digest not tx_digest.

while i can change to tx_digest, this introduces a non trivial change to the code that involves an additional trait everywhere that we wanted to avoid before

T: Serialize + Signable<DefaultHash>
instead of
T: Serialize

for all authenticator trait implementers. this makes a lot of places hard to implement such as PersonalMessage since this can trait can only be implemented as a private trait.

is this desirable? is there an alternative way to avoid it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

PersonalMessage also uses this trait but its not implemented inside the private trait module, it only implements Serialize

Copy link
Contributor

Choose a reason for hiding this comment

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

After discussing it seems like we should leave this as-is given deviating from this would be thrashing against the status quo (which we've identified is not great but not something we can really worry about addressing right now)

@joyqvq joyqvq merged commit 9b8a5ae into main Jul 10, 2024
48 checks passed
@joyqvq joyqvq deleted the joy/passkey branch July 10, 2024 15:51
tx-tomcat pushed a commit to tx-tomcat/sui-network that referenced this pull request Jul 29, 2024
## Description 

implementation for sui-foundation/sips#9

## Test plan 

added unit tests and e2e tests. also tested with real passkey result
from frontend

```
credential id (base64): 9Aj01fIn/T555beIoJ7swA87mLc=

pubkey (hex): 03e61ebc6b1796021e33fd3937298f2c460e77e5bb7fbeb3c42f7e0f11f67792cb

sui address: 0xb88d3e91880e6befc13881a4a7d5b4d2dfa402ae2b149cd9b36d6e084ba25925

tx bytes: AAAAALiNPpGIDmvvwTiBpKfVtNLfpAKuKxSc2bNtbghLolklAfuV/HGZhQdRfe9WXfY8A7b76qucni1/FFaa7LlYHgcGAgAAAAAAAAAgUuv6miRJNCj1OhyRzP5sZyrIU1DSRTLrXfvbmp9cuuu4jT6RiA5r78E4gaSn1bTS36QCrisUnNmzbW4IS6JZJegDAAAAAAAAgIQeAAAAAAAA

tx digest (hex): 000000f1b6d366d79ae9d2d98da7909b8fa4d856f64c4b9663a1d875d7823f5e8585e4

authenticatorData (hex): 49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d97631d00000000

clientDataJSON: `{"type":"webauthn.get","challenge":"AAAA8bbTZtea6dLZjaeQm4-k2Fb2TEuWY6HYddeCP16FheQ","origin":"http://localhost:5173","crossOrigin":false}`

r1 signature (hex): 02ecbbf52b29ec5d306501d00f175bd084d909a4f9a92318cf3df1fa3a86028cbe2dcc606a99f69817991bab559b744039c21b417c988056969b8fec78d17bad7c03e61ebc6b1796021e33fd3937298f2c460e77e5bb7fbeb3c42f7e0f11f67792cb

encoded sui signature (base64): BiVJlg3liA6MaHQ0Fw9kdmBbj+SuuaKGMseZXPO6gx2XYx0AAAAAigF7InR5cGUiOiJ3ZWJhdXRobi5nZXQiLCJjaGFsbGVuZ2UiOiJBQUFBOGJiVFp0ZWE2ZExaamFlUW00LWsyRmIyVEV1V1k2SFlkZGVDUDE2RmhlUSIsIm9yaWdpbiI6Imh0dHA6Ly9sb2NhbGhvc3Q6NTE3MyIsImNyb3NzT3JpZ2luIjpmYWxzZX1iAuy79Ssp7F0wZQHQDxdb0ITZCaT5qSMYzz3x+jqGAoy+Lcxgapn2mBeZG6tVm3RAOcIbQXyYgFaWm4/seNF7rXwD5h68axeWAh4z/Tk3KY8sRg535bt/vrPEL34PEfZ3kss=

encoded webuahthn signature length: 278

signature verified: true

localnet onchain verified, digest: DSt3BdgByH5WgKuysdwPMLrCtH2HZhvtzGNBJarBA7VR
```
---

## Release notes

Check each box that your changes affect. If none of the boxes relate to
your changes, release notes aren't required.

For each box you select, include information after the relevant heading
that describes the impact of your changes that a user might notice and
any actions they must take to implement updates.

- [ ] Protocol: 
- [ ] Nodes (Validators and Full nodes): 
- [ ] Indexer: 
- [ ] JSON-RPC: 
- [ ] GraphQL: 
- [ ] CLI: 
- [ ] Rust SDK:
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.

5 participants