From 8a9468ee8c44ca4c68884d59f455a5a6d11f48c1 Mon Sep 17 00:00:00 2001 From: Marek Date: Fri, 8 Jul 2022 17:06:51 +0800 Subject: [PATCH 1/6] Create xxxx-auth-slates.md Initial draft of the auth-slates proposal --- text/xxxx-auth-slates.md | 166 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 text/xxxx-auth-slates.md diff --git a/text/xxxx-auth-slates.md b/text/xxxx-auth-slates.md new file mode 100644 index 0000000..b28de63 --- /dev/null +++ b/text/xxxx-auth-slates.md @@ -0,0 +1,166 @@ + +- Title: auth-slates +- Authors: [Marek Narozniak](https://mareknarozniak.com/) +- Start date: July 7, 2022 +- RFC PR: Edit if merged: [mimblewimble/grin-rfcs#0000](https://github.com/mimblewimble/grin-rfcs/pull/0000) +- Tracking issue: [Edit if merged with link to tracking github issue] + +--- + +## Summary +[summary]: #summary + +We propose a protocol allowing to use slatepack-encoded signatures of authentication purposes. Unlike in case of the EVM-based blockchains where regular signature is used for authentication, our protocol works without revealing the slatepack address. + +## Motivation +[motivation]: #motivation + +GRIN digital cash project has managed to gather an online community of people spread around various online services, web boards and messenger apps. Apart from the [GRIN Forum](https://forum.grin.mw/) there is no official place of interaction. This is due to a general tendency to resist centralization which is very common among the GRIN community members. We have already witnessed birth of first GRIN-specific websites, such as [grinnode.live](https://grinnode.live/) and [Slatepacks Market](https://slatepacks.com/). It seems reasonable to assume there will be many more constructed in the future. + +Assuming there will be more GRIN-related online communities and it is common for GRIN enthusiasts to have a GRIN wallet, it seems logical to create a feature allowing authentication via the wallet. Especially that such features are already common in other blockchains [ref needed]. But unlike other blockchains, the "GRIN way" of implementing such features should embrace on of the core GRIN values, which is privacy. In this RFC we propose a protocol that allows the wallet to act as an alternative of a password manager allowing GRIN users to authenticate to online services without revealing their slatepack addresses. + +## Community-level explanation +[community-level-explanation]: #community-level-explanation + +This feature will allow you to use GRIN wallet to register and login to online services that support it. In this section we will briefly describe the user experience we have in mind. + +When you wish to register to some website. +1. You open the website registration form you have only single input `username` where you provide your desired username and you click `next` to submit the form. +2. Service will validate your input and inform you if the username is taken. If not, it will display a slatepack message related to your registration as well as textarea input to provide a response and a `sign-up` button. +3. In your wallet you run `grin-wallet register` command. The wallet asks you to paste the slatepack from the website. +4. After you submit the registration slatepack, wallet shows username and URL of the service and asks you if this information is valid. You may cancel the operation or proceed. +5. If you decide to proceed, wallet will provide a response slatepack which you copy. +6. You paste the response slatepack to registration form textarea and click `sign-up`. +7. The service informs you if the account was successfully created. + +When you wish to login to a service, you proceed as follows. +1. You open the website you wish to authenticate. There is a textarea input and `sign-in` button. +2. In your wallet you run `grin-wallet login`. +3. Wallet displays list of accounts with usernames and URLs of the services. You select one you wish to use and submit. +4. Wallet will display a login slatepack which you copy. +5. In the website you paste the slatepack and click `sign-in`. + +Your accounts are going to be stored locally but even if you lose your database, as long as you have your wallet recovery phrase and remember the URLs of the services you registered and your usernames your accounts can be recovered using `grin-wallet register --recover` command. + +This change will not break anything previously included in the wallet. We propose it to be based on additional key derivation mechanisms. + +## Reference-level explanation +[reference-level-explanation]: #reference-level-explanation + +This section will provide a more technical description of how we propose the auth slates to work. We consider two parties, `Steven` for service and `Ursula` for the user. + +### Registration protocol + +Ursula wishes to create the account. She fills in the web form and clicks `next`. Steven generates a slatepack with the following data encoded. + +```json +{ + "version_info": { + "version": 1 + }, + "authentication": "registration", + "data": { + "username": "picked-username", + "url": "url-of-the-service" + } +} +``` + +Ursula copies the slatepack, runs `grin-wallet register` and pastes it in as the input. Ursula's wallet will generate a new ED25519 private key of the following form + +``` +key = H(seed || username || url) +``` + +where `username` and `url` come from the registration slatepack and `seed` is the wallet decrypted seed key. From that it follows that only Ursula, as the party capable of decrypting the wallet seed is capable of creating this authentication key. + +Once key is generated, Ursula's wallet will generate following slatepack + +```json +{ + "version_info": { + "version": 1 + }, + "authentication": "registration-response", + "data": { + "username": "picked-username", + "url": "url-of-the-service", + "signature": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + } +} +``` + +which has `signature` field in addition being a digital signature of the login request. + +Ursula submits this slatepack into the web form and clicks `sign-up`. The online service will + +1. Check if signature is valid +2. Extract the key from the signature and save it own database along with the associated username +3. Inform Ursula of the successful registration + +### Login protocol + +Now Ursula wishes to login to Steven's online service. She starts by opening the website and sees the login form composed of the slatepack input textarea and `sign-in` button. + +Ursula runs `grin-wallet login`, picks the account the wishes to use and approves. The exact way of achieving this depends on the implementation and is not relevant here. It could be an interactive UI or could be command line options. Once approved, wallet will display a slatepack representing following encoded slate. + +```json +{ + "version_info": { + "version": 1 + }, + "authentication": "login", + "data": { + "username": "picked-username", + "url": "url-of-the-service", + "timestamp": 1657270059, + "signature": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + } +} +``` + +The slatepack contains current timestamp as a measure of preventing repetition attacks. Ursula proceeds by pasting it in the web form. Steven's website will + +1. Extract the key from the signature, check if it figures in the database. +2. If the key does not figure in the database the authentication will fail. If it does figure associated to provided username it will check if signature matches. +3. If the signature does not match the authentication will fail. Otherwise it will succed and create a server-side session for Ursula's account. + +### Account recovery protocol + +It might occurr that user loses the wallet database. As long as the wallet seed is backed up, account can be recreated as the private signing keys for authentication are derived from the wallet seed and username and URLs. If user remembers the services and usernames wallet can always recreate the signing keys. + +The minimal implementation of this feature would not require any database at all, user would need to provide username and URL to the wallet every time wishes to login. This would not require registration command and thus neither the recovery command. + +## Drawbacks +[drawbacks]: #drawbacks + +[TODO] + +## Rationale and alternatives +[rationale-and-alternatives]: #rationale-and-alternatives + +Alternatively one could login by signing the login information using the slatepack address key. The disadvantage of that is the slatepack address would become known and associated with the account. In certain scenarios that might be a desired feature. + +## Prior art +[prior-art]: #prior-art + +[TODO] + +## Unresolved questions +[unresolved-questions]: #unresolved-questions + +1. We should consider other forms of login. For instance, instead of deriving a key and providing a signature using this derived key we could use a zero-knowledge proof that owner of some wallet wishes to register to this particular service. This way no additional key is required as the zero-knowledge proof would prove there exists a signature without revealing the actual signature. +2. We should consider other way of deriving the authentication keys. +3. We should consider some common attack scenarios to evaluate the security aspects of this proposal. + +## Future possibilities +[future-possibilities]: #future-possibilities + +Implementing this proposal could result with improved privacy of GRIN users and stronger connection of the GRIN tech with the web. It could possibly motivate other GRIN-related projects for online communities. + +In the future we could consider integrating zero-knowledge proof mechanism such as [zk-SNARK](https://www.investopedia.com/terms/z/zksnark.asp) to allow one to link online accounts. The current proposal makes it impossible to link users. In general this is considered an advantage, however in certain scenarios one might want to prove that same username in different services is claimed by the owner of the same wallet. A zero-knowledge proof such as zk-SNARK could prove that both keys are derived from same seed without revealing the seed. + +## References +[references]: #references + +- [Keybase discussion](keybase://chat/grincoin#cryptography/5744) From 4b86f55d85904ec478a843847532391e1a8faa49 Mon Sep 17 00:00:00 2001 From: Marek Date: Fri, 8 Jul 2022 17:08:47 +0800 Subject: [PATCH 2/6] Update xxxx-auth-slates.md included a reference to the PR --- text/xxxx-auth-slates.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/xxxx-auth-slates.md b/text/xxxx-auth-slates.md index b28de63..00dfabf 100644 --- a/text/xxxx-auth-slates.md +++ b/text/xxxx-auth-slates.md @@ -2,7 +2,7 @@ - Title: auth-slates - Authors: [Marek Narozniak](https://mareknarozniak.com/) - Start date: July 7, 2022 -- RFC PR: Edit if merged: [mimblewimble/grin-rfcs#0000](https://github.com/mimblewimble/grin-rfcs/pull/0000) +- RFC PR: Edit if merged: [mimblewimble/grin-rfcs#90](https://github.com/mimblewimble/grin-rfcs/pull/90) - Tracking issue: [Edit if merged with link to tracking github issue] --- From 76ab0c8b948d903b43d4e37b309a2e76b49d74cc Mon Sep 17 00:00:00 2001 From: marekyggdrasil Date: Sun, 10 Jul 2022 13:04:12 +0200 Subject: [PATCH 3/6] Double hashing to prevent preimage attack --- text/xxxx-auth-slates.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/text/xxxx-auth-slates.md b/text/xxxx-auth-slates.md index 00dfabf..f7a5995 100644 --- a/text/xxxx-auth-slates.md +++ b/text/xxxx-auth-slates.md @@ -69,10 +69,10 @@ Ursula wishes to create the account. She fills in the web form and clicks `next` Ursula copies the slatepack, runs `grin-wallet register` and pastes it in as the input. Ursula's wallet will generate a new ED25519 private key of the following form ``` -key = H(seed || username || url) +key = H(H(seed || username || url) || username || url) ``` -where `username` and `url` come from the registration slatepack and `seed` is the wallet decrypted seed key. From that it follows that only Ursula, as the party capable of decrypting the wallet seed is capable of creating this authentication key. +where `username` and `url` come from the registration slatepack and `seed` is the wallet decrypted seed key. From that it follows that only Ursula, as the party capable of decrypting the wallet seed is capable of creating this authentication key. The double hashing prevents someone from getting a wallet seed using []preimage attack](https://en.wikipedia.org/wiki/Preimage_attack). Once key is generated, Ursula's wallet will generate following slatepack @@ -149,10 +149,16 @@ Alternatively one could login by signing the login information using the slatepa ## Unresolved questions [unresolved-questions]: #unresolved-questions +General review of the idea: + 1. We should consider other forms of login. For instance, instead of deriving a key and providing a signature using this derived key we could use a zero-knowledge proof that owner of some wallet wishes to register to this particular service. This way no additional key is required as the zero-knowledge proof would prove there exists a signature without revealing the actual signature. 2. We should consider other way of deriving the authentication keys. 3. We should consider some common attack scenarios to evaluate the security aspects of this proposal. +Low-level: + +1. Is double hashing sufficient to prevent getting someone else's wallet seed using the [preimage attack](https://en.wikipedia.org/wiki/Preimage_attack)? + ## Future possibilities [future-possibilities]: #future-possibilities From e7bd961439724dbbdf9ac27b737ad361b19398ec Mon Sep 17 00:00:00 2001 From: marekyggdrasil Date: Sun, 10 Jul 2022 13:20:17 +0200 Subject: [PATCH 4/6] Shielded data in login slatepack --- text/xxxx-auth-slates.md | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/text/xxxx-auth-slates.md b/text/xxxx-auth-slates.md index f7a5995..b7016d7 100644 --- a/text/xxxx-auth-slates.md +++ b/text/xxxx-auth-slates.md @@ -102,7 +102,19 @@ Ursula submits this slatepack into the web form and clicks `sign-up`. The online Now Ursula wishes to login to Steven's online service. She starts by opening the website and sees the login form composed of the slatepack input textarea and `sign-in` button. -Ursula runs `grin-wallet login`, picks the account the wishes to use and approves. The exact way of achieving this depends on the implementation and is not relevant here. It could be an interactive UI or could be command line options. Once approved, wallet will display a slatepack representing following encoded slate. +Ursula runs `grin-wallet login`, picks the account the wishes to use and approves. The exact way of achieving this depends on the implementation and is not relevant here. It could be an interactive UI or could be command line options. Once approved, wallet will generate a symmetric encryption key + +``` +symmkey = H(pubkey || username) +``` + +where `pubkey` is the ED25519 public key associated to `key`. Then a message + +``` +msg = picked-username || timestamp || url-of-the-service || random-data +``` + +is padded to fixed length and encrypted using `symmkey` resulting with `encrypted-message`. We also sign it using the `key`. With that following slatepack is constructed and displayed to Ursula ```json { @@ -110,20 +122,17 @@ Ursula runs `grin-wallet login`, picks the account the wishes to use and approve "version": 1 }, "authentication": "login", - "data": { - "username": "picked-username", - "url": "url-of-the-service", - "timestamp": 1657270059, - "signature": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - } + "data": "{content of encrypted-message}", + "signature": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" } ``` The slatepack contains current timestamp as a measure of preventing repetition attacks. Ursula proceeds by pasting it in the web form. Steven's website will -1. Extract the key from the signature, check if it figures in the database. -2. If the key does not figure in the database the authentication will fail. If it does figure associated to provided username it will check if signature matches. -3. If the signature does not match the authentication will fail. Otherwise it will succed and create a server-side session for Ursula's account. +1. Extract the `pubkey` from the signature, check if it figures in the database. If the key does not figure in the database the authentication will fail. +2. Find the `username` associated to this `pubkey` in the database. +3. Derive the `symmkey` and decrypt `encrypted-message` to recover `msg`. +4. From `msg` the fields `username` and `url-of-the-service` will be validated if match request and database records. Also `timestamp` will be checked if it is recent enough. I all this succeeds login will succeed and a server-side session will be created for Ursula's account. ### Account recovery protocol @@ -154,6 +163,7 @@ General review of the idea: 1. We should consider other forms of login. For instance, instead of deriving a key and providing a signature using this derived key we could use a zero-knowledge proof that owner of some wallet wishes to register to this particular service. This way no additional key is required as the zero-knowledge proof would prove there exists a signature without revealing the actual signature. 2. We should consider other way of deriving the authentication keys. 3. We should consider some common attack scenarios to evaluate the security aspects of this proposal. +4. We should consider if slatepacks should be shielded or not. For transactions slatepacks are potentially exchanged via third party service, but for the login use-case we might be able to assume exchange is direct. Low-level: From 2677a7b517009f939f812abf195802d767d0fcab Mon Sep 17 00:00:00 2001 From: marekyggdrasil Date: Sun, 10 Jul 2022 13:21:40 +0200 Subject: [PATCH 5/6] Disadvantage text suggested by Anonymous. --- text/xxxx-auth-slates.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/xxxx-auth-slates.md b/text/xxxx-auth-slates.md index b7016d7..387a6e2 100644 --- a/text/xxxx-auth-slates.md +++ b/text/xxxx-auth-slates.md @@ -143,7 +143,7 @@ The minimal implementation of this feature would not require any database at all ## Drawbacks [drawbacks]: #drawbacks -[TODO] +1. In order to be able to recover the data user needs to remember own username and login of the service. This is a minor disadvantage as compared to a traditional authentication method user is required to recall an additional piece of information - password. ## Rationale and alternatives [rationale-and-alternatives]: #rationale-and-alternatives From 21c5ca59aa7823a25e543a2087c5d40cc3204803 Mon Sep 17 00:00:00 2001 From: marekyggdrasil Date: Sun, 10 Jul 2022 13:22:32 +0200 Subject: [PATCH 6/6] Included Anonymous as a co-author --- text/xxxx-auth-slates.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/xxxx-auth-slates.md b/text/xxxx-auth-slates.md index 387a6e2..c71e708 100644 --- a/text/xxxx-auth-slates.md +++ b/text/xxxx-auth-slates.md @@ -1,6 +1,6 @@ - Title: auth-slates -- Authors: [Marek Narozniak](https://mareknarozniak.com/) +- Authors: [Marek Narozniak](https://mareknarozniak.com/), [Anonymous](https://forum.grin.mw/u/anynomous/) - Start date: July 7, 2022 - RFC PR: Edit if merged: [mimblewimble/grin-rfcs#90](https://github.com/mimblewimble/grin-rfcs/pull/90) - Tracking issue: [Edit if merged with link to tracking github issue]