From 2d8c580dc2a334b42a970eee66aeefaafb99d5d3 Mon Sep 17 00:00:00 2001 From: Benjamin Schulte Date: Tue, 25 Jan 2022 09:59:57 +0100 Subject: [PATCH 01/12] EIP-0028 ErgoAuth --- eip-0028.md | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 eip-0028.md diff --git a/eip-0028.md b/eip-0028.md new file mode 100644 index 00000000..20189e8b --- /dev/null +++ b/eip-0028.md @@ -0,0 +1,137 @@ +# ErgoAuth: user authentication protocol between wallet applications and dApps + +* Author: @MrStahlfelge +* Status: Proposed +* Created: 25-Jan-2022 +* License: CC0 +* Forking: not needed + +## Contents +- [Description](#description) +- [Background And Motivation](#background-and-motivation) +- [ErgoPay Interaction Protocol](#ergoauth-authentication-protocol) +- [Data Formats](#data-formats) +- [Implementation in Mobile Wallet](#implementation-in-mobile-wallet) +- [Implementation in dApp](#implementation-in-dapp) +- [Benefits for dApps](#benefits-for-dapps) +- [Benefits for Mobile Wallets](#benefits-for-mobile-wallets) + +## Description +This EIP defines a standard for trustless authentication of users of a wallet app and an online +dApp. + +## Background And Motivation + +dApps might want to validate if dApp users are really who they pretend to be. This is especially +useful for dApps that grant certain abilities to holders of special tokens. At the moment, +proofing that a user owns a token can only be done by sending the token to a depositary address. +By sending the token, the user proofed to have access privileges to the token. +However, sending token around is not always desirable. Especially for valuable tokens, users might +not want to send it away, and doing two transactions (one to send it to the depositary address, one +to refund it back) costs both time and transaction fees. + +To overcome this, ErgoAuth proposes a way to authenticate users trustless to have access to certain +addresses storing a box. The protocol is trustless in both ways: The users don't need to trust +the dApp, because the dApp does not get access to funds or secrets. The dApp don't need to trust +the users or the wallet app, because it can validate the authentication keys. + +## ErgoAuth authentication protocol + +An authentication with ErgoAuth is driven by a dApp that needs to authenticate a user. + +1) The user enters the necessary information in the dApp's UI for the dApp to know if authentication +is necessary. For example, users might enter their P2PK address (or, instead of manually entering, +use ErgoPay to send the address to the dApp automatically). + +2) The dApp determines that authenticating the user is needed. For this, the dApp prepares a unique +message that the wallet app should sign with a user's private key, and an Ergo address that the user +needs to authenticate for. This might be a P2PK address, but in general P2S addresses can be also +used for authentication. + +3) The dApp presents an ErgoAuth link for the user to click and open the wallet app and a QR code +for mobile users to scan from within the wallet app. + +4) The wallet application parses the QR code/link data and obtains a +`ErgoAuthRequestUrl` to fetch the actual `ErgoAuthRequest` data from +(see [Data Formats](#data-formats) section). + +5) When `ErgoAuthRequest` is obtained, the wallet presents a screen showing that a dApp wants to +authenticate the user, and the address the request is for. The wallet app should also inform the +user that no funds or moved and no secrets will leave the device. + +6) When the user agrees, the wallet app signs the obtained message from ErgoAuthRequest and sends +the signed message to the ErgoAuthRequest's replyToUrl. + +7) The dApp validates the signed message. When successful, it can proceed with its flow. + +## Data Formats + +Wallet apps should be able to initiate ErgoAuth both by using URI schemes +(clickable links) or QR codes. + +`ergoauth://` + +An URL is provided without the https prefix. http communication is not allowed except for IP addresses +(in order to test within a local network). + +Examples: +* `ergoauth://sigmavalley.io/auth/2021-16b8-66c4-b800-6e52-8ce4` will make the wallet app request +`https://sigmausd.io/auth/2021-16b8-66c4-b800-6e52-8ce4` +* `ergoauth://192.168.0.1/auth` will make the wallet app request +`http://192.168.0.1/auth` + +#### Response body: ErgoAuthRequest + +The wallet application should request URL and obtain the following data (json format) + +``` +ErgoAuthRequest: + - signingMessage: String + - address: String + - userMessage: String (optional*) + - messageSeverity: String (optional) "INFORMATION", "WARNING" + - replyToUrl: String +``` + +If provided, the wallet application should show the **userMessage** and display the **messageSeverity** +in a suitable way. + +After signing is performed and the `SignedMessage` data is obtained, the +wallet must POST the following data to the dApp using **replyToUrl** from the +request (json format). + +``` +ErgoAuthResponse: + - signedMessage: String (base64) +``` + +In case there was an error building the ErgoAuthRequest on the dApp side, the dApp might reply +with an `ErgoAuthRequestError` to inform the user about the error: + +``` +ErgoAuthRequestError: + - userMessage: String +``` + +The wallet application will show the user message to the user. + + +## Implementation in wallet app +TODO + +## Implementation in dApp +TODO + +## Benefits for dApps +- A dApp or website don’t need to handle user's secrets (mnemonic/private keys), but can +safely validate if a user has access to certain Ergo addresses. +- dApp's users don't need to worry about security of their private keys as the +wallet guarantees they never leave the device + + +## Benefits for Wallet apps + +Any wallet team should consider supporting ErgoAuth in their wallet along +with basic wallet features. Users can participate in Ergo dApps and mobile +wallet team can receive service fees from those transactions. + From 4d4cc348270b5ec9dcb193e310b0abe88bb57a7b Mon Sep 17 00:00:00 2001 From: Benjamin Schulte Date: Tue, 25 Jan 2022 20:40:30 +0100 Subject: [PATCH 02/12] Update eip-0028.md --- eip-0028.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/eip-0028.md b/eip-0028.md index 20189e8b..2672d4c7 100644 --- a/eip-0028.md +++ b/eip-0028.md @@ -128,10 +128,3 @@ safely validate if a user has access to certain Ergo addresses. - dApp's users don't need to worry about security of their private keys as the wallet guarantees they never leave the device - -## Benefits for Wallet apps - -Any wallet team should consider supporting ErgoAuth in their wallet along -with basic wallet features. Users can participate in Ergo dApps and mobile -wallet team can receive service fees from those transactions. - From f2cd92b3657367a02814cea3a8aabeec1dad539c Mon Sep 17 00:00:00 2001 From: Benjamin Schulte Date: Wed, 26 Jan 2022 14:28:09 +0100 Subject: [PATCH 03/12] Apply suggestions from code review Co-authored-by: Alexander Slesarenko --- eip-0028.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eip-0028.md b/eip-0028.md index 2672d4c7..f8c95a0c 100644 --- a/eip-0028.md +++ b/eip-0028.md @@ -9,7 +9,7 @@ ## Contents - [Description](#description) - [Background And Motivation](#background-and-motivation) -- [ErgoPay Interaction Protocol](#ergoauth-authentication-protocol) +- [ErgoAuth authentication protocol](#ergoauth-authentication-protocol) - [Data Formats](#data-formats) - [Implementation in Mobile Wallet](#implementation-in-mobile-wallet) - [Implementation in dApp](#implementation-in-dapp) @@ -24,7 +24,7 @@ dApp. dApps might want to validate if dApp users are really who they pretend to be. This is especially useful for dApps that grant certain abilities to holders of special tokens. At the moment, -proofing that a user owns a token can only be done by sending the token to a depositary address. +proving that a user owns a token can only be done by sending the token to a depositary address. By sending the token, the user proofed to have access privileges to the token. However, sending token around is not always desirable. Especially for valuable tokens, users might not want to send it away, and doing two transactions (one to send it to the depositary address, one From a00645a003bd8d59bcaa0936adb8119582471992 Mon Sep 17 00:00:00 2001 From: Benjamin Schulte Date: Wed, 26 Jan 2022 14:48:05 +0100 Subject: [PATCH 04/12] Update eip-0028.md --- eip-0028.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/eip-0028.md b/eip-0028.md index f8c95a0c..b084f4e8 100644 --- a/eip-0028.md +++ b/eip-0028.md @@ -59,8 +59,8 @@ for mobile users to scan from within the wallet app. authenticate the user, and the address the request is for. The wallet app should also inform the user that no funds or moved and no secrets will leave the device. -6) When the user agrees, the wallet app signs the obtained message from ErgoAuthRequest and sends -the signed message to the ErgoAuthRequest's replyToUrl. +6) When the user agrees, the wallet app adds some own bytes to the obtained message from ErgoAuthRequest, +signs it and sends the signed message to the ErgoAuthRequest's replyToUrl. 7) The dApp validates the signed message. When successful, it can proceed with its flow. @@ -96,15 +96,22 @@ ErgoAuthRequest: If provided, the wallet application should show the **userMessage** and display the **messageSeverity** in a suitable way. -After signing is performed and the `SignedMessage` data is obtained, the +After signing is performed, the wallet must POST the following data to the dApp using **replyToUrl** from the request (json format). ``` ErgoAuthResponse: - - signedMessage: String (base64) + - signedMessage: String + - signature: String (Base64) ``` +`signedMessage`: Message containing the `signingMessage` sent by the dApp with additional bytes added by the +wallet. The addition of random bytes is done to prevent letting the user signing a message that might be used +for unwanted malicious tasks. + +`signature`: Output of signing `signedMessage + In case there was an error building the ErgoAuthRequest on the dApp side, the dApp might reply with an `ErgoAuthRequestError` to inform the user about the error: From bd5bfd9ef676de90138df3bc30259de07c6ecf05 Mon Sep 17 00:00:00 2001 From: Benjamin Schulte Date: Fri, 28 Jan 2022 21:34:35 +0100 Subject: [PATCH 05/12] Update eip-0028.md --- eip-0028.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/eip-0028.md b/eip-0028.md index b084f4e8..d693d7d1 100644 --- a/eip-0028.md +++ b/eip-0028.md @@ -44,9 +44,8 @@ is necessary. For example, users might enter their P2PK address (or, instead of use ErgoPay to send the address to the dApp automatically). 2) The dApp determines that authenticating the user is needed. For this, the dApp prepares a unique -message that the wallet app should sign with a user's private key, and an Ergo address that the user -needs to authenticate for. This might be a P2PK address, but in general P2S addresses can be also -used for authentication. +message that the wallet app should sign with a user's private key, and a SigmaBoolean that the user +needs to authenticate for. This might be a P2PK address wrapped in a SigmaBoolean. 3) The dApp presents an ErgoAuth link for the user to click and open the wallet app and a QR code for mobile users to scan from within the wallet app. @@ -58,6 +57,8 @@ for mobile users to scan from within the wallet app. 5) When `ErgoAuthRequest` is obtained, the wallet presents a screen showing that a dApp wants to authenticate the user, and the address the request is for. The wallet app should also inform the user that no funds or moved and no secrets will leave the device. +In a future enhancement, the Auth Request could be relayed to a Cold wallet device. This is an enhancement +of EIP-0019 and would not change ErgoAuth protocol. 6) When the user agrees, the wallet app adds some own bytes to the obtained message from ErgoAuthRequest, signs it and sends the signed message to the ErgoAuthRequest's replyToUrl. @@ -87,7 +88,7 @@ The wallet application should request URL and obtain the following data (json fo ``` ErgoAuthRequest: - signingMessage: String - - address: String + - sigmaBoolean: String (base64 from serialized SigmaBoolean) - userMessage: String (optional*) - messageSeverity: String (optional) "INFORMATION", "WARNING" - replyToUrl: String @@ -103,14 +104,14 @@ request (json format). ``` ErgoAuthResponse: - signedMessage: String - - signature: String (Base64) + - proof: String (Base64) ``` `signedMessage`: Message containing the `signingMessage` sent by the dApp with additional bytes added by the wallet. The addition of random bytes is done to prevent letting the user signing a message that might be used for unwanted malicious tasks. -`signature`: Output of signing `signedMessage +`proof`: Output of signing `signedMessage` In case there was an error building the ErgoAuthRequest on the dApp side, the dApp might reply with an `ErgoAuthRequestError` to inform the user about the error: @@ -133,5 +134,6 @@ TODO - A dApp or website don’t need to handle user's secrets (mnemonic/private keys), but can safely validate if a user has access to certain Ergo addresses. - dApp's users don't need to worry about security of their private keys as the -wallet guarantees they never leave the device +wallet guarantees they never leave the device. This is especially true if authentication +is done with a cold device. From 0a31b3c7594ff8c318b70abd692245aa33f7b505 Mon Sep 17 00:00:00 2001 From: Benjamin Schulte Date: Tue, 5 Apr 2022 15:33:19 +0200 Subject: [PATCH 06/12] Update eip-0028.md --- eip-0028.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/eip-0028.md b/eip-0028.md index d693d7d1..1287b5d4 100644 --- a/eip-0028.md +++ b/eip-0028.md @@ -94,6 +94,8 @@ ErgoAuthRequest: - replyToUrl: String ``` +(Remark: An Ergo p2pk address is a SigmaBoolean, so authenticating a wallet address is possible with this) + If provided, the wallet application should show the **userMessage** and display the **messageSeverity** in a suitable way. @@ -128,7 +130,10 @@ The wallet application will show the user message to the user. TODO ## Implementation in dApp -TODO + +Ergo Appkit: ErgoAuthUtils helper class adds helper methods for server side applications. ErgoAuthSpec demonstrates the use. + +dApp: TODO ## Benefits for dApps - A dApp or website don’t need to handle user's secrets (mnemonic/private keys), but can From ccfe51957f75e24f0750b2813d694bd938851f7e Mon Sep 17 00:00:00 2001 From: Benjamin Schulte Date: Tue, 19 Apr 2022 22:38:39 +0200 Subject: [PATCH 07/12] Update eip-0028.md --- eip-0028.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/eip-0028.md b/eip-0028.md index 1287b5d4..2469528c 100644 --- a/eip-0028.md +++ b/eip-0028.md @@ -127,13 +127,13 @@ The wallet application will show the user message to the user. ## Implementation in wallet app -TODO +[Ergo Wallet App #112](https://github.com/ergoplatform/ergo-wallet-app/issues/112) ## Implementation in dApp -Ergo Appkit: ErgoAuthUtils helper class adds helper methods for server side applications. ErgoAuthSpec demonstrates the use. +[Ergo Appkit #157](https://github.com/ergoplatform/ergo-appkit/pull/157) -dApp: TODO +dApp: Added to [ErgoPay backend example](https://github.com/MrStahlfelge/ergopay-server-example/commit/9271f0ef890d6c8e63789f6c82b65595efe8549a) ## Benefits for dApps - A dApp or website don’t need to handle user's secrets (mnemonic/private keys), but can From a66e9babdd3e9068a8f076fcf571a00a7e6ac8f5 Mon Sep 17 00:00:00 2001 From: Benjamin Schulte Date: Tue, 5 Jul 2022 17:19:21 +0200 Subject: [PATCH 08/12] EIP-0028 Add hostname to signed message --- eip-0028.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/eip-0028.md b/eip-0028.md index 2469528c..9610323c 100644 --- a/eip-0028.md +++ b/eip-0028.md @@ -97,7 +97,8 @@ ErgoAuthRequest: (Remark: An Ergo p2pk address is a SigmaBoolean, so authenticating a wallet address is possible with this) If provided, the wallet application should show the **userMessage** and display the **messageSeverity** -in a suitable way. +in a suitable way. It should also show the replyToUrl's hostname so that the user knows to where +the authentication is sent. After signing is performed, the wallet must POST the following data to the dApp using **replyToUrl** from the @@ -111,7 +112,9 @@ ErgoAuthResponse: `signedMessage`: Message containing the `signingMessage` sent by the dApp with additional bytes added by the wallet. The addition of random bytes is done to prevent letting the user signing a message that might be used -for unwanted malicious tasks. +for unwanted malicious tasks. Besides random based, the signed message must also contain the replyToUrl's +hostname. This way, the dApp can check if an authentication was done by the user for that dApp, or if another +middleman reuses an authentication. `proof`: Output of signing `signedMessage` From 9d7e1c2406168e86137af5ebb96bc267f385f1f9 Mon Sep 17 00:00:00 2001 From: Benjamin Schulte Date: Wed, 13 Jul 2022 14:10:42 +0200 Subject: [PATCH 09/12] ErgoAuth: use signingMessage before 0-byte as user prompt, restrict replyToUrl to the same host as requestUrl --- eip-0028.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/eip-0028.md b/eip-0028.md index 9610323c..3c1901ab 100644 --- a/eip-0028.md +++ b/eip-0028.md @@ -96,9 +96,15 @@ ErgoAuthRequest: (Remark: An Ergo p2pk address is a SigmaBoolean, so authenticating a wallet address is possible with this) +The **signingMessage** is a String that is not user-friendly to read in general, as it might contain +information the dApp adds to make it unique. If the signingMessage containsa 0-byte character (unicode 0000), +the part of the signingMessage befire this sign is interpreted as the user prompt what he is going to sign for +and must be shown to the user. + If provided, the wallet application should show the **userMessage** and display the **messageSeverity** in a suitable way. It should also show the replyToUrl's hostname so that the user knows to where -the authentication is sent. +the authentication is sent. The replyToUrl's hostname must be the same as the one the request was +fetched from - a wallet application should verify that. After signing is performed, the wallet must POST the following data to the dApp using **replyToUrl** from the From 863b29ab8d66d4ea295eb1f6bca1a76b13a01f3f Mon Sep 17 00:00:00 2001 From: Benjamin Schulte Date: Fri, 15 Jul 2022 11:17:06 +0200 Subject: [PATCH 10/12] ErgoAuth: typo fixed --- eip-0028.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eip-0028.md b/eip-0028.md index 3c1901ab..4ef58b08 100644 --- a/eip-0028.md +++ b/eip-0028.md @@ -97,7 +97,7 @@ ErgoAuthRequest: (Remark: An Ergo p2pk address is a SigmaBoolean, so authenticating a wallet address is possible with this) The **signingMessage** is a String that is not user-friendly to read in general, as it might contain -information the dApp adds to make it unique. If the signingMessage containsa 0-byte character (unicode 0000), +information the dApp adds to make it unique. If the signingMessage contains 0-byte character (unicode 0000), the part of the signingMessage befire this sign is interpreted as the user prompt what he is going to sign for and must be shown to the user. From 978372ae7ea03abd8ab9be2032bb3d9ace53610f Mon Sep 17 00:00:00 2001 From: Benjamin Schulte Date: Mon, 24 Oct 2022 10:52:24 +0200 Subject: [PATCH 11/12] EIP-28 support for cold wallets --- eip-0028.md | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/eip-0028.md b/eip-0028.md index 4ef58b08..e35f0eb3 100644 --- a/eip-0028.md +++ b/eip-0028.md @@ -1,8 +1,9 @@ # ErgoAuth: user authentication protocol between wallet applications and dApps * Author: @MrStahlfelge -* Status: Proposed +* Status: Implemented * Created: 25-Jan-2022 +* Last change: 24-Oct-2022 * License: CC0 * Forking: not needed @@ -98,7 +99,7 @@ ErgoAuthRequest: The **signingMessage** is a String that is not user-friendly to read in general, as it might contain information the dApp adds to make it unique. If the signingMessage contains 0-byte character (unicode 0000), -the part of the signingMessage befire this sign is interpreted as the user prompt what he is going to sign for +the part of the signingMessage before this sign is interpreted as the user prompt what he is going to sign for and must be shown to the user. If provided, the wallet application should show the **userMessage** and display the **messageSeverity** @@ -134,6 +135,25 @@ ErgoAuthRequestError: The wallet application will show the user message to the user. +## Cold wallet support +Similar to [EIP-0019](eip-0019.md) for signing transactions from devices not connected to the internet +("cold wallets"), ErgoAuth can be used to sign messages from cold wallets. This is transparent for +dApps and handled by the wallet connected to the internet ("hot wallet"). + +For this, the `ErgoAuthRequest` must be transferred to the cold wallet via files or QR codes and +the `ErgoAuthResponse` must be transferred back the same way. + +The [interchange format to transfer chunks between hot wallet and cold wallet is similar to the one +defined in EIP-0019](eip-0019.md#interchange-format), with name "EARQ" for ErgoAuthRequest and "EARS" +for ErgoAuthResponse. Examples: + + {"EARQ":"{\"signingMessage\":\"....\",\"sigmaBoolean\":\"...\",\"userMessage\":\"...\",...}"} + + {"EARS":"{\"signedMessage\":\"....\",\"proof\":\"...\"} + +The ErgoAuthRequest's `replyToUrl` field must be omitted to save data bandwidth. + +Chunking as described in EIP-0019 is supported as well. ## Implementation in wallet app [Ergo Wallet App #112](https://github.com/ergoplatform/ergo-wallet-app/issues/112) @@ -142,7 +162,9 @@ The wallet application will show the user message to the user. [Ergo Appkit #157](https://github.com/ergoplatform/ergo-appkit/pull/157) -dApp: Added to [ErgoPay backend example](https://github.com/MrStahlfelge/ergopay-server-example/commit/9271f0ef890d6c8e63789f6c82b65595efe8549a) +dApp: +* [ErgoPay backend example](https://github.com/MrStahlfelge/ergopay-server-example/commit/9271f0ef890d6c8e63789f6c82b65595efe8549a) +* Login to https://www.paideia.im/ ## Benefits for dApps - A dApp or website don’t need to handle user's secrets (mnemonic/private keys), but can From 5b1eeb1bff86960a10f0a4dcb35259679dadb434 Mon Sep 17 00:00:00 2001 From: Benjamin Schulte Date: Mon, 5 Dec 2022 10:59:26 +0100 Subject: [PATCH 12/12] Clarified middleman prevention addition --- eip-0028.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/eip-0028.md b/eip-0028.md index e35f0eb3..282f1140 100644 --- a/eip-0028.md +++ b/eip-0028.md @@ -62,9 +62,12 @@ In a future enhancement, the Auth Request could be relayed to a Cold wallet devi of EIP-0019 and would not change ErgoAuth protocol. 6) When the user agrees, the wallet app adds some own bytes to the obtained message from ErgoAuthRequest, -signs it and sends the signed message to the ErgoAuthRequest's replyToUrl. +signs it and sends the signed message to the ErgoAuthRequest's replyToUrl. The added bytes include +the host address the authentication request was fetched from, added right after the message defined +by the dApp. This way, dApp can check if a user authenticated via the right domain and there is no +middleman. -7) The dApp validates the signed message. When successful, it can proceed with its flow. +8) The dApp validates the signed message. When successful, it can proceed with its flow. ## Data Formats @@ -120,8 +123,8 @@ ErgoAuthResponse: `signedMessage`: Message containing the `signingMessage` sent by the dApp with additional bytes added by the wallet. The addition of random bytes is done to prevent letting the user signing a message that might be used for unwanted malicious tasks. Besides random based, the signed message must also contain the replyToUrl's -hostname. This way, the dApp can check if an authentication was done by the user for that dApp, or if another -middleman reuses an authentication. +hostname right after the original signing message. This way, the dApp can check if an authentication was done by +the user for that dApp, or if another middleman reuses an authentication. `proof`: Output of signing `signedMessage`