Grant Application - MFKDF2

Hi @hanh,

Yes – passkey as a factor is available. This is the setup code in the original MFKDF repo (which does have previously mentioned security updates) and this is it in the newer Rust repo.

As a note, for passkeys to work with MFKDF2, you have to have the PRF extension available from your authenticator. In the web, you’d use the navigator.credentials API. Specifically, navigator.credentials.create() for the publicKey type where you’d set options such as PublicKeyCredentialCreationOptions with extensions containing the PRF extension enabled. Note: not all authenticators support this extension! We have found through our own testing that older versions of MacOS and the current Windows authenticator do not seem to support PRF. Please let me know if you need further examples here. There are more docs now merged into the Rust repo that you may find helpful!

The library is built for key derivation broadly, whether you want to use this for authentication or encryption from there is up to you. As for recovery, this is also part of the available API, however, if the policy is lost entirely, then you will lose the ability to derive that original key even with the factors you have available to you. The policy itself contains extra data necessary for deriving the key. Policies can be self-signed and stored publicly so that you may verify their integrity if you restore a policy from a public location at a later point. We recommend keeping your policy backed up in many places. Again, the material of a policy is safe to store publicly, so you can use your favorite hosting service as one storage option.

Please let me know if this is lacking in any way. I’m always happy to help work on this with you!

1 Like

Hmmm … Yes, it seems to work how I understood. However, this brings a big design problem that I hope you can help me solve since it is a deal breaker at this moment.

I want to realize this vision you mentioned in the proposal:

MFKDF2 has the potential of making novice Zcash users more comfortable with moving to self-custody by eliminating the need for seed phrases and other cumbersome manual key management strategies, allowing those users to experience the full privacy benefits of Zcash for the first time.

(emphasis mine)

My use case is as follows:

The user Alice wants to create a new account in her wallet app to send and receive funds. The wallet app must let her choose a password and generate a TOTP QR code. Alice scans the QR code on her phone Google Authenticator and registers a new TOTP.
Then, the wallet app creates an account.
One day, the phone breaks. She has the password and the TOTP authenticator.
The wallet app MUST be able to recover her funds on a new phone.

To be in line with “eliminating the need for seed phrases and other cumbersome manual key management strategies”, the wallet app is not allowed to require her to backup a seed phrase or any other data.

This is where I am stuck. I have the policy data but it looks like it needs to be backed up by the user. I looked at it and it’s a shamir shared secret, split from a random key. Therefore I don’t see how it can be recovered from the password and TOTP exclusively. How would you design the wallet app to fill these requirements?

Thanks

2 Likes

I see what you’re saying here. Let me break this down a bit and at least provide a perspective on this that may be helpful. As always feedback is appreciated!

Consider the case of a seed phrase style wallet (BIP32/39, etc.). A user must back up this seed phrase directly and you must also know how to derive a private key from the seed phrase itself as well. Think of MFKDF2 as being closer to “how to derive a private key from the seed phrase” rather than a user remembering storing a traditional seed phrase.

In this case, the wallet application is in charge of storing the policy information that Alice needs to properly derive her key. Given she can tell the wallet application “I am Alice” (i.e., via a username like alice123) she can be given her policy and input her password and TOTP code from the authenticator. This places minimal trust on the wallet application. That is, the wallet application solely has to host the policy and be available upon Alice’s request.

If Alice is extra cautious, she can also store a backup of the policy herself so that she doesn’t need to rely on any third party whatsoever. Likewise, as claimed in the original paper, Alice’s policy could even be stored on a public blockchain or other public storage medium (e.g., IPFS) so that she has redundancy.


If I, personally, were designing the wallet application, I would store the policy on behalf of Alice and provide this to her as needed. Though not necessary, defense in depth can be added by requiring Alice provide some subset of standardized authentication factors to retrieve her custom policy so that a malicious user, Bob, would have to know these factors to even retrieve the policy before brute-forcing Alice’s true private key. Likewise, I would offer Alice the ability to store a copy of her policy noting that for specific factors (such as TOTP) the policy will need updated over time.

Alice can easily store the policy in the cloud as she wishes too.

I am sorry but this seems that you are moving the goal posts. First of all, knowing the derivation path is the least of the worries since it is documented by ZIP-32.
Second, the grant submission was rather clear in its wording. I quote:

MFKDF2 has the potential of making novice Zcash users more comfortable with moving to self-custody by eliminating the need for seed phrases and other cumbersome manual key management strategies, allowing those users to experience the full privacy benefits of Zcash for the first time.

This is quite exciting and is the cornerstone of the grant. I don’t think you can change that promise.


