Adds BI.toPaddedBuffer and toBuffer
This commit is contained in:
parent
596b31b1e1
commit
d8883e8d32
8 changed files with 131 additions and 26 deletions
|
@ -55,12 +55,11 @@ function decode(string) {
|
|||
i++
|
||||
}
|
||||
|
||||
// FIXME: If BigInteger supported buffers, this could be a copy
|
||||
var buffer = new Buffer(num.toByteArrayUnsigned())
|
||||
var padding = new Buffer(i)
|
||||
padding.fill(0)
|
||||
var buffer = num.toBuffer()
|
||||
var leadz = new Buffer(i)
|
||||
leadz.fill(0)
|
||||
|
||||
return Buffer.concat([padding, buffer])
|
||||
return Buffer.concat([leadz, buffer])
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
|
27
src/bigi.js
27
src/bigi.js
|
@ -1,7 +1,17 @@
|
|||
var assert = require('assert')
|
||||
var BigInteger = require('bigi')
|
||||
|
||||
// Import operations
|
||||
BigInteger.fromHex = function(hex) {
|
||||
var buffer = new Buffer(hex, 'hex')
|
||||
assert.equal(buffer.length, Buffer.byteLength(hex) / 2)
|
||||
|
||||
return BigInteger.fromBuffer(buffer)
|
||||
}
|
||||
|
||||
BigInteger.fromBuffer = function(buffer) {
|
||||
assert(Array.isArray(buffer) || Buffer.isBuffer(buffer)) // FIXME: Transitionary
|
||||
|
||||
// FIXME: Transitionary
|
||||
if (Buffer.isBuffer(buffer)) {
|
||||
buffer = Array.prototype.slice.call(buffer)
|
||||
|
@ -10,4 +20,21 @@ BigInteger.fromBuffer = function(buffer) {
|
|||
return BigInteger.fromByteArrayUnsigned(buffer)
|
||||
}
|
||||
|
||||
// Export operations
|
||||
BigInteger.prototype.toBuffer = function() {
|
||||
return new Buffer(this.toByteArrayUnsigned())
|
||||
}
|
||||
|
||||
BigInteger.prototype.toHex = function() {
|
||||
return this.toBuffer().toString('hex')
|
||||
}
|
||||
|
||||
BigInteger.prototype.toPaddedBuffer = function(s) {
|
||||
var buffer = this.toBuffer()
|
||||
var padded = new Buffer(s - buffer.length)
|
||||
padded.fill(0)
|
||||
|
||||
return Buffer.concat([padded, buffer], s)
|
||||
}
|
||||
|
||||
module.exports = BigInteger
|
||||
|
|
|
@ -65,13 +65,7 @@ ECKey.prototype.sign = function(hash) {
|
|||
|
||||
// Export functions
|
||||
ECKey.prototype.toBuffer = function() {
|
||||
var buffer = new Buffer(this.D.toByteArrayUnsigned())
|
||||
|
||||
// pad out to atleast 32 bytes
|
||||
var padded = new Buffer(32 - buffer.length)
|
||||
padded.fill(0)
|
||||
|
||||
return Buffer.concat([padded, buffer])
|
||||
return this.D.toPaddedBuffer(32)
|
||||
}
|
||||
ECKey.prototype.toHex = function() {
|
||||
return this.toBuffer().toString('hex')
|
||||
|
|
|
@ -25,25 +25,18 @@ function magicHash(message) {
|
|||
// TODO: parameterize compression instead of using ECKey.compressed
|
||||
function sign(key, message) {
|
||||
var hash = magicHash(message)
|
||||
var sig = key.sign(hash)
|
||||
var obj = ecdsa.parseSig(sig)
|
||||
var i = ecdsa.calcPubKeyRecoveryParam(key.pub.Q, obj.r, obj.s, hash)
|
||||
var sig = ecdsa.parseSig(key.sign(hash))
|
||||
var i = ecdsa.calcPubKeyRecoveryParam(key.pub.Q, sig.r, sig.s, hash)
|
||||
|
||||
i += 27
|
||||
if (key.pub.compressed) {
|
||||
i += 4
|
||||
}
|
||||
|
||||
var rBa = obj.r.toByteArrayUnsigned()
|
||||
var sBa = obj.s.toByteArrayUnsigned()
|
||||
var rB = sig.r.toPaddedBuffer(32)
|
||||
var sB = sig.s.toPaddedBuffer(32)
|
||||
|
||||
// Pad to 32 bytes per value
|
||||
while (rBa.length < 32) rBa.unshift(0);
|
||||
while (sBa.length < 32) sBa.unshift(0);
|
||||
|
||||
sig = [i].concat(rBa, sBa)
|
||||
|
||||
return sig
|
||||
return Buffer.concat([new Buffer([i]), rB, sB], 65)
|
||||
}
|
||||
|
||||
// FIXME: stricter API?
|
||||
|
|
46
test/bigi.js
Normal file
46
test/bigi.js
Normal file
|
@ -0,0 +1,46 @@
|
|||
var assert = require('assert')
|
||||
var BigInteger = require('../').BigInteger
|
||||
|
||||
var fixtures = require('./fixtures/bigi')
|
||||
|
||||
describe('BigInteger', function() {
|
||||
describe('fromBuffer/fromHex', function() {
|
||||
it('should match the test vectors', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
assert.deepEqual(BigInteger.fromHex(f.hex).toString(), f.dec)
|
||||
assert.deepEqual(BigInteger.fromHex(f.hexPadded).toString(), f.dec)
|
||||
})
|
||||
})
|
||||
|
||||
fixtures.invalid.forEach(function(f) {
|
||||
it('throws on ' + f.description, function() {
|
||||
assert.throws(function() {
|
||||
BigInteger.fromHex(f.string)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('toBuffer/toHex', function() {
|
||||
it('should match the test vectors', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
var actualHex = new BigInteger(f.dec).toHex()
|
||||
|
||||
assert.equal(actualHex, f.hex)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('toPaddedBuffer', function() {
|
||||
it('should match the test vectors', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
var actualBuf = new BigInteger(f.dec).toPaddedBuffer(32)
|
||||
|
||||
assert.equal(actualBuf.length, 32)
|
||||
assert.equal(actualBuf.toString('hex'), f.hexPadded)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
module.exports = BigInteger
|
|
@ -39,7 +39,7 @@ describe('ecdsa', function() {
|
|||
var sig_a = s1.sign([0])
|
||||
|
||||
assert.ok(sig_a, 'Sign null')
|
||||
assert.ok(s1.pub.verify(BigInteger.ZERO, sig_a))
|
||||
assert.ok(s1.pub.verify([0], sig_a))
|
||||
|
||||
var message = new Buffer(1024) // More or less random :P
|
||||
var hash = crypto.sha256(message)
|
||||
|
|
46
test/fixtures/bigi.js
vendored
Normal file
46
test/fixtures/bigi.js
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
module.exports = {
|
||||
"valid": [
|
||||
{
|
||||
"dec": "1",
|
||||
"hex": "01",
|
||||
"hexPadded": "0000000000000000000000000000000000000000000000000000000000000001"
|
||||
},
|
||||
{
|
||||
"dec": "158798437896437949616241483468158498679",
|
||||
"hex": "77777777777777777777777777777777",
|
||||
"hexPadded": "0000000000000000000000000000000077777777777777777777777777777777"
|
||||
},
|
||||
{
|
||||
"dec": "115792089237316195423570985008687907852837564279074904382605163141518161494336",
|
||||
"hex": "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140",
|
||||
"hexPadded": "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140"
|
||||
},
|
||||
{
|
||||
"dec": "48968302285117906840285529799176770990048954789747953886390402978935544927851",
|
||||
"hex": "6c4313b03f2e7324d75e642f0ab81b734b724e13fec930f309e222470236d66b",
|
||||
"hexPadded": "6c4313b03f2e7324d75e642f0ab81b734b724e13fec930f309e222470236d66b"
|
||||
}
|
||||
],
|
||||
"invalid": [
|
||||
{
|
||||
"description": "non-hex string",
|
||||
"string": "invalid"
|
||||
},
|
||||
{
|
||||
"description": "non-hex alphabet",
|
||||
"string": "c2F0b3NoaQo="
|
||||
},
|
||||
{
|
||||
"description": "internal whitespace",
|
||||
"string": "11111 11111"
|
||||
},
|
||||
{
|
||||
"description": "leading whitespace",
|
||||
"string": " 1111111111"
|
||||
},
|
||||
{
|
||||
"description": "trailing whitespace",
|
||||
"string": "1111111111 "
|
||||
}
|
||||
]
|
||||
}
|
Loading…
Reference in a new issue