-
Notifications
You must be signed in to change notification settings - Fork 83
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Ethereum Private key (Epk) decryption provider implementation (#…
…499) **Epk-decryption:** * creation of the package to decrypt ECIES encrypted data with ethereum private keys
- Loading branch information
Showing
16 changed files
with
561 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"hooks": { | ||
"pre-commit": "yarn run lint-staged" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"src/**/*.ts": ["tslint --project . --fix", "prettier --single-quote --write", "git add"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"extension": [ | ||
".ts" | ||
], | ||
"include": [ | ||
"src/*.ts", | ||
"src/**/*.ts" | ||
], | ||
"require": [ | ||
"ts-node/register" | ||
], | ||
"reporter": [ | ||
"text-summary", | ||
"json", | ||
"html" | ||
], | ||
"sourceMap":true, | ||
"all": true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
# @requestnetwork/epk-decryption | ||
|
||
Ethereum Private Key Decryption Provider. | ||
|
||
`@requestnetwork/epk-decryption` is a typescript library part of the [Request Network protocol](https://github.com/RequestNetwork/requestNetwork). | ||
|
||
Implementation of the decryption provider from the private keys. | ||
The decryption provider is used to make decryption in the Request Network Protocol (e.g.: see [Transaction Manager](/packages/transaction-manager)). | ||
|
||
It uses the Request Network Protocol concept of `Identity` described in the [request logic specification](/packages/request-logic/specs/request-logic-specification-v2.0.0.md). | ||
|
||
## Installation | ||
|
||
```bash | ||
npm install @requestnetwork/epk-decryption | ||
``` | ||
|
||
## Usage | ||
|
||
```javascript | ||
import { EncryptionTypes, IdentityTypes } from '@requestnetwork/types' | ||
|
||
import EthereumPrivateKeyDecryptionProvider from '@requestnetwork/epk-decryption' | ||
|
||
const decryptionParametersExample: EncryptionTypes.IDecryptionParameters = { | ||
key: '0xc87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3', | ||
method: EncryptionTypes.METHOD.ECIES, | ||
}; | ||
|
||
// Identity from the previous signature parameter | ||
const identityExample: IdentityTypes.IIdentity = { | ||
type: IdentityTypes.TYPE.ETHEREUM_ADDRESS, | ||
value: '0x627306090abab3a6e1400e9345bc60c78a8bef57' | ||
}; | ||
|
||
// Construct the provider with a | ||
const decryptionProvider = new EthereumPrivateKeyDecryptionProvider(decryptionParametersExample); | ||
|
||
// can list the identity usable | ||
const listOfAvailableIdentity = decryptionProvider.getAllRegisteredIdentities(); // [identityExample] | ||
|
||
// can decrypt data with identity | ||
const dataToDecrypt = "02...."; | ||
const decryptedData = await decryptionProvider.decrypt(dataToDecrypt, identityExample); // "Decrypted data..." | ||
|
||
// can add a new decryption parameters | ||
decryptionProvider.addDecryptionParameters({method: EncryptionTypes.METHOD.ECIES, key: ...}); | ||
|
||
// can remove a decryption parameters from its identity | ||
decryptionProvider.removeRegisteredIdentity({type: IdentityTypes.TYPE.ETHEREUM_ADDRESS, value: ...}); | ||
|
||
// can remove all decryption parameters | ||
decryptionProvider.clearAllRegisteredIdentities(); | ||
``` | ||
|
||
## Contributing | ||
|
||
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change. | ||
[Read the contributing guide](/CONTRIBUTING.md) | ||
|
||
## License | ||
|
||
[MIT](/LICENSE) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
{ | ||
"name": "@requestnetwork/epk-decryption", | ||
"version": "0.1.0", | ||
"publishConfig": { | ||
"access": "public" | ||
}, | ||
"description": "Decryption provider using ethereum private keys.", | ||
"keywords": [ | ||
"requestnetwork", | ||
"decryption-provider" | ||
], | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/RequestNetwork/requestNetwork.git" | ||
}, | ||
"homepage": "https://github.com/RequestNetwork/requestNetwork/tree/master/packages/epk-decryption#readme", | ||
"bugs": { | ||
"url": "https://github.com/RequestNetwork/requestNetwork/issues" | ||
}, | ||
"license": "MIT", | ||
"engines": { | ||
"node": ">=8.0.0" | ||
}, | ||
"main": "dist/index.js", | ||
"types": "dist/index.d.ts", | ||
"directories": { | ||
"lib": "src", | ||
"test": "test" | ||
}, | ||
"files": [ | ||
"dist" | ||
], | ||
"scripts": { | ||
"build": "tsc -b", | ||
"clean": "shx rm -rf dist", | ||
"lint": "tslint --project . && eslint \"src/**/*.ts\"", | ||
"lint-staged": "lint-staged", | ||
"test": "nyc mocha --require ts-node/register --require source-map-support/register \"test/**/*.ts\"", | ||
"test:watch": "nyc mocha --watch --watch-extensions ts --require ts-node/register --require source-map-support/register \"test/**/*.ts\"" | ||
}, | ||
"dependencies": { | ||
"@requestnetwork/types": "0.4.0", | ||
"@requestnetwork/utils": "0.4.0" | ||
}, | ||
"devDependencies": { | ||
"@types/chai": "4.1.7", | ||
"@types/mocha": "5.2.6", | ||
"@typescript-eslint/parser": "1.2.0", | ||
"chai": "4.2.0", | ||
"chai-as-promised": "7.1.1", | ||
"eslint": "5.13.0", | ||
"eslint-plugin-spellcheck": "0.0.11", | ||
"eslint-plugin-typescript": "0.14.0", | ||
"husky": "2.4.0", | ||
"lint-staged": "8.1.3", | ||
"mocha": "5.2.0", | ||
"npm-run-all": "4.1.5", | ||
"nyc": "13.2.0", | ||
"prettier": "1.16.4", | ||
"shx": "0.3.2", | ||
"source-map-support": "0.5.10", | ||
"ts-node": "8.0.2", | ||
"tslint": "5.12.1", | ||
"typescript": "3.3.1" | ||
} | ||
} |
124 changes: 124 additions & 0 deletions
124
packages/epk-decryption/src/ethereum-private-key-decryption-provider.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
import { DecryptionProviderTypes, EncryptionTypes, IdentityTypes } from '@requestnetwork/types'; | ||
|
||
import Utils from '@requestnetwork/utils'; | ||
|
||
/** Type of the dictionary of decryptionParameters (private keys) indexed by ethereum address */ | ||
type IDecryptionParametersDictionary = Map<string, EncryptionTypes.IDecryptionParameters>; | ||
|
||
/** | ||
* Implementation of the decryption provider from private key | ||
* Allows to decrypt() with "ethereumAddress" identities thanks to their private key given in constructor() or addDecryptionParameters() | ||
*/ | ||
export default class EthereumPrivateKeyDecryptionProvider | ||
implements DecryptionProviderTypes.IDecryptionProvider { | ||
/** list of supported encryption method */ | ||
public supportedMethods: EncryptionTypes.METHOD[] = [EncryptionTypes.METHOD.ECIES]; | ||
/** list of supported identity types */ | ||
public supportedIdentityTypes: IdentityTypes.TYPE[] = [IdentityTypes.TYPE.ETHEREUM_ADDRESS]; | ||
|
||
/** Dictionary containing all the private keys indexed by address */ | ||
private decryptionParametersDictionary: IDecryptionParametersDictionary; | ||
|
||
constructor(decryptionParameters?: EncryptionTypes.IDecryptionParameters) { | ||
this.decryptionParametersDictionary = new Map<string, EncryptionTypes.IDecryptionParameters>(); | ||
if (decryptionParameters) { | ||
this.addDecryptionParameters(decryptionParameters); | ||
} | ||
} | ||
|
||
/** | ||
* Decrypts data | ||
* | ||
* @param data the encrypted data | ||
* @param identity identity to decrypt with | ||
* | ||
* @returns the data decrypted | ||
*/ | ||
public async decrypt(data: string, identity: IdentityTypes.IIdentity): Promise<string> { | ||
if (!Utils.multiFormat.isEciesEncryption(data)) { | ||
throw Error(`The data must be encrypted with ${EncryptionTypes.METHOD.ECIES}`); | ||
} | ||
|
||
if (!this.supportedIdentityTypes.includes(identity.type)) { | ||
throw Error(`Identity type not supported ${identity.type}`); | ||
} | ||
|
||
// toLowerCase to avoid mismatch because of case | ||
const decryptionParameters: | ||
| EncryptionTypes.IDecryptionParameters | ||
| undefined = this.decryptionParametersDictionary.get(identity.value.toLowerCase()); | ||
|
||
if (!decryptionParameters) { | ||
throw Error(`private key unknown for the identity: ${identity.value}`); | ||
} | ||
|
||
return Utils.encryption.decrypt(data, decryptionParameters); | ||
} | ||
|
||
/** | ||
* Adds a new private key in the provider | ||
* | ||
* @param decryptionParameters decryption parameters to add | ||
* | ||
* @returns identity from the decryption parameter added | ||
*/ | ||
public addDecryptionParameters( | ||
decryptionParameters: EncryptionTypes.IDecryptionParameters, | ||
): IdentityTypes.IIdentity { | ||
if (!this.supportedMethods.includes(decryptionParameters.method)) { | ||
throw Error(`Encryption method not supported ${decryptionParameters.method}`); | ||
} | ||
|
||
// compute the address from private key | ||
// toLowerCase to avoid mismatch because of case | ||
const address = Utils.crypto.EcUtils.getAddressFromPrivateKey( | ||
decryptionParameters.key, | ||
).toLowerCase(); | ||
|
||
this.decryptionParametersDictionary.set(address, decryptionParameters); | ||
|
||
return { | ||
type: IdentityTypes.TYPE.ETHEREUM_ADDRESS, | ||
value: address, | ||
}; | ||
} | ||
|
||
/** | ||
* Removes a private key from the provider | ||
* | ||
* @param identity identity to remove the private key | ||
* | ||
* @returns void | ||
*/ | ||
public removeRegisteredIdentity(identity: IdentityTypes.IIdentity): void { | ||
// Check the type of the identity to be sure that the value used to delete will be the right type | ||
if (!this.supportedIdentityTypes.includes(identity.type)) { | ||
throw Error(`Identity type not supported ${identity.type}`); | ||
} | ||
|
||
this.decryptionParametersDictionary.delete(identity.value); | ||
} | ||
|
||
/** | ||
* Removes all private keys from the provider | ||
* | ||
* @param identity identity to remove the private key | ||
* | ||
* @returns void | ||
*/ | ||
public clearAllRegisteredIdentities(): void { | ||
this.decryptionParametersDictionary.clear(); | ||
} | ||
|
||
/** | ||
* Gets all the identities available to decrypt with | ||
* | ||
* @returns all the identities registered | ||
*/ | ||
public getAllRegisteredIdentities(): IdentityTypes.IIdentity[] { | ||
return Array.from(this.decryptionParametersDictionary.keys(), address => ({ | ||
type: IdentityTypes.TYPE.ETHEREUM_ADDRESS, | ||
value: address, | ||
})); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export { | ||
default as EthereumPrivateKeyDecryptionProvider, | ||
} from './ethereum-private-key-decryption-provider'; |
Oops, something went wrong.