Sign Message v3 compatibility (#880)

* Change signed message shape to match v3

* Unit tests for signing

* Change subtab text.
This commit is contained in:
William O'Beirne 2018-01-22 15:27:37 -05:00 committed by Daniel Ternyak
parent 2d13c04835
commit 592caaaf47
5 changed files with 46 additions and 16 deletions

View File

@ -26,8 +26,8 @@ export default class SignMessageButton extends React.Component<Props, {}> {
try { try {
const signedMessage: ISignedMessage = { const signedMessage: ISignedMessage = {
address: await wallet.getAddressString(), address: await wallet.getAddressString(),
message, msg: message,
signature: await wallet.signMessage(message), sig: await wallet.signMessage(message),
version: '2' version: '2'
}; };

View File

@ -20,8 +20,13 @@ const initialState: State = {
signature: '' signature: ''
}; };
const signaturePlaceholder = const signatureExample: ISignedMessage = {
'{"address":"0x7cB57B5A97eAbe94205C07890BE4c1aD31E486A8","message":"asdfasdfasdf","signature":"0x4771d78f13ba8abf608457f12471f427ca8f2fb046c1acb3f5969eefdfe452a10c9154136449f595a654b44b3b0163e86dd099beaca83bfd52d64c21da2221bb1c","version":"2"}'; address: '0x7cB57B5A97eAbe94205C07890BE4c1aD31E486A8',
msg: 'asdfasdfasdf',
sig: '0x4771d78f13ba...',
version: '2'
};
const signaturePlaceholder = JSON.stringify(signatureExample, null, 2);
export class VerifyMessage extends Component<Props, State> { export class VerifyMessage extends Component<Props, State> {
public state: State = initialState; public state: State = initialState;
@ -82,10 +87,10 @@ export class VerifyMessage extends Component<Props, State> {
throw Error(); throw Error();
} }
const { address, message } = parsedSignature; const { address, msg } = parsedSignature;
this.setState({ this.setState({
verifiedAddress: address, verifiedAddress: address,
verifiedMessage: message verifiedMessage: msg
}); });
this.props.showNotification('success', translate('SUCCESS_7')); this.props.showNotification('success', translate('SUCCESS_7'));
} catch (err) { } catch (err) {

View File

@ -26,11 +26,11 @@ export default class SignAndVerifyMessage extends Component<RouteComponentProps<
const tabs = [ const tabs = [
{ {
path: 'sign', path: 'sign',
name: translate('Sign') name: translate('NAV_SignMsg')
}, },
{ {
path: 'verify', path: 'verify',
name: translate('Verify') name: translate('MSG_verify')
} }
]; ];

View File

@ -32,22 +32,22 @@ export function signMessageWithPrivKeyV2(privKey: Buffer, msg: string): string {
export interface ISignedMessage { export interface ISignedMessage {
address: string; address: string;
message: string; msg: string;
signature: string; sig: string;
version: string; version: string;
} }
// adapted from: // adapted from:
// https://github.com/kvhnuke/etherwallet/blob/2a5bc0db1c65906b14d8c33ce9101788c70d3774/app/scripts/controllers/signMsgCtrl.js#L118 // https://github.com/kvhnuke/etherwallet/blob/2a5bc0db1c65906b14d8c33ce9101788c70d3774/app/scripts/controllers/signMsgCtrl.js#L118
export function verifySignedMessage({ address, message, signature, version }: ISignedMessage) { export function verifySignedMessage({ address, msg, sig, version }: ISignedMessage) {
const sig = new Buffer(stripHexPrefixAndLower(signature), 'hex'); const sigb = new Buffer(stripHexPrefixAndLower(sig), 'hex');
if (sig.length !== 65) { if (sigb.length !== 65) {
return false; return false;
} }
//TODO: explain what's going on here //TODO: explain what's going on here
sig[64] = sig[64] === 0 || sig[64] === 1 ? sig[64] + 27 : sig[64]; sigb[64] = sigb[64] === 0 || sigb[64] === 1 ? sigb[64] + 27 : sigb[64];
const hash = version === '2' ? hashPersonalMessage(toBuffer(message)) : sha3(message); const hash = version === '2' ? hashPersonalMessage(toBuffer(msg)) : sha3(msg);
const pubKey = ecrecover(hash, sig[64], sig.slice(0, 32), sig.slice(32, 64)); const pubKey = ecrecover(hash, sigb[64], sigb.slice(0, 32), sigb.slice(32, 64));
return stripHexPrefixAndLower(address) === pubToAddress(pubKey).toString('hex'); return stripHexPrefixAndLower(address) === pubToAddress(pubKey).toString('hex');
} }

25
spec/libs/signing.spec.ts Normal file
View File

@ -0,0 +1,25 @@
import { getPrivKeyWallet } from 'libs/wallet';
import { signMessageWithPrivKeyV2, verifySignedMessage } from 'libs/signing';
describe('lib/signing', () => {
const msgToSign = 'Testing your code is great!';
const msgToVerify = {
address: '0x6980ba0ab378c2ed0efccd7ea6ab84d54615a2de',
msg: msgToSign,
sig:
'0xf08688e9dddbb5e4e0d1fb685ee9f693accb3c9aac84fdcf327423ca4a1c50463ef7aeb70be3221fe028bc752e210a4c377db8090bc4efa5ea7d391049c3a4771c',
version: '2'
};
const msgWallet = getPrivKeyWallet(
'05fb863d5da01481d52a629b7d07ee0b50c394503567318f2801cbac1901113b',
''
);
it('signMessageWithPrivKeyV2 properly signs a message', () => {
expect(signMessageWithPrivKeyV2(msgWallet.getPrivateKey(), msgToSign)).toEqual(msgToVerify.sig);
});
it('verifySignedMessage properly verifies a signed message', () => {
expect(verifySignedMessage(msgToVerify)).toBeTruthy();
});
});