Passkey based Account Abstraction signer for smart contract wallets

I’m long overdue to comment here, but better late than never. First of all, kudos to @rishotics and the rest of the Banana SDK team for leading this conversation. As the maintainer of Passkeys[dot]is I see the potential of the tech to be applied in crypto despite some caveats already identified.

For me, there are a couple of minimal requirements needed for this setup to work:

  • Multi-sig smart account - Although Passkeys are an ideal “kickstart” mechanism to onboard a user, it has a few flaws already pointed in the thread that make it unsuitable to make it a long-term solution as the only signer setup within a smart account. Here I envision something like a Safe that can be initially provisioned by a Passkey, yet can add other signers and even remove itself if needed.

  • Pure client implementation - Right now we are trying to go through the traditional webauthn workflow, which involves a server that creates a request and pairs it against the user name passed as part of the key creation params. However, relying on a server to “allow” usernames instead of passing the ECDSA signature might create a unwanted centralised point of failure not required for a smart wallet.

  • Lazy deployment - Because of the way Passkeys work, we can generate a public key during the generation of the first instance of the account. This key can then be passed to a contract and an entrypoint to provide a smart account address. We could use this address from day 0 until we would want to deploy it, allowing us minimal engagement with it until needed (e.g. airdrop to the account). Seems like @nlok5923 has already a way to have this address available.

  • Minimal gas cost - Even on L2s, the current cost of a secp256r1 signature verification is circa 1.2m, which is a pretty penny. There are multiple groups exploring the reduction of this cost (gas bad) including doing Elliptic-curve optimisations (see Ledger’s team presentation for EthCC '23), but nothing is “official” yet. Even my own demo on github (passkeys-webauth) has this cost.

  • Audit - At the end of the day we are verifying a ECDSA signature manually, since current’s Ethereum ecrecover is unable to parse this curve. Thus, it would be beneficial to the community to rally over an audit around a standard that can be used across the industry and benefit smart wallet creators as equal instead of building yet another lego block.

If we can tackle these points, I believe the other concerns can be partially or fully mitigated. For instance, we can work around Apple’s iCloud Keychain native syncing, and trusting their HSM setup provides a similar attack vector than, let’s say, a Web2 OAuth login like Web3Auth. Even then I would argue that Passkeys provide a better alternative, since they can work offline and w/o any server interface, as long as navigator.credentials is supported by the browser.

Now to answer some questions:

  • MicahZoltu - The keys are stored in the device and synced to iCloud for iOS devices (other devices do not have automatic cloud storage). In iOS, you can’t enable Passkeys w/o iCloud Keychain enabled, but you can remove the key from iCloud once it’s synced, and only from iCloud. In terms of security, in theory, and based on statements made by various Apple spokespeople, Apple stores user’s credentials KEK’s in their HSMs, which would be wiped after 10 failed attempts to the user’s iCloud. Thus, even on the case of a governmental seizure, they would technically be unable to share the key. Of course, metadata and other IP related information, even to the point of device fingerprinting, would still be likely possible. plusminushalf shared more on this in a previous post.

  • drortirosh yes, this is correct. What’s even funnier, is that the actual signing payload doesn’t matter. Because of the way webauthn works, we always sign on top of the authenticatorData and can not make use of the payload. So, the only thing we can learn from this request is “it has been signed”. It doesn’t matter what the user signs, just that it signed something at X point in time.

  • Victor928 it would be safe to assume that all transactions through a Passkey-based smart account would have a minimal requirement of the secp256r1 verification, currently at 1.2m cost on a naive implementation, some research pointing it going down as low as 300k-60k (see Ledger’s presentation for EthCC '23 on this).

  • Joseph under a single 1-out-of-1 naive implementation of a Passkey-based smart account, there’s no key revocation, and thus, would be awful if you need to rotate. Right now, the only way to “share” a Passkey is physically via Airdrop to a contact nearby, or using a roaming authenticator (e.g., Yubikey). Thus a multi-sig setup would likely be preferred. Other comments were already answered by @rishotics in the last post.

(NB: Someone with more rights kindly update to mention the people tagged).

2 Likes

Hey Jose, great insights. Building on them, here’s how we at Biconomy have approached these challenges:

  • Multi-sig Smart Account: Recognizing the concerns you raised, we’ve designed a modular architecture for our smart wallet. It encompasses:

    • Validation Modules: These dictate the ownership logic of the smart contract wallet.
    • Feature Modules: These introduce additional capabilities to the account. Upon deployment, users can choose between the standard ECDSA validation module with secp256k1 keys or opt for the Passkey validation module. To address concerns over passkeys, we have the option of enabling a social recovery module as a fallback.
  • Pure Client Implementation: I believe this is not a centralised / single point of failure. I’d like to emphasise that the keyId in passkeys isn’t part of the signature. When a smart contract is generated on-chain, it verifies x mod n == r. As @nlok5923 mentioned, parsing these values can generate the H160 Ethereum-compatible address. The username or this address can be used as and stored offchain. The keyId in passkeys simply directs which specific passkey to sign with.

  • Lazy Deployment: Similar to any wallet connecting to a dapp, when a user connects with passkeys, the dapp can leverage the x, y coordinates to request the smart account factory for the counterfactual smart account address. The address derivation will rely on the formula: moduleContractAddr + ModuleData + index, where ModuleData encompasses the x, y, and keyId.

  • Minimizing Gas Costs: Indeed, gas costs are a concern. A promising solution, in my view, is implementing a precompile for p256. EIP-7212 has outlined this approach effectively. The Opclave team is also working on this, having incorporated a precompile into optimism-geth to minimise gas usage.

  • Audit: We’ve undertaken multiple audits for secp256r1 and have some notable concerns which everyone should look into. Sharing this so we can have more discussion about it: bcnmy/scw-contracts.

Hoping this adds depth and I’m eager to see more perspectives on the matter.

1 Like

Great points, @amanraj1608

Had a few queries out of curiosity on Biconomy’s modular SCA implementations.

  • As you mentioned, the address would be counterfactually computed before the smart contract wallet deployment and it’s derived from moduleContractAddr + ModuleData + index. So before requesting for counterfactual address does the user have to somehow provide inputs that he needs the passkey module to be enabled? and let’s say in the near future he doesn’t need the passkey feature anymore so can the user be able to unsubscribe to that module. Suppose if he does it then the ModuleData should change and which would lead to a change in smart contract wallet address computation whenever the user would try to connect to a dapp which integrated Biconomy smart account sdk ?

  • Surely agrees that p256 precompile would greatly benefit the Passkey or in r1 ecosystem in general. But I think ledger has also launched r1 verifier implementation during ethcc which brings down verification to 70 - 75k gas and which is most efficient currently.

  • Also I believe in the foreseeable future instead of multiple smart contract account module standards we will be having something like a uniform module marketplace where devs can publish their built modules and users can subscribe/unsubscribe to the modules based on their requirements. Would love to know how Biconomy’s looking over it.

Thanks!

So before requesting for counterfactual address does the user have to somehow provide inputs that he needs the passkey module to be enabled

Yes so the user needs to pass the information of one authorisation module address at the time of deployment. This authorisation module will have the data of who is the owner of the SCW.
In future if anyone wants to change from ECDSA module to passkey module or vice verca, it can be done by using the enableModule method. Yeah the address will change if you are calculating with one address data and sending the other address data. But this is same case as before, to get the counterfactual addr you needed the EOA. If the contract is already deployed with any one module then it will not change ofc.
Also if you calculated and deployed with Passkeys on chain A and then change the module to ecdsa, and if you want the same addr on chain B you can do same thing, deploy the smart account with the same passkeys and update the ownership module with data as you want.

instead of multiple smart contract account module standards we will be having something like a uniform module

I believe the ERC-6900 will solve this issue and Biconomy would also be working on same.

1 Like