Skip to content

Commit

Permalink
Add wipePrivateData method (#22)
Browse files Browse the repository at this point in the history
  • Loading branch information
RyanZim authored and jprichardson committed Aug 11, 2018
1 parent fdce425 commit 6244516
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 0 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ Signs the buffer `hash` with the private key using `secp256k1` and returns the s

Verifies that the `signature` is valid for `hash` and the `hdkey`'s public key using `secp256k1`. Returns `true` for valid, `false` for invalid. Throws if the `hash` or `signature` is the wrong length.

### `hdkey.wipePrivateData()`

Wipes all record of the private key from the `hdkey` instance. After calling this method, the instance will behave as if it was created via `HDKey.fromExtendedKey(xpub)`.

### `hdkey.toJSON()`

Serializes the `hdkey` to an object that can be `JSON.stringify()`ed.
Expand Down
6 changes: 6 additions & 0 deletions lib/hdkey.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,12 @@ HDKey.prototype.verify = function (hash, signature) {
return secp256k1.verify(hash, signature, this.publicKey)
}

HDKey.prototype.wipePrivateData = function () {
if (this._privateKey) crypto.randomBytes(this._privateKey.length).copy(this._privateKey)
this._privateKey = null
return this
}

HDKey.prototype.toJSON = function () {
return {
xpriv: this.privateExtendedKey,
Expand Down
42 changes: 42 additions & 0 deletions test/hdkey.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,4 +211,46 @@ describe('hdkey', function () {
}, /Path must start with "m" or "M"/)
})
})

describe('- after wipePrivateData()', function () {
it('should not have private data', function () {
const hdkey = HDKey.fromMasterSeed(Buffer.from(fixtures.valid[6].seed, 'hex')).wipePrivateData()
assert.equal(hdkey.privateKey, null)
assert.equal(hdkey.privateExtendedKey, null)
assert.throws(() => hdkey.sign(Buffer.alloc(32)), "shouldn't be able to sign")
const childKey = hdkey.derive('m/0')
assert.equal(childKey.publicExtendedKey, fixtures.valid[7].public)
assert.equal(childKey.privateKey, null)
assert.equal(childKey.privateExtendedKey, null)
})

it('should have correct data', function () {
// m/0/2147483647'/1/2147483646'/2
const key = 'xprvA2nrNbFZABcdryreWet9Ea4LvTJcGsqrMzxHx98MMrotbir7yrKCEXw7nadnHM8Dq38EGfSh6dqA9QWTyefMLEcBYJUuekgW4BYPJcr9E7j'
const hdkey = HDKey.fromExtendedKey(key).wipePrivateData()
assert.equal(hdkey.versions.private, 0x0488ade4)
assert.equal(hdkey.versions.public, 0x0488b21e)
assert.equal(hdkey.depth, 5)
assert.equal(hdkey.parentFingerprint, 0x31a507b8)
assert.equal(hdkey.index, 2)
assert.equal(hdkey.chainCode.toString('hex'), '9452b549be8cea3ecb7a84bec10dcfd94afe4d129ebfd3b3cb58eedf394ed271')
assert.equal(hdkey.publicKey.toString('hex'), '024d902e1a2fc7a8755ab5b694c575fce742c48d9ff192e63df5193e4c7afe1f9c')
assert.equal(hdkey.identifier.toString('hex'), '26132fdbe7bf89cbc64cf8dafa3f9f88b8666220')
})

it('should be able to verify signatures', function () {
const fullKey = HDKey.fromMasterSeed(fixtures.valid[0].seed)
// using JSON methods to clone before mutating
const wipedKey = HDKey.fromJSON(fullKey.toJSON()).wipePrivateData()

const hash = Buffer.alloc(32, 8)
assert.ok(wipedKey.verify(hash, fullKey.sign(hash)))
})

it('should not throw if called on hdkey without private data', function () {
const hdkey = HDKey.fromExtendedKey(fixtures.valid[0].public)
assert.doesNotThrow(() => hdkey.wipePrivateData())
assert.equal(hdkey.publicExtendedKey, fixtures.valid[0].public)
})
})
})

0 comments on commit 6244516

Please sign in to comment.