Skip to content

Commit

Permalink
Merge pull request #5 from axic/feature/secp256k1
Browse files Browse the repository at this point in the history
hdkey: use the secp256k1 package for crypto
  • Loading branch information
jprichardson committed Mar 23, 2016
2 parents 514054e + ae47568 commit 8f11397
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 27 deletions.
42 changes: 18 additions & 24 deletions lib/hdkey.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
var assert = require('assert')
var crypto = require('crypto')
var BigInteger = require('bigi')
var cs = require('coinstring')
var ecurve = require('ecurve')
var curve = ecurve.getCurveByName('secp256k1')
var Point = ecurve.Point
var secp256k1 = require('secp256k1')

var MASTER_SECRET = new Buffer('Bitcoin seed')
var HARDENED_OFFSET = 0x80000000
Expand Down Expand Up @@ -34,9 +31,10 @@ Object.defineProperty(HDKey.prototype, 'privateKey', {
},
set: function (value) {
assert.equal(value.length, 32, 'Private key must be 32 bytes.')
assert(secp256k1.privateKeyVerify(value) === true, 'Invalid private key')

this._privateKey = value
this._publicPoint = curve.G.multiply(BigInteger.fromBuffer(this._privateKey))
this._publicKey = this._publicPoint.getEncoded(true) // force compressed point
this._publicKey = secp256k1.publicKeyCreate(value, true)
this._identifier = hash160(this.publicKey)
this._fingerprint = this._identifier.slice(0, 4).readUInt32BE(0)
}
Expand All @@ -48,8 +46,9 @@ Object.defineProperty(HDKey.prototype, 'publicKey', {
},
set: function (value) {
assert(value.length === 33 || value.length === 65, 'Public key must be 33 or 65 bytes.')
this._publicPoint = Point.decodeFrom(curve, value)
this._publicKey = this._publicPoint.getEncoded(true) // force compressed point
assert(secp256k1.publicKeyVerify(value) === true, 'Invalid public key')

this._publicKey = secp256k1.publicKeyConvert(value, true) // force compressed point
this._identifier = hash160(this.publicKey)
this._fingerprint = this._identifier.slice(0, 4).readUInt32BE(0)
this._privateKey = null
Expand Down Expand Up @@ -119,33 +118,28 @@ HDKey.prototype.deriveChild = function (index) {
var IR = I.slice(32)

var hd = new HDKey(this.versions)
var pIL = BigInteger.fromBuffer(IL)

// Private parent key -> private child key
if (this.privateKey) {
// ki = parse256(IL) + kpar (mod n)
var ki = pIL.add(BigInteger.fromBuffer(this.privateKey)).mod(curve.n)

// In case parse256(IL) >= n or ki == 0, one should proceed with the next value for i
if (pIL.compareTo(curve.n) >= 0 || ki.signum() === 0) {
try {
hd.privateKey = secp256k1.privateKeyTweakAdd(this.privateKey, IL)
// throw if IL >= n || (privateKey + IL) === 0
} catch (err) {
// In case parse256(IL) >= n or ki == 0, one should proceed with the next value for i
return this.derive(index + 1)
}

// if less than 32 bytes, pad with 0's
hd.privateKey = ki.toBuffer(32)

// Public parent key -> public child key
} else {
// Ki = point(parse256(IL)) + Kpar
// = G*IL + Kpar
var Ki = curve.G.multiply(pIL).add(this._publicPoint)

// In case parse256(IL) >= n or Ki is the point at infinity, one should proceed with the next value for i
if (pIL.compareTo(curve.n) >= 0 || curve.isInfinity(Ki)) {
return this.derive(index + 1)
try {
hd.publicKey = secp256k1.publicKeyTweakAdd(this.publicKey, IL, true)
// throw if IL >= n || (g**IL + publicKey) is infinity
} catch (err) {
// In case parse256(IL) >= n or Ki is the point at infinity, one should proceed with the next value for i
return this.derive(index + 1, isHardened)
}

hd.publicKey = Ki.getEncoded(true)
}

hd.chainCode = IR
Expand Down
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
},
"homepage": "https://github.com/cryptocoinjs/hdkey",
"devDependencies": {
"bigi": "^1.1.0",
"coveralls": "^2.10.0",
"ecurve": "^1.0.0",
"istanbul": "^0.3.17",
"mocha": "^2.2.5",
"mocha-lcov-reporter": "0.0.1",
Expand All @@ -30,9 +32,8 @@
"standard": "4.x"
},
"dependencies": {
"bigi": "^1.1.0",
"ecurve": "^1.0.0",
"coinstring": "^2.0.0"
"coinstring": "^2.0.0",
"secp256k1": "^3.0.1"
},
"scripts": {
"browser-test": "mochify --wd -R spec",
Expand Down

0 comments on commit 8f11397

Please sign in to comment.