Merge pull request #548 from yhuard/master

Remove `eth-lib` from dependencies, address CVE-2022-0355
pull/493/head
Daniel Meyer 3 years ago committed by GitHub
commit 5a3f6d8586
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      README.md
  2. 21
      dist/es/create-identity.js
  3. 14
      dist/es/vrs.js
  4. 2
      dist/lib/calculate-contract-address.js
  5. 2
      dist/lib/cipher.js
  6. 31
      dist/lib/create-identity.js
  7. 2
      dist/lib/decrypt-with-private-key.js
  8. 2
      dist/lib/encrypt-with-public-key.js
  9. 2
      dist/lib/hash.js
  10. 66
      dist/lib/index.js
  11. 2
      dist/lib/public-key-by-private-key.js
  12. 2
      dist/lib/recover-public-key.js
  13. 4
      dist/lib/recover.js
  14. 4
      dist/lib/sign-transaction.js
  15. 2
      dist/lib/sign.js
  16. 4
      dist/lib/tx-data-by-compiled.js
  17. 4
      dist/lib/util.js
  18. 15
      dist/lib/vrs.js
  19. 5
      package.json
  20. 28
      src/create-identity.js
  21. 18
      src/vrs.js
  22. 3
      test/integration.test.js
  23. 3
      test/tutorials/signed-data.test.js
  24. 5
      test/unit.test.js
  25. 2
      tutorials/creating-transactions.md
  26. 2
      typings/index.d.ts

