From fd3b43900f3ee637ca6bea42c2a458b2d65fc2c8 Mon Sep 17 00:00:00 2001 From: Temitope Alabi Date: Mon, 14 May 2018 17:46:25 -0700 Subject: [PATCH 1/6] Draft 0.1 --- EIPS/eip-1024.md | 74 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 EIPS/eip-1024.md diff --git a/EIPS/eip-1024.md b/EIPS/eip-1024.md new file mode 100644 index 0000000000000..91b8f7eb4b505 --- /dev/null +++ b/EIPS/eip-1024.md @@ -0,0 +1,74 @@ +--- +eip: 1024 +title: Add web3.eth.encrypt +author: Tope Alabi +status: Draft +type: Interface Track +created: 2018-05-14 +--- + +### Summary +... + +### Abstract +This EIP proposes a cross-client method for requesting encryption/decryption. This method will include a version parameter, so that different encryption methods can be added under the same name. + +Parity wallet already implements this and the MetaMask version is on the way. Having a cross-client standard will enable a whole new wave of decentralized applications that will allow users to securely store their private data in public databases such as IPFS. + +### Motivation +Imagine an illegal immigrant named Martha. Martha moved to the United States illegally but then had 2 children there, so her children are citizens. One day Martha gets arrested and deported but her children get to stay. How will Martha pass power of Attorney, bank account info, identification docs, and other sensitive information to her children? Storing that data in a centralized database can be incriminating for Martha, so maybe decentralized databases like IPFS could help, but if the data is not encrypted anyone can see it. If Martha had access to a Dapp that could encrypt her data in a way that’ is connected to her identity and save it in a decentralized database, Martha’s children will experience less suffering. +More casually, Martha can store her nickname in a secure way or create a treasure hunt game, etc. + +### Specification +``` +/** +* Returns user's public Encryption key +*/ +web3.eth.getPublicEncryptionKey(account) { /* implementation */ } + +/** +* Encrypts plain data. +* @param {Account} account - The account to encrypt with +* @param {string} version - A unique string identifying the encryption strategy. +* @param {Object} data - The data to encrypt +* @param {Function} callback - The function to call back when decryption is complete. +*/ +web3.eth.encrypt = function encrypt (account, version, data, callback) { /* implementation */ } +web3.eth.encrypt(account, 'x25519-xsalsa20-poly1305-v1', data, callback) + +/** +* Decrypts some encrypted data. +* @param {Account} account - The account to decrypt with +* @param {string} version - A unique string identifying the decryption strategy. +* @param {Object} data - The data to decrypt +* @param {Function} callback - The function to call back when decryption is complete. +*/ +web3.eth.decrypt = function decrypt (account, version, data, callback) { /* implementation */ } +web3.eth.decrypt(account, 'x25519-xsalsa20-poly1305-v1', data, callback) + +``` + +### Rationale +These methods should require user confirmation. We include the versioning to allow differnet encryption/decryption types to be added under the same method name. For example, it might make sense to have a few kinds of decrypt methods, for different kinds of consent: +- Consent to download a decrypted file. +- Consent to return decrypted file to the current site. +- Consent to return any number of decrypted messages to the current site over a certain period of time. (could enable chat apps) + + +### Backwards Compatibility +This solution is compatible with existing Parity implementation. + +### Test Cases +`getPublicEncryptionKey(account)` should return a public encryption key of the form `"C5YMNdqE4kLgxQhJO1MfuQcHP5hjVSXzamzd/TxlR0U="` + +`web3.eth.encrypt(account, 'x25519-xsalsa20-poly1305-v1', 'data', callback)` should return a blob of the form `{ + ethereumPrivateKey: '7e5374ec2ef0d91761a6e72fdf8f6ac665519bfdf6da0a2329cf0d804514b816', + encryptionPrivateKey: 'flN07C7w2Rdhpucv349qxmVRm/322gojKc8NgEUUuBY=', + encryptionPublicKey: 'C5YMNdqE4kLgxQhJO1MfuQcHP5hjVSXzamzd/TxlR0U=' }` + +`web3.eth.decrypt(account, 'x25519-xsalsa20-poly1305-v1', 'data', callback)` should return plain text/file of the form `{ data:'My name is Satoshi Buterin' }` + +### Implementation +Parity wallet has already implemented a compatible encryption/decryption method. Metamask is currently building one. +https://github.com/paritytech/parity/blob/bd7273061e3f13f53fdd2fa91dc641a83bcc47f0/ethcore/crypto/src/lib.rs#L211 +https://github.com/topealabi/eth-sig-util/blob/master/index.js From 089ab7ddadbf89d8112349f46766a32629b621c9 Mon Sep 17 00:00:00 2001 From: Temitope Alabi Date: Tue, 15 May 2018 15:25:58 -0700 Subject: [PATCH 2/6] Draft 0.2 --- EIPS/eip-1024.md | 50 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/EIPS/eip-1024.md b/EIPS/eip-1024.md index 91b8f7eb4b505..09d01f155b357 100644 --- a/EIPS/eip-1024.md +++ b/EIPS/eip-1024.md @@ -11,16 +11,23 @@ created: 2018-05-14 ... ### Abstract -This EIP proposes a cross-client method for requesting encryption/decryption. This method will include a version parameter, so that different encryption methods can be added under the same name. +This EIP proposes a cross-client method for requesting encryption/decryption. This method will include a version parameter, so that different encryption methods can be added under the same name. This solution will utilize the cryptographically complete and well audited nacl library. Ethereum keypairs are not used directly for encryption, instead we derive an encryption keypair from the account's private key for decryption and generate a random ephemeral keypair for encryption. -Parity wallet already implements this and the MetaMask version is on the way. Having a cross-client standard will enable a whole new wave of decentralized applications that will allow users to securely store their private data in public databases such as IPFS. +Parity wallet already implements a compatible encrypt/decrypt method and the MetaMask version is on the way. Having a cross-client standard will enable a whole new wave of decentralized applications that will allow users to securely store their private data in public databases such as IPFS. ### Motivation -Imagine an illegal immigrant named Martha. Martha moved to the United States illegally but then had 2 children there, so her children are citizens. One day Martha gets arrested and deported but her children get to stay. How will Martha pass power of Attorney, bank account info, identification docs, and other sensitive information to her children? Storing that data in a centralized database can be incriminating for Martha, so maybe decentralized databases like IPFS could help, but if the data is not encrypted anyone can see it. If Martha had access to a Dapp that could encrypt her data in a way that’ is connected to her identity and save it in a decentralized database, Martha’s children will experience less suffering. -More casually, Martha can store her nickname in a secure way or create a treasure hunt game, etc. +Imagine an illegal immigrant named Martha. Martha moved to the United States illegally but then had 2 children there, so her children are citizens. One day Martha gets arrested and deported but her children get to stay. How will Martha pass power of Attorney, bank account info, identification docs, and other sensitive information to her children? Storing that data in a centralized database can be incriminating for Martha, so maybe decentralized databases like IPFS could help, but if the data is not encrypted anyone can see it, which kind of defeats the purpose. If Martha had access to a Dapp with end-to-end encryption connected to her identity, she could save her data in a decentralized, censor-proof database and still have confidence that only her children can access it. + +More casually, Martha can create a treasure hunt game, or a decentralized chat app etc. ### Specification + +Using the nacl library this solution will generate an encryptionKeyPair(ethereumPrivateKey) for each account. ``` +//Javascript Implementation + +const nacl = require('tweetnacl') + /** * Returns user's public Encryption key */ @@ -48,8 +55,29 @@ web3.eth.decrypt(account, 'x25519-xsalsa20-poly1305-v1', data, callback) ``` +**To Encrypt:** +- Alice requests Bob's publicEncryptionKey +- Bob generates his encryptionKeypair using nacl.box.keyPair.fromSecretKey(bob.ethereumPrivateKey) +- Bob sends Alice his encryptionKeyPair.publicKey + +- Alice generates a random ephemeralKeyPair +- Alice uses her ephemeralKeypair.secretKey and Bob's encryptionPublicKey to encrypt the data using nacl.box. She sends him an encrypted blob of the form: + +``` +{ version: 'x25519-xsalsa20-poly1305', + nonce: '1dvWO7uOnBnO7iNDJ9kO9pTasLuKNlej', + ephemPublicKey: 'FBH1/pAEHOOW14Lu3FWkgV3qOEcuL78Zy+qW1RwzMXQ=', + ciphertext: 'f8kBcl/NCyf3sybfbwAKk/np2Bzt9lRVkZejr6uh5FgnNlH/ic62DZzy' } +``` + + +**To Decrypt:** +- Bob generates his encryptionPrivatekey using nacl.box.keyPair.fromSecretKey(bob.ethereumPrivateKey).secretKey +- Bob passes his encryptionPrivateKey along with the encrypted blob to nacl.box.open(ciphertext, nonce, ephemPublicKey, myencryptionPrivatekey) + + ### Rationale -These methods should require user confirmation. We include the versioning to allow differnet encryption/decryption types to be added under the same method name. For example, it might make sense to have a few kinds of decrypt methods, for different kinds of consent: +These methods should require user confirmation. We include the versioning to allow different encryption/decryption types to be added under the same method name. For example, it might make sense to have a few kinds of decrypt methods, for different kinds of consent: - Consent to download a decrypted file. - Consent to return decrypted file to the current site. - Consent to return any number of decrypted messages to the current site over a certain period of time. (could enable chat apps) @@ -57,14 +85,15 @@ These methods should require user confirmation. We include the versioning to all ### Backwards Compatibility This solution is compatible with existing Parity implementation. +https://github.com/paritytech/parity/blob/bd7273061e3f13f53fdd2fa91dc641a83bcc47f0/ethcore/crypto/src/lib.rs#L211 ### Test Cases `getPublicEncryptionKey(account)` should return a public encryption key of the form `"C5YMNdqE4kLgxQhJO1MfuQcHP5hjVSXzamzd/TxlR0U="` -`web3.eth.encrypt(account, 'x25519-xsalsa20-poly1305-v1', 'data', callback)` should return a blob of the form `{ - ethereumPrivateKey: '7e5374ec2ef0d91761a6e72fdf8f6ac665519bfdf6da0a2329cf0d804514b816', - encryptionPrivateKey: 'flN07C7w2Rdhpucv349qxmVRm/322gojKc8NgEUUuBY=', - encryptionPublicKey: 'C5YMNdqE4kLgxQhJO1MfuQcHP5hjVSXzamzd/TxlR0U=' }` +`web3.eth.encrypt(account, 'x25519-xsalsa20-poly1305-v1', 'data', callback)` should return a blob of the form `{ version: 'x25519-xsalsa20-poly1305', + nonce: '1dvWO7uOnBnO7iNDJ9kO9pTasLuKNlej', + ephemPublicKey: 'FBH1/pAEHOOW14Lu3FWkgV3qOEcuL78Zy+qW1RwzMXQ=', + ciphertext: 'f8kBcl/NCyf3sybfbwAKk/np2Bzt9lRVkZejr6uh5FgnNlH/ic62DZzy' }` `web3.eth.decrypt(account, 'x25519-xsalsa20-poly1305-v1', 'data', callback)` should return plain text/file of the form `{ data:'My name is Satoshi Buterin' }` @@ -72,3 +101,6 @@ This solution is compatible with existing Parity implementation. Parity wallet has already implemented a compatible encryption/decryption method. Metamask is currently building one. https://github.com/paritytech/parity/blob/bd7273061e3f13f53fdd2fa91dc641a83bcc47f0/ethcore/crypto/src/lib.rs#L211 https://github.com/topealabi/eth-sig-util/blob/master/index.js + +## Copyright +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From e49bdf86622b4c3a239897bf2aa35b1cb35ae005 Mon Sep 17 00:00:00 2001 From: Temitope Alabi Date: Tue, 15 May 2018 15:29:49 -0700 Subject: [PATCH 3/6] Draft 0.3 --- EIPS/eip-1024.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/EIPS/eip-1024.md b/EIPS/eip-1024.md index 09d01f155b357..e601899487118 100644 --- a/EIPS/eip-1024.md +++ b/EIPS/eip-1024.md @@ -7,8 +7,6 @@ type: Interface Track created: 2018-05-14 --- -### Summary -... ### Abstract This EIP proposes a cross-client method for requesting encryption/decryption. This method will include a version parameter, so that different encryption methods can be added under the same name. This solution will utilize the cryptographically complete and well audited nacl library. Ethereum keypairs are not used directly for encryption, instead we derive an encryption keypair from the account's private key for decryption and generate a random ephemeral keypair for encryption. @@ -59,7 +57,6 @@ web3.eth.decrypt(account, 'x25519-xsalsa20-poly1305-v1', data, callback) - Alice requests Bob's publicEncryptionKey - Bob generates his encryptionKeypair using nacl.box.keyPair.fromSecretKey(bob.ethereumPrivateKey) - Bob sends Alice his encryptionKeyPair.publicKey - - Alice generates a random ephemeralKeyPair - Alice uses her ephemeralKeypair.secretKey and Bob's encryptionPublicKey to encrypt the data using nacl.box. She sends him an encrypted blob of the form: @@ -98,8 +95,7 @@ https://github.com/paritytech/parity/blob/bd7273061e3f13f53fdd2fa91dc641a83bcc47 `web3.eth.decrypt(account, 'x25519-xsalsa20-poly1305-v1', 'data', callback)` should return plain text/file of the form `{ data:'My name is Satoshi Buterin' }` ### Implementation -Parity wallet has already implemented a compatible encryption/decryption method. Metamask is currently building one. -https://github.com/paritytech/parity/blob/bd7273061e3f13f53fdd2fa91dc641a83bcc47f0/ethcore/crypto/src/lib.rs#L211 +Parity wallet has already implemented a compatible encryption/decryption method. The Metamask version will be published soon. https://github.com/topealabi/eth-sig-util/blob/master/index.js ## Copyright From 0ee294a91ea803909fd30eac82ddebb642d607b1 Mon Sep 17 00:00:00 2001 From: Temitope Alabi Date: Wed, 16 May 2018 16:05:13 -0700 Subject: [PATCH 4/6] Draft 0.4 --- EIPS/eip-1024.md | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/EIPS/eip-1024.md b/EIPS/eip-1024.md index e601899487118..e79ec98aa7af8 100644 --- a/EIPS/eip-1024.md +++ b/EIPS/eip-1024.md @@ -9,9 +9,9 @@ created: 2018-05-14 ### Abstract -This EIP proposes a cross-client method for requesting encryption/decryption. This method will include a version parameter, so that different encryption methods can be added under the same name. This solution will utilize the cryptographically complete and well audited nacl library. Ethereum keypairs are not used directly for encryption, instead we derive an encryption keypair from the account's private key for decryption and generate a random ephemeral keypair for encryption. +This EIP proposes a cross-client method for requesting encryption/decryption. This method will include a version parameter, so that different encryption methods can be added under the same name. Nacl is a cryptographically complete and well audited library that works well for this by implementers are free to choose their crypto. Ethereum keypairs should not be used directly for encryption, instead we should derive an encryption keypair from the account's private key for decryption and generate a random ephemeral keypair for encryption. -Parity wallet already implements a compatible encrypt/decrypt method and the MetaMask version is on the way. Having a cross-client standard will enable a whole new wave of decentralized applications that will allow users to securely store their private data in public databases such as IPFS. +Parity wallet already implements a compatible [encrypt/decrypt] https://wiki.parity.io/JSONRPC-parity-module#parity_decryptmessage method and the MetaMask version is on the way. Having a cross-client standard will enable a whole new wave of decentralized applications that will allow users to securely store their private data in public databases such as IPFS. ### Motivation Imagine an illegal immigrant named Martha. Martha moved to the United States illegally but then had 2 children there, so her children are citizens. One day Martha gets arrested and deported but her children get to stay. How will Martha pass power of Attorney, bank account info, identification docs, and other sensitive information to her children? Storing that data in a centralized database can be incriminating for Martha, so maybe decentralized databases like IPFS could help, but if the data is not encrypted anyone can see it, which kind of defeats the purpose. If Martha had access to a Dapp with end-to-end encryption connected to her identity, she could save her data in a decentralized, censor-proof database and still have confidence that only her children can access it. @@ -22,34 +22,31 @@ More casually, Martha can create a treasure hunt game, or a decentralized chat a Using the nacl library this solution will generate an encryptionKeyPair(ethereumPrivateKey) for each account. ``` -//Javascript Implementation const nacl = require('tweetnacl') /** -* Returns user's public Encryption key +* Returns user's public Encryption key derived from privateKey Ethereum key +* @param {Account} reciever - The Ethereum account that will be recieving/decrypting the data */ -web3.eth.getPublicEncryptionKey(account) { /* implementation */ } +web3.eth.getEncryptionPublicKey(reciever.privateKey) { /* implementation */ } /** * Encrypts plain data. -* @param {Account} account - The account to encrypt with +* @param {string} encryptionPublicKey - The encryption public key of the reciever * @param {string} version - A unique string identifying the encryption strategy. * @param {Object} data - The data to encrypt * @param {Function} callback - The function to call back when decryption is complete. -*/ -web3.eth.encrypt = function encrypt (account, version, data, callback) { /* implementation */ } -web3.eth.encrypt(account, 'x25519-xsalsa20-poly1305-v1', data, callback) +*/ +web3.eth.encrypt(encryptionPublicKey, version, data, callback) { /* implementation */ } /** * Decrypts some encrypted data. -* @param {Account} account - The account to decrypt with -* @param {string} version - A unique string identifying the decryption strategy. -* @param {Object} data - The data to decrypt +* @param {Account} reciever - The account that will decrypt the message +* @param {Object} encryptedData - The data to decrypt * @param {Function} callback - The function to call back when decryption is complete. */ -web3.eth.decrypt = function decrypt (account, version, data, callback) { /* implementation */ } -web3.eth.decrypt(account, 'x25519-xsalsa20-poly1305-v1', data, callback) +web3.eth.decrypt = function decrypt (recievier.privatekey, encryptedData, callback) { /* implementation */ } ``` @@ -81,18 +78,22 @@ These methods should require user confirmation. We include the versioning to all ### Backwards Compatibility -This solution is compatible with existing Parity implementation. -https://github.com/paritytech/parity/blob/bd7273061e3f13f53fdd2fa91dc641a83bcc47f0/ethcore/crypto/src/lib.rs#L211 +Parity implements an encrypt/decrypt method with a different curve than the one which is intended in this proposal, but that it would be possible to add support for curves to this standard. + https://wiki.parity.io/JSONRPC-parity-module#parity_decryptmessage ### Test Cases -`getPublicEncryptionKey(account)` should return a public encryption key of the form `"C5YMNdqE4kLgxQhJO1MfuQcHP5hjVSXzamzd/TxlR0U="` +`getEncryptionPublicKey(7e5374ec2ef0d91761a6e72fdf8f6ac665519bfdf6da0a2329cf0d804514b816)` should return a public encryption key of the form `"C5YMNdqE4kLgxQhJO1MfuQcHP5hjVSXzamzd/TxlR0U="` -`web3.eth.encrypt(account, 'x25519-xsalsa20-poly1305-v1', 'data', callback)` should return a blob of the form `{ version: 'x25519-xsalsa20-poly1305', +`web3.eth.encrypt("C5YMNdqE4kLgxQhJO1MfuQcHP5hjVSXzamzd/TxlR0U=", 'x25519-xsalsa20-poly1305-v1', {data: 'My name is Satoshi Buterin'})` should return a blob of the form `{ version: 'x25519-xsalsa20-poly1305', nonce: '1dvWO7uOnBnO7iNDJ9kO9pTasLuKNlej', ephemPublicKey: 'FBH1/pAEHOOW14Lu3FWkgV3qOEcuL78Zy+qW1RwzMXQ=', ciphertext: 'f8kBcl/NCyf3sybfbwAKk/np2Bzt9lRVkZejr6uh5FgnNlH/ic62DZzy' }` -`web3.eth.decrypt(account, 'x25519-xsalsa20-poly1305-v1', 'data', callback)` should return plain text/file of the form `{ data:'My name is Satoshi Buterin' }` +`web3.eth.decrypt('7e5374ec2ef0d91761a6e72fdf8f6ac665519bfdf6da0a2329cf0d804514b816', +{ version: 'x25519-xsalsa20-poly1305', + nonce: '1dvWO7uOnBnO7iNDJ9kO9pTasLuKNlej', + ephemPublicKey: 'FBH1/pAEHOOW14Lu3FWkgV3qOEcuL78Zy+qW1RwzMXQ=', + ciphertext: 'f8kBcl/NCyf3sybfbwAKk/np2Bzt9lRVkZejr6uh5FgnNlH/ic62DZzy' })` should return plain text/file of the form `{ data:'My name is Satoshi Buterin' }` ### Implementation Parity wallet has already implemented a compatible encryption/decryption method. The Metamask version will be published soon. From fc9b5a84aeead4e49f10bf2bcdc122c73ec9783d Mon Sep 17 00:00:00 2001 From: Temitope Alabi Date: Wed, 16 May 2018 16:08:02 -0700 Subject: [PATCH 5/6] Draft 0.5 --- EIPS/eip-1024.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/EIPS/eip-1024.md b/EIPS/eip-1024.md index e79ec98aa7af8..5240c434d646d 100644 --- a/EIPS/eip-1024.md +++ b/EIPS/eip-1024.md @@ -19,8 +19,7 @@ Imagine an illegal immigrant named Martha. Martha moved to the United States ill More casually, Martha can create a treasure hunt game, or a decentralized chat app etc. ### Specification - -Using the nacl library this solution will generate an encryptionKeyPair(ethereumPrivateKey) for each account. + ``` const nacl = require('tweetnacl') From b676508e4d16c8765361231c2d8ef42768d75d70 Mon Sep 17 00:00:00 2001 From: Temitope Alabi Date: Fri, 18 May 2018 12:45:31 -0700 Subject: [PATCH 6/6] updated title --- EIPS/eip-1024.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-1024.md b/EIPS/eip-1024.md index 5240c434d646d..9447e3abd5219 100644 --- a/EIPS/eip-1024.md +++ b/EIPS/eip-1024.md @@ -1,6 +1,6 @@ --- eip: 1024 -title: Add web3.eth.encrypt +title: Add web3.eth.encrypt and web3.eth.decrypt functions author: Tope Alabi status: Draft type: Interface Track