-
Notifications
You must be signed in to change notification settings - Fork 9
Wallet login #68
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Wallet login #68
Changes from 7 commits
a20fcc3
3fa744a
39da7ac
9fa1e28
26e0a5e
433ec0c
479a9ba
13708f0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,2 @@ | ||
| .idea/ | ||
| *~ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,116 @@ | ||
| - FIP: 68 | ||
| - title: Login into Portable account with metamask | ||
| - author: Sabyasachi Patra, @asabya | ||
| - status: draft | ||
| - created: 2023-03-01 | ||
|
|
||
| # Summary | ||
| Addressing web3 login workflow to portable account where users can retrieve their wallet in a decentralized manner from browser with metamask. | ||
|
|
||
| # Context, motivation and guide level explanation | ||
|
|
||
| The solution worked out here allows to log in to the user account from any browser into the same account described in [FIP-59](https://github.com/fairDataSociety/FIPs/blob/master/text/0059-portable-account.md) created with | ||
| [fdp-create-account](https://github.com/fairDataSociety/fdp-create-account) project. | ||
|
|
||
| # Reference-level explanation | ||
|
|
||
| For the login to work with metamask, user should already have a portable account created with [fdp-create-account](https://github.com/fairDataSociety/fdp-create-account). | ||
|
|
||
| As we know while creating a portable account users can provide a 12 word mnemonic phrase for the portable wallet or a 12 word mnemonic will be generated for them. | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we use portable account term for the account uploaded and encrypted in Swarm. In order to use that you only need to provide
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I am talking about the account creation process here. |
||
|
|
||
| This solution starts with importing the portable wallet into metamask. After that it is a two-step process | ||
|
||
|
|
||
| ## Step 1: | ||
| ```go | ||
| ConnectPortableAccountWithWallet(userName, passPhrase, addressHex, signature string) error | ||
asabya marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| ``` | ||
|
|
||
| This function will get the portable wallet (wallet seed) and re-upload an alternate socTopic described later | ||
|
|
||
| ## Step 2: | ||
| ```go | ||
| LoginWithWallet(addressHex, signature string) (*user.Info, error) | ||
| ``` | ||
|
|
||
| This function will get the encrypted portable wallet (wallet seed) and username from the alternate socTopic and decrypt it with the signature provided by the user. | ||
|
|
||
|
|
||
| ## Uploading portable wallet (wallet seed) to Ethereum Swarm to an alternate socTopic | ||
|
|
||
| In FIP-59 we have discussed, about the socTopic which is a topic in the swarm where the portable account is stored. In this solution we will be using an alternate socTopic, but with the same logic, to store the wallet seed. | ||
| ``` | ||
| socTopic = H(fdpLoginVersion + portableWalletAddress + signature) | ||
| ``` | ||
|
|
||
| Where `portableWalletAddress` and the `signature` will be provided by the user. As we have already imported the portable wallet into metamask, we can get the `portableWalletAddress` from there. The `signature` will be generated by signing the `portableWalletAddress` with metamask with the portable wallet. | ||
asabya marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ## Wallet seed encryption | ||
| In FIP-59 we have discussed, about the encryption of wallet seed and storing it in a chunk. | ||
|
|
||
| - We will first generate FIP-59 socTopic with username and password provided by the user. | ||
| - Then download the wallet seed chunk from FIP-59 socTopic and decrypt it with the password provided by the user. | ||
|
|
||
| We have the seed now. We will store the username with the seed for identifying the user while logging in with metamask. | ||
|
|
||
| ### Creating the chunk | ||
|
|
||
| The content of the chunk will look something lite this | ||
|
|
||
| ``` | ||
| SEED + USERNAME_SIZE + USERNAME + RANDOM_DATA | ||
| ``` | ||
|
|
||
| We store the username length in 8 bytes, then the username and then the random data. | ||
asabya marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| The `SEED + USERNAME_SIZE + USERNAME` will be padded with random data with byte length `CHUNK_SIZE - SEED_SIZE - IV_LENGTH - USERNAME_LENGTH - USERNAME_SIZE`. | ||
|
|
||
| *** `USERNAME_SIZE` is 8 bytes, `USERNAME_LENGTH` is the length of the username provided by the user. | ||
asabya marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| The resulted data will be encrypted with AES, where the encryption key is the SHA256 hash of the signature. | ||
|
|
||
| ```go | ||
| func (*Info) PadSeedName(seed []byte, username string, passphrase string) ([]byte, error) { | ||
| usernameLength := len(username) | ||
| endIndexBytes := make([]byte, nameSize) | ||
| binary.LittleEndian.PutUint64(endIndexBytes, uint64(usernameLength)) | ||
| paddingLength := utils.MaxChunkLength - aes.BlockSize - seedSize - nameSize - usernameLength | ||
| randomBytes, err := utils.GetRandBytes(paddingLength) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| chunkData := make([]byte, 0, utils.MaxChunkLength) | ||
| chunkData = append(chunkData, seed...) | ||
| chunkData = append(chunkData, endIndexBytes...) | ||
| chunkData = append(chunkData, []byte(username)...) | ||
| chunkData = append(chunkData, randomBytes...) | ||
| encryptedBytes, err := utils.EncryptBytes([]byte(passphrase), chunkData) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("seed padding failed: %w", err) | ||
| } | ||
| return encryptedBytes, nil | ||
| } | ||
| ``` | ||
|
|
||
| ### Getting seed back from the chunk | ||
|
|
||
| We decrypt the chunk with the same signature and then get the seed and username from the decrypted data. | ||
|
|
||
| ```go | ||
| func (*Info) RemovePadFromSeedName(paddedSeed []byte, passphrase string) ([]byte, string, error) { | ||
| decryptedBytes, err := utils.DecryptBytes([]byte(passphrase), paddedSeed) | ||
| if err != nil { | ||
| return nil, "", fmt.Errorf("seed decryption failed: %w", err) | ||
| } | ||
| usernameLength := int(binary.LittleEndian.Uint64(decryptedBytes[seedSize : seedSize+nameSize])) | ||
| return decryptedBytes[:seedSize], string(decryptedBytes[seedSize+nameSize : seedSize+nameSize+usernameLength]), nil | ||
| } | ||
| ``` | ||
|
|
||
| Implementation can be found [here](https://github.com/fairDataSociety/fairOS-dfs/blob/feat/podSubscription.0/pkg/account/account.go) | ||
|
|
||
| # Prior art | ||
| [FIP-59](https://github.com/fairDataSociety/FIPs/blob/master/text/0059-portable-account.md) | ||
|
|
||
| ## Copyright | ||
|
|
||
| Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). | ||
Uh oh!
There was an error while loading. Please reload this page.