Bringing back js-sha3
to fix in-browser signing (#4063)
* Bring back Uint8Array sha3 support * Added SHA3 test with HEX encoding * Rename hex2Ascii => hexToAscii Add tests or the api/util/format functions Use js-sha3 for sha3 with hex encoding support * Adding Uint8Array test * Fixing Transaction import
This commit is contained in:
parent
52d3633473
commit
f6349187ef
@ -139,7 +139,6 @@
|
|||||||
"blockies": "0.0.2",
|
"blockies": "0.0.2",
|
||||||
"brace": "0.9.0",
|
"brace": "0.9.0",
|
||||||
"bytes": "2.4.0",
|
"bytes": "2.4.0",
|
||||||
"crypto-js": "3.1.9-1",
|
|
||||||
"debounce": "1.0.0",
|
"debounce": "1.0.0",
|
||||||
"es6-error": "4.0.0",
|
"es6-error": "4.0.0",
|
||||||
"es6-promise": "4.0.5",
|
"es6-promise": "4.0.5",
|
||||||
|
@ -20,15 +20,21 @@ export function bytesToHex (bytes) {
|
|||||||
return '0x' + bytes.map((b) => ('0' + b.toString(16)).slice(-2)).join('');
|
return '0x' + bytes.map((b) => ('0' + b.toString(16)).slice(-2)).join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function hex2Ascii (_hex) {
|
export function hexToBytes (hex) {
|
||||||
const hex = /^(?:0x)?(.*)$/.exec(_hex.toString())[1];
|
const raw = toHex(hex).slice(2);
|
||||||
|
const bytes = [];
|
||||||
|
|
||||||
let str = '';
|
for (let i = 0; i < raw.length; i += 2) {
|
||||||
|
bytes.push(parseInt(raw.substr(i, 2), 16));
|
||||||
for (let i = 0; i < hex.length; i += 2) {
|
|
||||||
str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function hexToAscii (hex) {
|
||||||
|
const bytes = hexToBytes(hex);
|
||||||
|
const str = bytes.map((byte) => String.fromCharCode(byte)).join('');
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import { bytesToHex } from './format';
|
import { bytesToHex, hexToBytes, hexToAscii, bytesToAscii, asciiToHex } from './format';
|
||||||
|
|
||||||
describe('api/util/format', () => {
|
describe('api/util/format', () => {
|
||||||
describe('bytesToHex', () => {
|
describe('bytesToHex', () => {
|
||||||
@ -26,4 +26,46 @@ describe('api/util/format', () => {
|
|||||||
expect(bytesToHex([0, 15, 16])).to.equal('0x000f10');
|
expect(bytesToHex([0, 15, 16])).to.equal('0x000f10');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('hexToBytes', () => {
|
||||||
|
it('correctly converts an empty string', () => {
|
||||||
|
expect(hexToBytes('')).to.deep.equal([]);
|
||||||
|
expect(hexToBytes('0x')).to.deep.equal([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('correctly converts a non-empty string', () => {
|
||||||
|
expect(hexToBytes('0x000f10')).to.deep.equal([0, 15, 16]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('asciiToHex', () => {
|
||||||
|
it('correctly converts an empty string', () => {
|
||||||
|
expect(asciiToHex('')).to.equal('0x');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('correctly converts a non-empty string', () => {
|
||||||
|
expect(asciiToHex('abc')).to.equal('0x616263');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('hexToAscii', () => {
|
||||||
|
it('correctly converts an empty string', () => {
|
||||||
|
expect(hexToAscii('')).to.equal('');
|
||||||
|
expect(hexToAscii('0x')).to.equal('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('correctly converts a non-empty string', () => {
|
||||||
|
expect(hexToAscii('0x616263')).to.equal('abc');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('bytesToAscii', () => {
|
||||||
|
it('correctly converts an empty string', () => {
|
||||||
|
expect(bytesToAscii([])).to.equal('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('correctly converts a non-empty string', () => {
|
||||||
|
expect(bytesToAscii([97, 98, 99])).to.equal('abc');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
import { isAddress as isAddressValid, toChecksumAddress } from '../../abi/util/address';
|
import { isAddress as isAddressValid, toChecksumAddress } from '../../abi/util/address';
|
||||||
import { decodeCallData, decodeMethodInput, methodToAbi } from './decode';
|
import { decodeCallData, decodeMethodInput, methodToAbi } from './decode';
|
||||||
import { bytesToHex, hex2Ascii, asciiToHex } from './format';
|
import { bytesToHex, hexToAscii, asciiToHex } from './format';
|
||||||
import { fromWei, toWei } from './wei';
|
import { fromWei, toWei } from './wei';
|
||||||
import { sha3 } from './sha3';
|
import { sha3 } from './sha3';
|
||||||
import { isArray, isFunction, isHex, isInstanceOf, isString } from './types';
|
import { isArray, isFunction, isHex, isInstanceOf, isString } from './types';
|
||||||
@ -30,7 +30,7 @@ export default {
|
|||||||
isInstanceOf,
|
isInstanceOf,
|
||||||
isString,
|
isString,
|
||||||
bytesToHex,
|
bytesToHex,
|
||||||
hex2Ascii,
|
hexToAscii,
|
||||||
asciiToHex,
|
asciiToHex,
|
||||||
createIdentityImg,
|
createIdentityImg,
|
||||||
decodeCallData,
|
decodeCallData,
|
||||||
|
@ -14,21 +14,17 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import CryptoJS from 'crypto-js';
|
import { keccak_256 } from 'js-sha3'; // eslint-disable-line
|
||||||
import CryptoSha3 from 'crypto-js/sha3';
|
|
||||||
|
import { hexToBytes } from './format';
|
||||||
|
|
||||||
export function sha3 (value, options) {
|
export function sha3 (value, options) {
|
||||||
if (options && options.encoding === 'hex') {
|
if (options && options.encoding === 'hex') {
|
||||||
if (value.length > 2 && value.substr(0, 2) === '0x') {
|
const bytes = hexToBytes(value);
|
||||||
value = value.substr(2);
|
return sha3(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
value = CryptoJS.enc.Hex.parse(value);
|
const hash = keccak_256(value);
|
||||||
}
|
|
||||||
|
|
||||||
const hash = CryptoSha3(value, {
|
|
||||||
outputLength: 256
|
|
||||||
}).toString();
|
|
||||||
|
|
||||||
return `0x${hash}`;
|
return `0x${hash}`;
|
||||||
}
|
}
|
||||||
|
@ -21,5 +21,16 @@ describe('api/util/sha3', () => {
|
|||||||
it('constructs a correct sha3 value', () => {
|
it('constructs a correct sha3 value', () => {
|
||||||
expect(sha3('jacogr')).to.equal('0x2f4ff4b5a87abbd2edfed699db48a97744e028c7f7ce36444d40d29d792aa4dc');
|
expect(sha3('jacogr')).to.equal('0x2f4ff4b5a87abbd2edfed699db48a97744e028c7f7ce36444d40d29d792aa4dc');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('constructs a correct sha3 encoded as hex', () => {
|
||||||
|
const key = '000000000000000000000000391694e7e0b0cce554cb130d723a9d27458f9298' + '0000000000000000000000000000000000000000000000000000000000000001';
|
||||||
|
expect(sha3(key, { encoding: 'hex' })).to.equal('0x6661e9d6d8b923d5bbaab1b96e1dd51ff6ea2a93520fdc9eb75d059238b8c5e9');
|
||||||
|
expect(sha3(`0x${key}`, { encoding: 'hex' })).to.equal('0x6661e9d6d8b923d5bbaab1b96e1dd51ff6ea2a93520fdc9eb75d059238b8c5e9');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('constructs a correct sha3 from Uint8Array', () => {
|
||||||
|
expect(sha3('01020304', { encoding: 'hex' })).to.equal('0xa6885b3731702da62e8e4a8f584ac46a7f6822f4e2ba50fba902f67b1588d23b');
|
||||||
|
expect(sha3(Uint8Array.from([1, 2, 3, 4]))).to.equal('0xa6885b3731702da62e8e4a8f584ac46a7f6822f4e2ba50fba902f67b1588d23b');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import { bytesToHex, hex2Ascii } from '~/api/util/format';
|
import { bytesToHex, hexToAscii } from '~/api/util/format';
|
||||||
|
|
||||||
import ABI from './abi/certifier.json';
|
import ABI from './abi/certifier.json';
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ export default class BadgeReg {
|
|||||||
name = bytesToHex(name);
|
name = bytesToHex(name);
|
||||||
name = name === ZERO32
|
name = name === ZERO32
|
||||||
? null
|
? null
|
||||||
: hex2Ascii(name);
|
: hexToAscii(name);
|
||||||
|
|
||||||
return this.fetchMeta(id)
|
return this.fetchMeta(id)
|
||||||
.then(({ title, icon }) => {
|
.then(({ title, icon }) => {
|
||||||
@ -84,7 +84,7 @@ export default class BadgeReg {
|
|||||||
})
|
})
|
||||||
.then(([ title, icon ]) => {
|
.then(([ title, icon ]) => {
|
||||||
title = bytesToHex(title);
|
title = bytesToHex(title);
|
||||||
title = title === ZERO32 ? null : hex2Ascii(title);
|
title = title === ZERO32 ? null : hexToAscii(title);
|
||||||
|
|
||||||
if (bytesToHex(icon) === ZERO32) {
|
if (bytesToHex(icon) === ZERO32) {
|
||||||
icon = null;
|
icon = null;
|
||||||
|
@ -167,7 +167,7 @@ class MethodDecoding extends Component {
|
|||||||
getAscii () {
|
getAscii () {
|
||||||
const { api } = this.context;
|
const { api } = this.context;
|
||||||
const { transaction } = this.props;
|
const { transaction } = this.props;
|
||||||
const ascii = api.util.hex2Ascii(transaction.input || transaction.data);
|
const ascii = api.util.hexToAscii(transaction.input || transaction.data);
|
||||||
|
|
||||||
return { value: ascii, valid: ASCII_INPUT.test(ascii) };
|
return { value: ascii, valid: ASCII_INPUT.test(ascii) };
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import scrypt from 'scryptsy';
|
import scrypt from 'scryptsy';
|
||||||
import Transaction from 'ethereumjs-tx';
|
import * as Transaction from 'ethereumjs-tx';
|
||||||
import { pbkdf2Sync } from 'crypto';
|
import { pbkdf2Sync } from 'crypto';
|
||||||
import { createDecipheriv } from 'browserify-aes';
|
import { createDecipheriv } from 'browserify-aes';
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user