Skip to content

Commit

Permalink
Merge pull request #287 from spalladino/handle-large-chainid-on-rpcsig
Browse files Browse the repository at this point in the history
Handle signatures for chainIds greater than 110
  • Loading branch information
holgerd77 authored Feb 1, 2021
2 parents e19262e + cc7850d commit 4ca587e
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 6 deletions.
7 changes: 3 additions & 4 deletions src/signature.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const { ecdsaSign, ecdsaRecover, publicKeyConvert } = require('ethereum-cryptography/secp256k1')
import * as BN from 'bn.js'
import { toBuffer, setLengthLeft, bufferToHex } from './bytes'
import { toBuffer, setLengthLeft, bufferToHex, bufferToInt } from './bytes'
import { keccak } from './hash'
import { assertIsBuffer } from './helpers'

Expand Down Expand Up @@ -71,12 +71,11 @@ export const toRpcSig = function(v: number, r: Buffer, s: Buffer, chainId?: numb
export const fromRpcSig = function(sig: string): ECDSASignature {
const buf: Buffer = toBuffer(sig)

// NOTE: with potential introduction of chainId this might need to be updated
if (buf.length !== 65) {
if (buf.length < 65) {
throw new Error('Invalid signature length')
}

let v = buf[64]
let v = bufferToInt(buf.slice(64))
// support both versions of `eth_sign` responses
if (v < 27) {
v += 27
Expand Down
52 changes: 50 additions & 2 deletions test/signature.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,20 @@ describe('ecsign', function() {
)
assert.equal(sig.v, 41)
})

it('should produce a signature for chainId=150', function() {
const chainId = 150
const sig = ecsign(echash, ecprivkey, chainId)
assert.deepEqual(
sig.r,
Buffer.from('99e71a99cb2270b8cac5254f9e99b6210c6c10224a1579cf389ef88b20a1abe9', 'hex'),
)
assert.deepEqual(
sig.s,
Buffer.from('129ff05af364204442bdb53ab6f18a99ab48acc9326fa689f228040429e3ca66', 'hex'),
)
assert.equal(sig.v, chainId * 2 + 35)
})
})

describe('ecrecover', function() {
Expand All @@ -63,6 +77,14 @@ describe('ecrecover', function() {
const pubkey = ecrecover(echash, v, r, s, chainId)
assert.deepEqual(pubkey, privateToPublic(ecprivkey))
})
it('should recover a public key (chainId = 150)', function() {
const chainId = 150
const r = Buffer.from('99e71a99cb2270b8cac5254f9e99b6210c6c10224a1579cf389ef88b20a1abe9', 'hex')
const s = Buffer.from('129ff05af364204442bdb53ab6f18a99ab48acc9326fa689f228040429e3ca66', 'hex')
const v = chainId * 2 + 35
const pubkey = ecrecover(echash, v, r, s, chainId)
assert.deepEqual(pubkey, privateToPublic(ecprivkey))
})
it('should fail on an invalid signature (v = 21)', function() {
const r = Buffer.from('99e71a99cb2270b8cac5254f9e99b6210c6c10224a1579cf389ef88b20a1abe9', 'hex')
const s = Buffer.from('129ff05af364204442bdb53ab6f18a99ab48acc9326fa689f228040429e3ca66', 'hex')
Expand Down Expand Up @@ -160,6 +182,13 @@ describe('isValidSignature', function() {
const v = 41
assert.equal(isValidSignature(v, r, s, false, chainId), true)
})
it('should work otherwise(chainId=150)', function() {
const chainId = 150
const r = Buffer.from('99e71a99cb2270b8cac5254f9e99b6210c6c10224a1579cf389ef88b20a1abe9', 'hex')
const s = Buffer.from('129ff05af364204442bdb53ab6f18a99ab48acc9326fa689f228040429e3ca66', 'hex')
const v = chainId * 2 + 35
assert.equal(isValidSignature(v, r, s, false, chainId), true)
})
// FIXME: add homestead test
})

Expand Down Expand Up @@ -194,13 +223,32 @@ describe('message sig', function() {
)
})

it('should throw on invalid length', function() {
it('should return hex strings that the RPC can use (chainId=150)', function() {
const chainId = 150
const v = chainId * 2 + 35
assert.equal(
toRpcSig(v, r, s, chainId),
'0x99e71a99cb2270b8cac5254f9e99b6210c6c10224a1579cf389ef88b20a1abe9129ff05af364204442bdb53ab6f18a99ab48acc9326fa689f228040429e3ca66014f',
)
assert.deepEqual(
fromRpcSig(
'0x99e71a99cb2270b8cac5254f9e99b6210c6c10224a1579cf389ef88b20a1abe9129ff05af364204442bdb53ab6f18a99ab48acc9326fa689f228040429e3ca66014f',
),
{
v,
r: r,
s: s,
},
)
})

it('should throw on shorter length', function() {
assert.throws(function() {
fromRpcSig('')
})
assert.throws(function() {
fromRpcSig(
'0x99e71a99cb2270b8cac5254f9e99b6210c6c10224a1579cf389ef88b20a1abe9129ff05af364204442bdb53ab6f18a99ab48acc9326fa689f228040429e3ca660042',
'0x99e71a99cb2270b8cac5254f9e99b6210c6c10224a1579cf389ef88b20a1abe9129ff05af364204442bdb53ab6f18a99ab48acc9326fa689f228040429e3ca',
)
})
})
Expand Down

0 comments on commit 4ca587e

Please sign in to comment.