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++
|
i++
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: If BigInteger supported buffers, this could be a copy
|
var buffer = num.toBuffer()
|
||||||
var buffer = new Buffer(num.toByteArrayUnsigned())
|
var leadz = new Buffer(i)
|
||||||
var padding = new Buffer(i)
|
leadz.fill(0)
|
||||||
padding.fill(0)
|
|
||||||
|
|
||||||
return Buffer.concat([padding, buffer])
|
return Buffer.concat([leadz, buffer])
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
27
src/bigi.js
27
src/bigi.js
|
@ -1,7 +1,17 @@
|
||||||
var assert = require('assert')
|
var assert = require('assert')
|
||||||
var BigInteger = require('bigi')
|
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) {
|
BigInteger.fromBuffer = function(buffer) {
|
||||||
|
assert(Array.isArray(buffer) || Buffer.isBuffer(buffer)) // FIXME: Transitionary
|
||||||
|
|
||||||
// FIXME: Transitionary
|
// FIXME: Transitionary
|
||||||
if (Buffer.isBuffer(buffer)) {
|
if (Buffer.isBuffer(buffer)) {
|
||||||
buffer = Array.prototype.slice.call(buffer)
|
buffer = Array.prototype.slice.call(buffer)
|
||||||
|
@ -10,4 +20,21 @@ BigInteger.fromBuffer = function(buffer) {
|
||||||
return BigInteger.fromByteArrayUnsigned(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
|
module.exports = BigInteger
|
||||||
|
|
|
@ -65,13 +65,7 @@ ECKey.prototype.sign = function(hash) {
|
||||||
|
|
||||||
// Export functions
|
// Export functions
|
||||||
ECKey.prototype.toBuffer = function() {
|
ECKey.prototype.toBuffer = function() {
|
||||||
var buffer = new Buffer(this.D.toByteArrayUnsigned())
|
return this.D.toPaddedBuffer(32)
|
||||||
|
|
||||||
// pad out to atleast 32 bytes
|
|
||||||
var padded = new Buffer(32 - buffer.length)
|
|
||||||
padded.fill(0)
|
|
||||||
|
|
||||||
return Buffer.concat([padded, buffer])
|
|
||||||
}
|
}
|
||||||
ECKey.prototype.toHex = function() {
|
ECKey.prototype.toHex = function() {
|
||||||
return this.toBuffer().toString('hex')
|
return this.toBuffer().toString('hex')
|
||||||
|
|
|
@ -25,25 +25,18 @@ function magicHash(message) {
|
||||||
// TODO: parameterize compression instead of using ECKey.compressed
|
// TODO: parameterize compression instead of using ECKey.compressed
|
||||||
function sign(key, message) {
|
function sign(key, message) {
|
||||||
var hash = magicHash(message)
|
var hash = magicHash(message)
|
||||||
var sig = key.sign(hash)
|
var sig = ecdsa.parseSig(key.sign(hash))
|
||||||
var obj = ecdsa.parseSig(sig)
|
var i = ecdsa.calcPubKeyRecoveryParam(key.pub.Q, sig.r, sig.s, hash)
|
||||||
var i = ecdsa.calcPubKeyRecoveryParam(key.pub.Q, obj.r, obj.s, hash)
|
|
||||||
|
|
||||||
i += 27
|
i += 27
|
||||||
if (key.pub.compressed) {
|
if (key.pub.compressed) {
|
||||||
i += 4
|
i += 4
|
||||||
}
|
}
|
||||||
|
|
||||||
var rBa = obj.r.toByteArrayUnsigned()
|
var rB = sig.r.toPaddedBuffer(32)
|
||||||
var sBa = obj.s.toByteArrayUnsigned()
|
var sB = sig.s.toPaddedBuffer(32)
|
||||||
|
|
||||||
// Pad to 32 bytes per value
|
return Buffer.concat([new Buffer([i]), rB, sB], 65)
|
||||||
while (rBa.length < 32) rBa.unshift(0);
|
|
||||||
while (sBa.length < 32) sBa.unshift(0);
|
|
||||||
|
|
||||||
sig = [i].concat(rBa, sBa)
|
|
||||||
|
|
||||||
return sig
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: stricter API?
|
// 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])
|
var sig_a = s1.sign([0])
|
||||||
|
|
||||||
assert.ok(sig_a, 'Sign null')
|
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 message = new Buffer(1024) // More or less random :P
|
||||||
var hash = crypto.sha256(message)
|
var hash = crypto.sha256(message)
|
||||||
|
|
2
test/fixtures/base58.js
vendored
2
test/fixtures/base58.js
vendored
|
@ -71,4 +71,4 @@ module.exports = {
|
||||||
"string": " \t\n\u000b\f\r skip \r\f\u000b\n\t a"
|
"string": " \t\n\u000b\f\r skip \r\f\u000b\n\t a"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
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