FIX readme for v2

pull/1/head
pubkey 7 years ago
parent a56e42d5f8
commit 4d44c16804
  1. 128
      README.md
  2. 26
      test/integration.test.js
  3. 34
      test/performance.test.js
  4. 34
      test/unit.test.js
  5. 12
      typings/index.d.ts

@ -1,124 +1,124 @@
# ethereum-encryption
# eth-crypto
A javascript module to encrypt, decrypt, sign and verify data with an ethereum public- or privateKey. This internally uses [bitcore-lib](https://github.com/bitpay/bitcore-lib) and [bitcore-ecies](https://github.com/bitpay/bitcore-ecies).
Cryptographic functions for ethereum and how to use them together with web3 and solidity.
`Warning: There was no audit on this code. Use this on your own risk.`
## Tutorials
## Install
## Functions
### Install
```bash
npm install ethereum-encryption --save
npm install eth-crypto --save
```
```javascript
// es6
import EthereumEncryption from 'ethereum-encryption';
import EthCrypto from 'eth-crypto';
// node
const EthereumEncryption = require('ethereum-encryption');
const EthCrypto = require('eth-crypto');
```
## API
### createPrivateKey()
Creates a new privateKey from random bytes and returns it as hex-string.
```javascript
const privateKey = EthereumEncryption.createPrivateKey();
// '2400238629a674a372694567f949c94847b76607de151433587c20547aa90460'
```
### createIdentity()
You can then use the created privateKeys together with ganache by transforming them into a buffer.
Creates a new ethereum-identity with privateKey, publicKey and address as hex-string.
```javascript
const ganache = require('ganache-cli');
const Web3 = require('web3');
const web3 = new Web3();
web3.setProvider(ganache.provider({
accounts: [{
secretKey: new Buffer(privateKey, 'hex'),
balance: web3.utils.toWei('100', 'ether')
}]
}));
const identity = EthCrypto.createIdentity();
/* > {
address: '0x3f243FdacE01Cfd9719f7359c94BA11361f32471',
privateKey: '0x107be946709e41b7895eea9f2dacf998a0a9124acbb786f0fd1a826101581a07',
publicKey: 'bf1cc3154424dc22191941d9f4f50b063a2b663a2337e5548abea633c1d06ece...'
} */
```
### publicKeyFromPrivateKey()
### publicKeyByPrivateKey()
Derives the publicKey from a privateKey and returns it as hex-string.
```javascript
const publicKey = EthereumEncryption.publicKeyFromPrivateKey(
'2400238629a674a372694567f949c94847b76607de151433587c20547aa90460'
const publicKey = EthCrypto.publicKeyByPrivateKey(
'0x107be946709e41b7895eea9f2dacf998a0a9124acbb786f0fd1a826101581a07'
);
// '03a34d6aef3eb42335fb3cacb59478c0b44c0bbeb8bb4ca427dbc7044157a5d24b'
// > 'bf1cc3154424dc22191941d9f4f50b063a2b663a2337e5548abea633c1d06ece...'
```
### publicKeyToAddress()
### addressByPublicKey()
Derives the ethereum-address from the publicKey.
```javascript
const address = EthereumEncryption.publicKeyToAddress(
'03a34d6aef3eb42335fb3cacb59478c0b44c0bbeb8bb4ca427dbc7044157a5d24b'
const address = EthCrypto.publicKeyToAddress(
'bf1cc3154424dc22191941d9f4f50b063a2b663a2337e5548abea633c1d06ece...'
);
// '0x63dcee1fd1d814858acd4172bb20e1aa0c947c0a'
```
### hash()
Creates the `sha3_256`-hash of the given string.
```javascript
const hash = EthereumEncryption.hash('foobar');
// '09234807e4af85f17c66b48ee3bca89dffd1f1233659f9f940a2b17b0b8c6bc5'
// > '0x3f243FdacE01Cfd9719f7359c94BA11361f32471'
```
### signHash()
### sign()
Signs the sha3_256-hash with the privateKey. Returns the signature as hex-string.
Signs the message with the privateKey. Returns the signature as object with hex-strings.
```javascript
const signature = EthereumEncryption.signHash(
'2400238629a674a372694567f949c94847b76607de151433587c20547aa90460', // privateKey
'09234807e4af85f17c66b48ee3bca89dffd1f1233659f9f940a2b17b0b8c6bc5' // hash
const signature = EthCrypto.sign(
'0x107be946709e41b7895eea9f2dacf998a0a9124acbb786f0fd1a826101581a07', // privateKey
'foobar' // message
);
// '40f50efc7aee9d414b5621a5818a6cc8f89bc000087d6a41ed9cc66b605365295279d3bbd7710f9fc4c4d73c39f74a0e5c116168e69d1341c3a5467142f3e63a'
/* > {
v: '0x1b',
r: '0xc04b809d8f33c46ff80c44ba58e866ff0d5126d9943b58bee03cc5279450cacc',
s: '0x757a3393b695ba83b2aba0c35c150399bf7959493aad80d51d917435b1a7ebda'
} */
```
### verifyHashSignature()
### recover()
Check if signature of the hash was signed by the privateKey of the publicKey. Returns `true` if valid, `false` if not.
Recovers the signers address from the signature.
```javascript
const valid = verifyHashSignature.verifyHashSignature(
'03a34d6aef3eb42335fb3cacb59478c0b44c0bbeb8bb4ca427dbc7044157a5d24b', // publicKey
'09234807e4af85f17c66b48ee3bca89dffd1f1233659f9f940a2b17b0b8c6bc5', // hash
'40f50efc7aee9d414b5621a5818a6cc8f89bc000087d6a41ed9cc66b605365295279d3bbd7710f9fc4c4d73c39f74a0e5c116168e69d1341c3a5467142f3e63a' // signature
const signer = EthCrypto.recover(
{
v: '0x1b',
r: '0xc04b809d8f33c46ff80c44ba58e866ff0d5126d9943b58bee03cc5279450cacc',
s: '0x757a3393b695ba83b2aba0c35c150399bf7959493aad80d51d917435b1a7ebda'
}, // signature
'foobar' // signed message
);
// true
// > '0x3f243FdacE01Cfd9719f7359c94BA11361f32471'
```
### encryptWithPublicKey()
Encrypts the message with the publicKey. Returns the encrypted hex-string.
Encrypts the message with the publicKey so that only the corresponding privateKey can decrypt it. Returns (async) the encrypted data as object with hex-strings.
```javascript
const encrypted = verifyHashSignature.encryptWithPublicKey(
'03a34d6aef3eb42335fb3cacb59478c0b44c0bbeb8bb4ca427dbc7044157a5d24b', // publicKey
'foobar' // data
const encrypted = await EthCrypto.encryptWithPublicKey(
'bf1cc3154424dc22191941d9f4f50b063a2b663a2337e5548abea633c1d06ece...', // publicKey
'foobar' // message
);
// '0333eec583d04a55ce0aba9dbfb04035e8c6de4f501ecc9b26c08fa501a5ec1507ccd64457ceae9dd4f52abfa673912f2618bfb71392f864465d9bfe996bc0a2acf6133e14a689b7c1299c60eadf43f45adbb8a21543b0c4749aa9bc2a106a0f8e'
/* > {
iv: '02aeac54cb45283b427bd1a5028552c1',
ephemPublicKey: '044acf39ed83c304f19f41ea66615d7a6c0068d5fc48ee181f2fb1091...',
ciphertext: '5fbbcc1a44ee19f7499dbc39cfc4ce96',
mac: '96490b293763f49a371d3a2040a2d2cb57f246ee88958009fe3c7ef2a38264a1'
} */
```
### decryptWithPrivateKey()
Decrypt the encrypted message with the privateKey. Returns the message as string.
Decrypts the encrypted data with the privateKey. Returns (async) the message as string.
```javascript
const message = verifyHashSignature.decryptWithPrivateKey(
'2400238629a674a372694567f949c94847b76607de151433587c20547aa90460', // privateKey
'0333eec583d04a55ce0aba9dbfb04035e8c6de4f501ecc9b26c08fa501a5ec1507ccd64457ceae9dd4f52abfa673912f2618bfb71392f864465d9bfe996bc0a2acf6133e14a689b7c1299c60eadf43f45adbb8a21543b0c4749aa9bc2a106a0f8e' // encrypted-data
const message = await EthCrypto.decryptWithPrivateKey(
'0x107be946709e41b7895eea9f2dacf998a0a9124acbb786f0fd1a826101581a07', // privateKey
{
iv: '02aeac54cb45283b427bd1a5028552c1',
ephemPublicKey: '044acf39ed83c304f19f41ea66615d7a6c0068d5fc48ee181f2fb1091...',
ciphertext: '5fbbcc1a44ee19f7499dbc39cfc4ce96',
mac: '96490b293763f49a371d3a2040a2d2cb57f246ee88958009fe3c7ef2a38264a1'
} // encrypted-data
);
// 'foobar'
```

@ -3,9 +3,9 @@ const Web3 = require('web3');
const Tx = require('ethereumjs-tx');
const AsyncTestUtil = require('async-test-util');
const assert = require('assert');
const EthereumEncryption = require('../dist/lib/index');
const EthCrypto = require('../dist/lib/index');
const compiled = require('../gen/TestContract.json');
const web3 = EthereumEncryption.util.web3;
const web3 = EthCrypto.util.web3;
describe('integration.test.js', () => {
const state = {
@ -20,7 +20,7 @@ describe('integration.test.js', () => {
// create accounts
const ganacheAccounts = new Array(20)
.fill(0)
.map(() => EthereumEncryption.createIdentity())
.map(() => EthCrypto.createIdentity())
.map(identity => {
state.accounts.push(identity);
const twoStripped = identity.privateKey.replace(/^.{2}/g, '');
@ -66,7 +66,7 @@ describe('integration.test.js', () => {
const web3 = new Web3();
const ganacheAccounts = new Array(10)
.fill(0)
.map(() => EthereumEncryption.createIdentity())
.map(() => EthCrypto.createIdentity())
.map(identity => ({
secretKey: new Buffer(identity.privateKey.replace(/^.{2}/g, ''), 'hex'),
balance: web3.utils.toWei('100', 'ether')
@ -76,7 +76,7 @@ describe('integration.test.js', () => {
}));
});
it('should be possible to sign transaction with the key', async () => {
const identity = EthereumEncryption.createIdentity();
const identity = EthCrypto.createIdentity();
const web3 = new Web3();
web3.setProvider(ganache.provider({
@ -109,23 +109,23 @@ describe('integration.test.js', () => {
.methods.hashNumber(nr)
.call();
const jsHash = EthereumEncryption.hash.solidityHash(nr);
const jsHash = EthCrypto.hash.solidityHash(nr);
assert.equal(solHash, jsHash);
});
it('string: should create the same hash as solidity', async () => {
const str = 'foobar';
const jsHash = EthereumEncryption.hash.solidityHash(str);
const jsHash = EthCrypto.hash.solidityHash(str);
const solHash = await state.contract
.methods.hashString(str)
.call();
assert.equal(jsHash, solHash);
});
it('should create the same hash as web3.accounts.sign()', async () => {
const ident = EthereumEncryption.createIdentity();
const ident = EthCrypto.createIdentity();
const str = 'foobar';
const account = web3.eth.accounts.privateKeyToAccount(ident.privateKey);
const sig = account.sign(str);
const jsHash = EthereumEncryption.hash.signHash(
const jsHash = EthCrypto.hash.signHash(
str
);
assert.equal(jsHash, sig.messageHash);
@ -133,15 +133,15 @@ describe('integration.test.js', () => {
});
describe('sign', () => {
it('should validate the signature on solidity', async () => {
const ident = EthereumEncryption.createIdentity();
const ident = EthCrypto.createIdentity();
const message = AsyncTestUtil.randomString(12);
const messageHash = EthereumEncryption.hash.signHash(message);
const signature = await EthereumEncryption.sign(
const messageHash = EthCrypto.hash.signHash(message);
const signature = await EthCrypto.sign(
ident.privateKey,
message
);
const jsSigner = EthereumEncryption.recover(signature, message);
const jsSigner = EthCrypto.recover(signature, message);
assert.equal(jsSigner, ident.address);
const solSigner = await state.contract
.methods.recoverSignature(

@ -5,7 +5,7 @@ const convertHrtime = require('convert-hrtime');
const AsyncTestUtil = require('async-test-util');
const assert = require('assert');
const EthereumEncryption = require('../dist/lib/index');
const EthCrypto = require('../dist/lib/index');
const TEST_DATA = {
address: '0x3f243FdacE01Cfd9719f7359c94BA11361f32471',
@ -23,18 +23,18 @@ describe('performance.test.js', () => {
describe('.sign()', () => {
it('sameKey', async () => {
// prepare
const identity = EthereumEncryption.createIdentity();
const identity = EthCrypto.createIdentity();
const runs = 300;
const hashes = new Array(runs)
.fill(0)
.map(() => AsyncTestUtil.randomString(12))
.map(s => EthereumEncryption.hash.solidityHash(s).replace(/^.{2}/g, ''));
.map(s => EthCrypto.hash.solidityHash(s).replace(/^.{2}/g, ''));
// run
const startTime = process.hrtime();
for (let i = 0; i < runs; i++) {
const hash = hashes.pop();
EthereumEncryption.sign(
EthCrypto.sign(
identity.privateKey,
hash
);
@ -49,17 +49,17 @@ describe('performance.test.js', () => {
const hashes = new Array(runs)
.fill(0)
.map(() => AsyncTestUtil.randomString(12))
.map(s => EthereumEncryption.hash.solidityHash(s).replace(/^.{2}/g, ''));
.map(s => EthCrypto.hash.solidityHash(s).replace(/^.{2}/g, ''));
const keys = new Array(runs)
.fill(0)
.map(() => EthereumEncryption.createIdentity().privateKey);
.map(() => EthCrypto.createIdentity().privateKey);
// run
const startTime = process.hrtime();
for (let i = 0; i < runs; i++) {
const hash = hashes.pop();
const key = keys.pop();
EthereumEncryption.sign(
EthCrypto.sign(
key,
hash
);
@ -72,13 +72,13 @@ describe('performance.test.js', () => {
describe('.encryptWithPublicKey()', () => {
it('sameKey', async () => {
// prepare
const identity = EthereumEncryption.createIdentity();
const identity = EthCrypto.createIdentity();
const runs = 1000;
const hashes = new Array(runs)
.fill(0)
.map(() => AsyncTestUtil.randomString(12))
.map(s => EthereumEncryption.hash.solidityHash(s));
.map(s => EthCrypto.hash.solidityHash(s));
// run
const startTime = process.hrtime();
@ -88,7 +88,7 @@ describe('performance.test.js', () => {
.fill(0)
.map(async () => {
const hash = hashes.pop();
await EthereumEncryption.encryptWithPublicKey(
await EthCrypto.encryptWithPublicKey(
identity.publicKey,
hash
);
@ -104,10 +104,10 @@ describe('performance.test.js', () => {
const hashes = new Array(runs)
.fill(0)
.map(() => AsyncTestUtil.randomString(12))
.map(s => EthereumEncryption.hash.solidityHash(s));
.map(s => EthCrypto.hash.solidityHash(s));
const keys = new Array(runs)
.fill(0)
.map(() => EthereumEncryption.createIdentity().publicKey);
.map(() => EthCrypto.createIdentity().publicKey);
// run
const startTime = process.hrtime();
@ -117,7 +117,7 @@ describe('performance.test.js', () => {
.map(async () => {
const hash = hashes.pop();
const publicKey = keys.pop();
await EthereumEncryption.encryptWithPublicKey(
await EthCrypto.encryptWithPublicKey(
publicKey,
hash
);
@ -131,15 +131,15 @@ describe('performance.test.js', () => {
describe('.decryptWithPrivateKey()', () => {
it('sameKey', async () => {
// prepare
const identity = EthereumEncryption.createIdentity();
const identity = EthCrypto.createIdentity();
const runs = 1000;
const hashes = await Promise.all(
new Array(runs)
.fill(0)
.map(() => AsyncTestUtil.randomString(12))
.map(s => EthereumEncryption.hash.solidityHash(s))
.map(async (h) => EthereumEncryption.encryptWithPublicKey(
.map(s => EthCrypto.hash.solidityHash(s))
.map(async (h) => EthCrypto.encryptWithPublicKey(
identity.publicKey,
h
))
@ -152,7 +152,7 @@ describe('performance.test.js', () => {
.fill(0)
.map(async () => {
const encrypted = hashes.pop();
await EthereumEncryption.decryptWithPrivateKey(
await EthCrypto.decryptWithPrivateKey(
identity.privateKey,
encrypted
);

@ -1,6 +1,6 @@
const AsyncTestUtil = require('async-test-util');
const assert = require('assert');
const EthereumEncryption = require('../dist/lib/index');
const EthCrypto = require('../dist/lib/index');
const eccrypto = require('eccrypto');
const TEST_DATA = {
@ -12,7 +12,7 @@ const TEST_DATA = {
describe('unit.test.js', () => {
describe('.createIdentity()', () => {
it('should create an identity', () => {
const ident = EthereumEncryption.createIdentity();
const ident = EthCrypto.createIdentity();
assert.equal(typeof ident.privateKey, 'string');
assert.equal(typeof ident.publicKey, 'string');
assert.equal(typeof ident.address, 'string');
@ -21,14 +21,14 @@ describe('unit.test.js', () => {
describe('.publicKeyByPrivateKey()', () => {
describe('positive', () => {
it('should give the correct publicKey', () => {
const publicKey = EthereumEncryption.publicKeyByPrivateKey(TEST_DATA.privateKey);
const publicKey = EthCrypto.publicKeyByPrivateKey(TEST_DATA.privateKey);
assert.equal(publicKey, TEST_DATA.publicKey);
});
});
describe('negative', () => {
it('should crash when non-key given', () => {
assert.throws(
() => EthereumEncryption.publicKeyByPrivateKey(
() => EthCrypto.publicKeyByPrivateKey(
AsyncTestUtil.randomString(12)
)
);
@ -38,13 +38,13 @@ describe('unit.test.js', () => {
describe('.addressByPublicKey()', () => {
describe('positive', () => {
it('should generate the correct address', () => {
const address = EthereumEncryption.addressByPublicKey(TEST_DATA.publicKey);
const address = EthCrypto.addressByPublicKey(TEST_DATA.publicKey);
assert.equal(address, TEST_DATA.address);
});
});
describe('negative', () => {
assert.throws(
() => EthereumEncryption.addressByPublicKey(
() => EthCrypto.addressByPublicKey(
AsyncTestUtil.randomString(12)
)
);
@ -54,7 +54,7 @@ describe('unit.test.js', () => {
describe('positive', () => {
it('should sign the data', () => {
const message = AsyncTestUtil.randomString(12);
const signature = EthereumEncryption.sign(TEST_DATA.privateKey, message);
const signature = EthCrypto.sign(TEST_DATA.privateKey, message);
assert.ok(signature);
assert.equal(typeof signature.r, 'string');
assert.equal(typeof signature.s, 'string');
@ -64,7 +64,7 @@ describe('unit.test.js', () => {
describe('negative', () => {
it('should not sign with wrong key', () => {
assert.throws(
() => EthereumEncryption.sign(
() => EthCrypto.sign(
AsyncTestUtil.randomString(222),
AsyncTestUtil.randomString(12)
)
@ -76,8 +76,8 @@ describe('unit.test.js', () => {
describe('positive', () => {
it('should return the correct address', () => {
const message = AsyncTestUtil.randomString(12);
const signature = EthereumEncryption.sign(TEST_DATA.privateKey, message);
const address = EthereumEncryption.recover(signature, message);
const signature = EthCrypto.sign(TEST_DATA.privateKey, message);
const address = EthCrypto.recover(signature, message);
assert.equal(address, TEST_DATA.address);
});
});
@ -87,7 +87,7 @@ describe('unit.test.js', () => {
describe('positive', () => {
it('should encrypt the data', async () => {
const message = AsyncTestUtil.randomString(12);
const encrypted = await EthereumEncryption.encryptWithPublicKey(
const encrypted = await EthCrypto.encryptWithPublicKey(
TEST_DATA.publicKey,
message
);
@ -101,7 +101,7 @@ describe('unit.test.js', () => {
it('should throw when non-key given', async () => {
const message = AsyncTestUtil.randomString(12);
await AsyncTestUtil.assertThrows(
() => EthereumEncryption.encryptWithPublicKey(
() => EthCrypto.encryptWithPublicKey(
AsyncTestUtil.randomString(12),
message
)
@ -109,22 +109,22 @@ describe('unit.test.js', () => {
});
});
});
describe('.decryptWithPrivateKey()', ()=> {
describe('positive', ()=> {
describe('.decryptWithPrivateKey()', () => {
describe('positive', () => {
it('should decrypt the data', async () => {
const message = AsyncTestUtil.randomString(12);
const encrypted = await EthereumEncryption.encryptWithPublicKey(
const encrypted = await EthCrypto.encryptWithPublicKey(
TEST_DATA.publicKey,
message
);
const decrypted = await EthereumEncryption.decryptWithPrivateKey(
const decrypted = await EthCrypto.decryptWithPrivateKey(
TEST_DATA.privateKey,
encrypted
);
assert.equal(decrypted, message);
});
});
describe('negative', ()=> {});
describe('negative', () => {});
});
/*
describe('.testBlock()', ()=> {

12
typings/index.d.ts vendored

@ -1,12 +1,14 @@
import Web3 from 'web3';
export function addressByPublicKey(publicKey: string): string;
export function createIdentity(): {
privateKey: string,
publicKey: string,
address: string
};
export function publicKeyByPrivateKey(privateKey: string): string;
export function addressByPublicKey(publicKey: string): string;
export type Signature = {
v: string,
r: string,
@ -20,11 +22,11 @@ export type Encrypted = {
mac: string
};
export function decryptWithPrivateKey(privateKey: string, encrypted: Encrypted): Promise<string>;
export function encryptWithPublicKey(publicKey: string, message: string): Promise<Encrypted>;
export function publicKeyByPrivateKey(privateKey: string): string;
export function sign(privateKey: string, message: string): Signature;
export function recover(sig: Signature, message: string);
export function sign(privateKEy: string, message: string): Signature;
export function encryptWithPublicKey(publicKey: string, message: string): Promise<Encrypted>;
export function decryptWithPrivateKey(privateKey: string, encrypted: Encrypted): Promise<string>;
export type hash = {
solidityHash(msg: string): string;

Loading…
Cancel
Save