@ -235,7 +235,7 @@ const identity = EthCrypto.createIdentity();
const rawTx = {
from: identity.address,
to: '0x86Fa049857E0209aa7D9e616F7eb3b3B78ECfdb0',
value: 1000000000000000000,
value: new BN('1000000000000000000'),
gasPrice: 5000000000,
nonce: 0,
gasLimit: 21000

@ -1,8 +1,7 @@
import publicKeyByPrivateKey from './public-key-by-private-key';
import { fromPrivate } from 'eth-lib/lib/account';
import { keccak256 } from 'eth-lib/lib/hash';
import Bytes from 'eth-lib/lib/bytes';
import { utils as ethersUtils, Wallet } from 'ethers';
import { stripHexPrefix } from 'ethereumjs-util';
var MIN_ENTROPY_SIZE = 128;
var keccak256 = ethersUtils.keccak256;
/**
* create a privateKey from the given entropy or a new one
* @param {Buffer} entropy
@ -16,9 +15,8 @@ export function createPrivateKey(entropy) {
var outerHex = keccak256(entropy);
return outerHex;
} else {
// @link https://github.com/MaiaVictor/eth-lib/blob/master/lib/account.js#L8
var innerHex = keccak256(Bytes.concat(Bytes.random(32), Bytes.random(32)));
var middleHex = Bytes.concat(Bytes.concat(Bytes.random(32), innerHex), Bytes.random(32));
var innerHex = keccak256(ethersUtils.concat([ethersUtils.randomBytes(32), ethersUtils.randomBytes(32)]));
var middleHex = ethersUtils.concat([ethersUtils.concat([ethersUtils.randomBytes(32), innerHex]), ethersUtils.randomBytes(32)]);
var _outerHex = keccak256(middleHex);
@ -33,7 +31,12 @@ export function createPrivateKey(entropy) {
export default function createIdentity(entropy) {
var privateKey = createPrivateKey(entropy);
var identity = fromPrivate(privateKey);
identity.publicKey = publicKeyByPrivateKey(identity.privateKey);
var wallet = new Wallet(privateKey);
var identity = {
privateKey: privateKey,
// remove trailing '0x04'
publicKey: stripHexPrefix(wallet.publicKey).slice(2),
address: wallet.address
};
return identity;
}

14
dist/es/vrs.js vendored

@ -1,4 +1,4 @@
import { decodeSignature, encodeSignature } from 'eth-lib/lib/account';
import { utils as ethersUtils } from 'ethers';
/**
* split signature-hex into parts
* @param {string} hexString
@ -6,11 +6,12 @@ import { decodeSignature, encodeSignature } from 'eth-lib/lib/account';
*/
export function fromString(hexString) {
var arr = decodeSignature(hexString);
var arr = ethersUtils.splitSignature(hexString);
return {
v: arr[0],
r: arr[1],
s: arr[2]
// convert "v" to hex
v: "0x".concat(arr.v.toString(16)),
r: arr.r,
s: arr.s
};
}
/**
@ -20,6 +21,5 @@ export function fromString(hexString) {
*/
export function toString(sig) {
var partsArray = [sig.v, sig.r, sig.s];
return encodeSignature(partsArray);
return ethersUtils.joinSignature(sig);
}

@ -3,7 +3,7 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = calculateContractAddress;
exports["default"] = calculateContractAddress;
var _ethereumjsUtil = require("ethereumjs-util");

@ -3,8 +3,8 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.stringify = stringify;
exports.parse = parse;
exports.stringify = stringify;
var _publicKey = require("./public-key");

@ -1,22 +1,17 @@
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.createPrivateKey = createPrivateKey;
exports.default = createIdentity;
var _publicKeyByPrivateKey = _interopRequireDefault(require("./public-key-by-private-key"));
var _account = require("eth-lib/lib/account");
exports["default"] = createIdentity;
var _hash = require("eth-lib/lib/hash");
var _ethers = require("ethers");
var _bytes = _interopRequireDefault(require("eth-lib/lib/bytes"));
var _ethereumjsUtil = require("ethereumjs-util");
var MIN_ENTROPY_SIZE = 128;
var keccak256 = _ethers.utils.keccak256;
/**
* create a privateKey from the given entropy or a new one
* @param {Buffer} entropy
@ -27,15 +22,14 @@ function createPrivateKey(entropy) {
if (entropy) {
if (!Buffer.isBuffer(entropy)) throw new Error('EthCrypto.createPrivateKey(): given entropy is no Buffer');
if (Buffer.byteLength(entropy, 'utf8') < MIN_ENTROPY_SIZE) throw new Error('EthCrypto.createPrivateKey(): Entropy-size must be at least ' + MIN_ENTROPY_SIZE);
var outerHex = (0, _hash.keccak256)(entropy);
var outerHex = keccak256(entropy);
return outerHex;
} else {
// @link https://github.com/MaiaVictor/eth-lib/blob/master/lib/account.js#L8
var innerHex = (0, _hash.keccak256)(_bytes.default.concat(_bytes.default.random(32), _bytes.default.random(32)));
var innerHex = keccak256(_ethers.utils.concat([_ethers.utils.randomBytes(32), _ethers.utils.randomBytes(32)]));
var middleHex = _bytes.default.concat(_bytes.default.concat(_bytes.default.random(32), innerHex), _bytes.default.random(32));
var middleHex = _ethers.utils.concat([_ethers.utils.concat([_ethers.utils.randomBytes(32), innerHex]), _ethers.utils.randomBytes(32)]);
var _outerHex = (0, _hash.keccak256)(middleHex);
var _outerHex = keccak256(middleHex);
return _outerHex;
}
@ -49,7 +43,12 @@ function createPrivateKey(entropy) {
function createIdentity(entropy) {
var privateKey = createPrivateKey(entropy);
var identity = (0, _account.fromPrivate)(privateKey);
identity.publicKey = (0, _publicKeyByPrivateKey.default)(identity.privateKey);
var wallet = new _ethers.Wallet(privateKey);
var identity = {
privateKey: privateKey,
// remove trailing '0x04'
publicKey: (0, _ethereumjsUtil.stripHexPrefix)(wallet.publicKey).slice(2),
address: wallet.address
};
return identity;
}

@ -3,7 +3,7 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = decryptWithPrivateKey;
exports["default"] = decryptWithPrivateKey;
var _eccrypto = require("eccrypto");

@ -3,7 +3,7 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = encryptWithPublicKey;
exports["default"] = encryptWithPublicKey;
var _eccrypto = require("eccrypto");

2
dist/lib/hash.js vendored

@ -3,8 +3,8 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.keccak256 = keccak256;
exports.SIGN_PREFIX = void 0;
exports.keccak256 = keccak256;
var _ethers = require("ethers");

66
dist/lib/index.js vendored

@ -1,73 +1,76 @@
"use strict";
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof = require("@babel/runtime/helpers/typeof");
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "calculateContractAddress", {
enumerable: true,
get: function get() {
return _calculateContractAddress["default"];
}
});
exports.cipher = void 0;
Object.defineProperty(exports, "createIdentity", {
enumerable: true,
get: function get() {
return _createIdentity.default;
return _createIdentity["default"];
}
});
Object.defineProperty(exports, "decryptWithPrivateKey", {
enumerable: true,
get: function get() {
return _decryptWithPrivateKey.default;
return _decryptWithPrivateKey["default"];
}
});
exports["default"] = void 0;
Object.defineProperty(exports, "encryptWithPublicKey", {
enumerable: true,
get: function get() {
return _encryptWithPublicKey.default;
return _encryptWithPublicKey["default"];
}
});
exports.publicKey = exports.hex = exports.hash = void 0;
Object.defineProperty(exports, "publicKeyByPrivateKey", {
enumerable: true,
get: function get() {
return _publicKeyByPrivateKey.default;
return _publicKeyByPrivateKey["default"];
}
});
Object.defineProperty(exports, "recover", {
enumerable: true,
get: function get() {
return _recover.default;
return _recover["default"];
}
});
Object.defineProperty(exports, "recoverPublicKey", {
enumerable: true,
get: function get() {
return _recoverPublicKey.default;
return _recoverPublicKey["default"];
}
});
Object.defineProperty(exports, "sign", {
enumerable: true,
get: function get() {
return _sign.default;
return _sign["default"];
}
});
Object.defineProperty(exports, "signTransaction", {
enumerable: true,
get: function get() {
return _signTransaction.default;
return _signTransaction["default"];
}
});
Object.defineProperty(exports, "txDataByCompiled", {
enumerable: true,
get: function get() {
return _txDataByCompiled.default;
return _txDataByCompiled["default"];
}
});
Object.defineProperty(exports, "calculateContractAddress", {
enumerable: true,
get: function get() {
return _calculateContractAddress.default;
}
});
exports.util = exports.vrs = exports.hex = exports.hash = exports.cipher = exports.publicKey = exports.default = void 0;
exports.vrs = exports.util = void 0;
var _createIdentity = _interopRequireDefault(require("./create-identity"));
@ -112,22 +115,27 @@ exports.vrs = vrs;
var util = _interopRequireWildcard(require("./util"));
exports.util = util;
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
var _default = {
createIdentity: _createIdentity.default,
createIdentity: _createIdentity["default"],
publicKey: publicKey,
decryptWithPrivateKey: _decryptWithPrivateKey.default,
encryptWithPublicKey: _encryptWithPublicKey.default,
decryptWithPrivateKey: _decryptWithPrivateKey["default"],
encryptWithPublicKey: _encryptWithPublicKey["default"],
cipher: cipher,
publicKeyByPrivateKey: _publicKeyByPrivateKey.default,
recover: _recover.default,
recoverPublicKey: _recoverPublicKey.default,
sign: _sign.default,
signTransaction: _signTransaction.default,
txDataByCompiled: _txDataByCompiled.default,
calculateContractAddress: _calculateContractAddress.default,
publicKeyByPrivateKey: _publicKeyByPrivateKey["default"],
recover: _recover["default"],
recoverPublicKey: _recoverPublicKey["default"],
sign: _sign["default"],
signTransaction: _signTransaction["default"],
txDataByCompiled: _txDataByCompiled["default"],
calculateContractAddress: _calculateContractAddress["default"],
hash: hash,
hex: hex,
vrs: vrs,
util: util
};
exports.default = _default;
exports["default"] = _default;

@ -3,7 +3,7 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = publicKeyOfPrivateKey;
exports["default"] = publicKeyOfPrivateKey;
var _ethereumjsUtil = require("ethereumjs-util");

@ -3,7 +3,7 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = recoverPublicKey;
exports["default"] = recoverPublicKey;
var _secp256k = require("secp256k1");

@ -5,7 +5,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = recover;
exports["default"] = recover;
var _recoverPublicKey = _interopRequireDefault(require("./recover-public-key"));
@ -18,7 +18,7 @@ var _publicKey = require("./public-key");
* @return {string} address
*/
function recover(sigString, hash) {
var pubkey = (0, _recoverPublicKey.default)(sigString, hash);
var pubkey = (0, _recoverPublicKey["default"])(sigString, hash);
var address = (0, _publicKey.toAddress)(pubkey);
return address;
}

@ -5,7 +5,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = signTransaction;
exports["default"] = signTransaction;
var _tx = require("@ethereumjs/tx");
@ -16,7 +16,7 @@ var _publicKey = require("./public-key");
function signTransaction(rawTx, privateKey) {
var txOptions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
// check if privateKey->address matches rawTx.from
var publicKey = (0, _publicKeyByPrivateKey.default)(privateKey);
var publicKey = (0, _publicKeyByPrivateKey["default"])(privateKey);
var address = (0, _publicKey.toAddress)(publicKey);
if (address != rawTx.from) throw new Error('EthCrypto.signTransaction(): rawTx.from does not match the address of the privateKey');
var privateKeyBuffer = Buffer.from(privateKey.replace(/^.{2}/g, ''), 'hex');

2
dist/lib/sign.js vendored

@ -3,7 +3,7 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = sign;
exports["default"] = sign;
var _secp256k = require("secp256k1");

@ -5,7 +5,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = txDataByCompiled;
exports["default"] = txDataByCompiled;
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
@ -16,6 +16,6 @@ function txDataByCompiled(abi, bytecode, args) {
if (typeof abi === 'string') abi = JSON.parse(abi); // Construct a Contract Factory
var factory = new _ethers.ContractFactory(abi, '0x' + bytecode);
var deployTransaction = factory.getDeployTransaction.apply(factory, (0, _toConsumableArray2.default)(args));
var deployTransaction = factory.getDeployTransaction.apply(factory, (0, _toConsumableArray2["default"])(args));
return deployTransaction.data;
}

4
dist/lib/util.js vendored

@ -3,10 +3,10 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.removeLeading0x = removeLeading0x;
exports.addLeading0x = addLeading0x;
exports.uint8ArrayToHex = uint8ArrayToHex;
exports.hexToUnit8Array = hexToUnit8Array;
exports.removeLeading0x = removeLeading0x;
exports.uint8ArrayToHex = uint8ArrayToHex;
function removeLeading0x(str) {
if (str.startsWith('0x')) return str.substring(2);else return str;

15
dist/lib/vrs.js vendored

@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
exports.fromString = fromString;
exports.toString = toString;
var _account = require("eth-lib/lib/account");
var _ethers = require("ethers");
/**
* split signature-hex into parts
@ -14,11 +14,13 @@ var _account = require("eth-lib/lib/account");
* @return {{v: string, r: string, s: string}}
*/
function fromString(hexString) {
var arr = (0, _account.decodeSignature)(hexString);
var arr = _ethers.utils.splitSignature(hexString);
return {
v: arr[0],
r: arr[1],
s: arr[2]
// convert "v" to hex
v: "0x".concat(arr.v.toString(16)),
r: arr.r,
s: arr.s
};
}
/**
@ -29,6 +31,5 @@ function fromString(hexString) {
function toString(sig) {
var partsArray = [sig.v, sig.r, sig.s];
return (0, _account.encodeSignature)(partsArray);
return _ethers.utils.joinSignature(sig);
}

@ -95,11 +95,10 @@
},
"dependencies": {
"@babel/runtime": "7.16.7",
"@ethereumjs/tx": "3.3.1",
"@ethereumjs/tx": "3.4.0",
"@types/bn.js": "5.1.0",
"eccrypto": "1.1.6",
"eth-lib": "0.2.8",
"ethereumjs-util": "7.1.1",
"ethereumjs-util": "7.1.3",
"ethers": "5.5.4",
"secp256k1": "4.0.3"
}

@ -1,16 +1,8 @@
import publicKeyByPrivateKey from './public-key-by-private-key';
import {
fromPrivate
} from 'eth-lib/lib/account';
import {
keccak256
} from 'eth-lib/lib/hash';
import Bytes from 'eth-lib/lib/bytes';
import { utils as ethersUtils, Wallet } from 'ethers';
import { stripHexPrefix } from 'ethereumjs-util';
const MIN_ENTROPY_SIZE = 128;
const { keccak256 } = ethersUtils;
/**
* create a privateKey from the given entropy or a new one
@ -27,9 +19,8 @@ export function createPrivateKey(entropy) {
const outerHex = keccak256(entropy);
return outerHex;
} else {
// @link https://github.com/MaiaVictor/eth-lib/blob/master/lib/account.js#L8
const innerHex = keccak256(Bytes.concat(Bytes.random(32), Bytes.random(32)));
const middleHex = Bytes.concat(Bytes.concat(Bytes.random(32), innerHex), Bytes.random(32));
const innerHex = keccak256(ethersUtils.concat([ethersUtils.randomBytes(32), ethersUtils.randomBytes(32)]));
const middleHex = ethersUtils.concat([ethersUtils.concat([ethersUtils.randomBytes(32), innerHex]), ethersUtils.randomBytes(32)]);
const outerHex = keccak256(middleHex);
return outerHex;
}
@ -42,7 +33,12 @@ export function createPrivateKey(entropy) {
*/
export default function createIdentity(entropy) {
const privateKey = createPrivateKey(entropy);
const identity = fromPrivate(privateKey);
identity.publicKey = publicKeyByPrivateKey(identity.privateKey);
const wallet = new Wallet(privateKey);
const identity = {
privateKey: privateKey,
// remove trailing '0x04'
publicKey: stripHexPrefix(wallet.publicKey).slice(2),
address: wallet.address,
};
return identity;
}

@ -1,19 +1,18 @@
import {
decodeSignature,
encodeSignature
} from 'eth-lib/lib/account';
utils as ethersUtils
} from 'ethers';
/**
* split signature-hex into parts
* @param {string} hexString
* @return {{v: string, r: string, s: string}}
*/
export function fromString(hexString) {
const arr = decodeSignature(hexString);
const arr = ethersUtils.splitSignature(hexString);
return {
v: arr[0],
r: arr[1],
s: arr[2]
// convert "v" to hex
v: `0x${arr.v.toString(16)}`,
r: arr.r,
s: arr.s,
};
}
@ -23,6 +22,5 @@ export function fromString(hexString) {
* @return {string} hexString
*/
export function toString(sig) {
const partsArray = [sig.v, sig.r, sig.s];
return encodeSignature(partsArray);
return ethersUtils.joinSignature(sig);
}

@ -4,6 +4,7 @@ const path = require('path');
const AsyncTestUtil = require('async-test-util');
const SolidityCli = require('solidity-cli');
const assert = require('assert');
const BN = require('bn.js');
const EthCrypto = require('../dist/lib/index');
// const web3 = EthCrypto.util.web3;
@ -109,7 +110,7 @@ describe('integration.test.js', () => {
const rawTx = {
from: identity.address,
to: '0x63dcee1fd1d814858acd4172bb20e1aa0c947c0a',
value: parseInt(web3.utils.toWei('1', 'ether')),
value: new BN(web3.utils.toWei('1', 'ether')),
nonce: 0,
gasLimit: 60000,
gasPrice: parseInt(gasPrice)

@ -6,6 +6,7 @@
const ganache = require('ganache-cli');
const Web3 = require('web3');
const assert = require('assert');
const BN = require('bn.js');
const EthCrypto = require('../../dist/lib/index');
describe('signed-data.md', () => {
@ -86,7 +87,7 @@ describe('signed-data.md', () => {
from: creatorIdentity.address,
to: contractAddress,
nonce: 1,
value: parseInt(web3.utils.toWei('3', 'ether')),
value: new BN(web3.utils.toWei('3', 'ether')),
gasLimit: 600000,
gasPrice: 20000000000
};

@ -1,5 +1,6 @@
const AsyncTestUtil = require('async-test-util');
const assert = require('assert');
const BN = require('bn.js');
const EthCrypto = require('../dist/lib/index');
const TEST_DATA = {
@ -331,7 +332,7 @@ describe('unit.test.js', () => {
const rawTx = {
from: ident.address,
to: '0x86Fa049857E0209aa7D9e616F7eb3b3B78ECfdb0',
value: 1000000000000000000,
value: new BN('1000000000000000000'),
gasPrice: 5000000000,
gasLimit: 21000
};
@ -348,7 +349,7 @@ describe('unit.test.js', () => {
const rawTx = {
from: ident.address,
to: '0x86Fa049857E0209aa7D9e616F7eb3b3B78ECfdb0',
value: 1000000000000000000,
value: new BN('1000000000000000000'),
gasPrice: 5000000000,
gasLimit: 21000
};

@ -36,7 +36,7 @@ An ethereum-transaction is basically a json-object with defined values. Lets cre
const rawTransaction = {
from: identity.address, // sender address
to: '0x86Fa049857E0209aa7D9e616F7eb3b3B78ECfdb0', // reciever address
value: 1000000000000000000, // amount of wei we want to send (= 1 ether)
value: new BN('1000000000000000000'), // amount of wei we want to send (= 1 ether)
nonce: 0, // incremental tx-number. Add +1 for every transaction you do
gasPrice: 5000000000,
gasLimit: 21000 // normal gasLimit for code-less transactions

@ -1,4 +1,4 @@
import BigNumber = require('bn.js');
import BigNumber from 'bn.js';
import { TxOptions } from '@ethereumjs/tx';
type createIdentityType = (entropy?: Buffer) => {

Loading…
Cancel
Save