Thanks very much for your comments!
When user has gathered all the private keys, a new request is made which can then be verified by a script. The script then organizes all the information so the request can be validated by all nodes and hence the public key is changed.
This approach only works for channels such as email or SMS.
One node communicates with the user and so is convinced, but what about the rest of nodes? SMTP has DKIM, but it's optional. I'm not familiar with GSM, but I'd guess it's even worse there.
Here's the flow that I am assuming.
1. The user contacts the node with a request to change the public key associated with the account. The request includes a public key for the requester and the account id.
2. The node initiates a script and passes the IP address, a public id of the requester, and the account id to the script.
3. The script generates a private key/public key on the fly, opens a transaction on the blockchain with the following information, a fee charged to the requester (the user must have an account that can be used to pay the fee, the public key which will be used to validate that the requester received the secret over the channel, and the account id in question.
4. Once the fee for the request has completed, the script builds a receipt of itself (including the full code, a hash related to the code, a signed receipt from the original node that the transaction has completed, and other details which still need to be worked out).
5. The user (most likely through a wallet application) will provide the channel detail (such as an email address) which can be matched against a hash that is associated with the account channel (to be clear, the hash is NOT for a password. It is for the DETAILS associated with the channel such as the email address or in the case of SMS, the phone number. In the case of a separate private key, it could be a hash of the exact name used to identify the public key.
6. Once the script has the channel specific, it validates it against the hash and it passes the private key that was generated on the fly through the channel. This transaction is not public is any way. One OPEN issue is how to guarantee that the script does not leak the private key generated on the fly. I am still working on this.
7. The user now proceeds to respond to each request by the script to cover each channel registered with the account. Each channel would be a separate transaction. It is purposely time consuming and not too expensive so long as it is done infrequently. There should be a pricing mechanism that penalizes multiple attempts. It might be that you get 3 attempts or it might be that after 3 attempts, the price doubles unless you wait a longer period such as a month. The exact circumstances that are most effective would need to be worked out.
8. One the user has gathered all the private keys associated with each channel, they now make a request that includes the hash associated with the channel signed by the private key received. This request can now be validated against the transaction that has previously been committed by the script. If all signatures validate and all required hashes are included, then a new transaction is created with an additional fee that includes the fee, the account, all the signed hashes, and the new public key that should should be used from this time stamp (transaction id) on.
I hope that clarifies my assumptions. The public key will only be accepted when the transaction for the change is accepted by the blockchain. There are still open issues which I am working through.
It makes one BIG assumption. It assumes that scripts can be run reliably without being tampered with.
You said "compiled into byte code", but that doesn't guarantee anything. There are some techniques for this: homomorphic encryption, zero-knowledge proof, trusted execution environment.
I agree. The details for ensuring that script code runs reliably without being tampered with or leaking any private information is nontrivial. I am still working through the details. I will do another post with more details. I have NOT worked out all issues. Thanks for your suggestions on approaches. I have looked to zero-knowledge and reputation as the main strategy here. I have not yet looked at homomorphic encryption. I am not clear what you mean by trusted execution environment. If you have any suggestions for establishing a trusted, decentralized execution environment, I would be very interested. I have been primarily looking at solidity as an example scripting language.
Hopefully, the explanation above answers your questions here. My assumption is that MFA would include channels (verification over email, verification over SMS) or private keys or other channels that could be defined at a future point. The types of channels available would be limited to channels that can be effectively implemented through a script.
No, here the knowledge of a hash is enough for the attack.
[/quote]
It sounds to me like you are understanding the hash to be associated with a password so that an attacker can guess the password and so break the hash. Am I misunderstanding your point?
The hash represents the exact detail for the channel (the email address, the phone number for SMS, etc.) so even if they break the channel, they would still need to get ownership of the channel and further get ownership of all channels that are used to validate the identity. My assumption is here is that a fee per request, a limit on the frequency of requests, and reasonable default settings should go a long way to preventing the attacks you describe. The reasonable default settings is still an open issue. MFA will never be completely secure. My fallback is to rely on a notification when a change has gone through and a dispute process which will offer additional protections (the notification is available from the public blockchain itself, the dispute process needs to be detailed which I have not yet done).;