Your suggestion is to store the users policy?

If I, personally, were designing the wallet application, I would store the policy on behalf of Alice and provide this to her as needed.

I would be extremely uncomfortable with this solution since it gives secret key material to a third party. Even if it is a share, it raises the issue of trust and IMO, such design does not qualify as self custody anymore.

Edit: Besides, if the solution is to split the secret and store in the cloud, it could be done with the seed phrase.

Could you think of another solution?

Thanks,
–h

Hi @hanh,

I appreciate you bringing up these concerns. It’s important to nail this for users to have proper security and enhanced UX at the same time. Let me reiterate a few points:

MFKDF does, indeed, remove the need for seed phrases and manual key management strategies. However, as with many other methods, there is still a need for something akin to a salt to be stored somewhere. The policy for a specific MFKDF does need to be known by the party who is deriving the key.

The secret material you are referencing is the MFKDF policy which can be safely given to a third party if a user wishes since this policy information is either encrypted or public metadata. The only way to compromise the encrypted information in the policy is by deriving the MFKDF key itself (this is what is proven in the original paper via the “entropy” result).

Happy to answer any more questions or address any concerns you may have, as always.

1 Like

Well, this statement contradicts itself. You begin by saying it removes the need for manual key management and then you say there is something that must be stored somewhere.

Mfkdf replaces the 24 word seed phrase with a multi kb policy. It is not clear to me where the win is in this scenario.

Maybe you can suggest another use case?

MFKDF replaces the need for a user to safely store secret information (a task which is a challenge for many users) with a task that the user and/or a 3rd party can do without risk of secret information being lost.

You are correct that without the policy available that the key cannot be derived. This is also true for a seed phrase, but a seed phrase itself must also be safe guarded.

The policy file should be safe guarded too, shouldn’t it?

@hanh Vivek here! There are no confidentiality requirements for the policy file. It’s designed to be stored in an untrusted cloud, or openly on IPFS or on a blockchain. Note that integrity/availability is still important, because losing the policy file could cause a loss of access to the wallet. Hope that helps! :slight_smile:

I think your intuition is valid but nuanced. My understanding is the policy could contain information useful to a malicious actor but only under certain circumstances. However, in most circumstances publishing the policy is generally acceptable, provided the nuances are well understood by the developer.

To reconcile this, I found the Reconstitution Example helpful. It suggests that while publishing the policy doesn’t directly compromise the keys, weak policies can weaken the barrier to key derivation. Effectively, a known policy with weak parameters might reduce the search space.

This creates a specific challenge with policy updates. Since the library allows the policy to change, your derived key is effectively only as secure as the weakest policy you have ever used.

Given this, I suspect that in a wallet context, allowing user driven policy updates introduces risks that may be better managed by simply rotating to a new key and policy. Clear documentation on these trade-offs will be essential for developers to adopt this safely.

P.S. These are just my observations as an outsider; I defer to the Multifactor team to correct any technical misunderstandings.

2 Likes

Huge supporter for this! UX improvements are key for bringing privacy to everyone, and from what I know the multifactor team is absolutely cracked.

2 Likes

I deliberated for a long time whether to include a MFKDF2 derived key based on password + totp as an alternate method without seed phrase. Finally, I think that the cons outweigh the pros, though it is a matter of opinion.

Pros

  • don’t need to save a 24 word seed phrase
  • can use any password
  • 2fa with totp provides additional security

Cons

  • the policy file becomes critical. Losing it means losing the key.
  • If the policy file is public (blockchain, shared drive),
    • Depending on the type of factors, the key can be brute forced. A typical totp key requires 1m attempts and could be broken in a few minutes. The security of a password can be high, but many passwords are very weak: 123456, password, etc. The wallet essentially becomes a brain wallet.
  • If the policy file is kept secret, it becomes a key management issue that we tried to avoid.

The user makes decisions that can greatly affect the security of their account. For instance, if they choose a simple password and puts the policy file in a public blockchain, I am afraid their funds are going to be easily stolen. Seed phrases have the same entropy as long as the users use a correct crypto RNG.

TLDR; I think with mfkdf2, some users will misuse the system, get their funds stolen and blame it on the app.

1 Like

Thanks for you feedback @hanh. I agree that TOTP + passwords are not a usecase I’d encourage any wallet to allow.

My intention when approving this grant was not to encourage users to choose a combination of weak factors. Rather it is to allow users to become comfortable using incredibly strong and convenient factors like Google or Apple passkeys while allowing them to strengthen those with additional or alternative factors to fit within their own risk models and comfort levels for both security and redundancy. I’d love to see a Zcash wallet explore this use case.

3 Likes