commit
4689abb513
15 changed files with 67 additions and 1405 deletions
|
@ -122,11 +122,6 @@ BitcoinJS (c) 2011-2012 Stefan Thomas
|
|||
Released under MIT license
|
||||
http://bitcoinjs.org/
|
||||
|
||||
JSBN (c) 2003-2005 Tom Wu
|
||||
Released under BSD license
|
||||
http://www-cs-students.stanford.edu/~tjw/jsbn/
|
||||
|
||||
CryptoJS (c) 2009–2012 by Jeff Mott
|
||||
Released under New BSD license
|
||||
http://code.google.com/p/crypto-js/
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
"compile": "./node_modules/.bin/browserify ./src/index.js -s Bitcoin | ./node_modules/.bin/uglifyjs > bitcoinjs-min.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"bigi": "0.2.0",
|
||||
"crypto-js": "3.1.2-3",
|
||||
"secure-random": "0.2.1"
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
// Merged Buffer refactorings from base58-native by Stephen Pair
|
||||
// Copyright (c) 2013 BitPay Inc
|
||||
|
||||
var BigInteger = require('./jsbn/jsbn')
|
||||
var BigInteger = require('./bigi')
|
||||
|
||||
var ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
|
||||
var ALPHABET_BUF = new Buffer(ALPHABET, 'ascii')
|
||||
|
@ -16,7 +16,7 @@ for(var i = 0; i < ALPHABET.length; i++) {
|
|||
var BASE = BigInteger.valueOf(58)
|
||||
|
||||
function encode(buffer) {
|
||||
var bi = BigInteger.fromByteArrayUnsigned(buffer)
|
||||
var bi = BigInteger.fromBuffer(buffer)
|
||||
var result = new Buffer(buffer.length << 1)
|
||||
|
||||
var i = result.length - 1
|
||||
|
|
13
src/bigi.js
Normal file
13
src/bigi.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
var assert = require('assert')
|
||||
var BigInteger = require('bigi')
|
||||
|
||||
BigInteger.fromBuffer = function(buffer) {
|
||||
// FIXME: Transitionary
|
||||
if (Buffer.isBuffer(buffer)) {
|
||||
buffer = Array.prototype.slice.call(buffer)
|
||||
}
|
||||
|
||||
return BigInteger.fromByteArrayUnsigned(buffer)
|
||||
}
|
||||
|
||||
module.exports = BigInteger
|
|
@ -2,13 +2,8 @@
|
|||
// Ported loosely from BouncyCastle's Java EC code
|
||||
// Only Fp curves implemented for now
|
||||
|
||||
var BigInteger = require('./jsbn'),
|
||||
sec = require('./sec');
|
||||
var BigInteger = require('./bigi')
|
||||
|
||||
// ----------------
|
||||
// ECFieldElementFp
|
||||
|
||||
// constructor
|
||||
function ECFieldElementFp(q,x) {
|
||||
this.x = x;
|
||||
// TODO if(x.compareTo(q) >= 0) error
|
||||
|
@ -343,12 +338,12 @@ ECPointFp.decodeFrom = function (curve, enc) {
|
|||
if (type == 4) {
|
||||
var xBa = enc.slice(1, 1 + dataLen/2),
|
||||
yBa = enc.slice(1 + dataLen/2, 1 + dataLen),
|
||||
x = BigInteger.fromByteArrayUnsigned(xBa),
|
||||
y = BigInteger.fromByteArrayUnsigned(yBa);
|
||||
x = BigInteger.fromBuffer(xBa),
|
||||
y = BigInteger.fromBuffer(yBa);
|
||||
}
|
||||
else {
|
||||
var xBa = enc.slice(1),
|
||||
x = BigInteger.fromByteArrayUnsigned(xBa),
|
||||
x = BigInteger.fromBuffer(xBa),
|
||||
p = curve.getQ(),
|
||||
xCubedPlus7 = x.multiply(x).multiply(x).add(new BigInteger('7')).mod(p),
|
||||
pPlus1Over4 = p.add(new BigInteger('1'))
|
31
src/ecdsa.js
31
src/ecdsa.js
|
@ -1,10 +1,12 @@
|
|||
var sec = require('./jsbn/sec')
|
||||
var rng = require('secure-random')
|
||||
var BigInteger = require('./jsbn/jsbn')
|
||||
var BigInteger = require('./bigi')
|
||||
var ECPointFp = require('./ec').ECPointFp
|
||||
|
||||
var convert = require('./convert')
|
||||
var HmacSHA256 = require('crypto-js/hmac-sha256')
|
||||
var ECPointFp = require('./jsbn/ec').ECPointFp
|
||||
|
||||
var sec = require('./sec')
|
||||
var ecparams = sec("secp256k1")
|
||||
|
||||
var P_OVER_FOUR = null
|
||||
|
||||
function implShamirsTrick(P, k, Q, l) {
|
||||
|
@ -48,19 +50,14 @@ function deterministicGenerateK(hash,key) {
|
|||
v = HmacSHA256(v,k)
|
||||
v = HmacSHA256(v,k)
|
||||
vArr = convert.wordArrayToBytes(v)
|
||||
return BigInteger.fromByteArrayUnsigned(vArr)
|
||||
return BigInteger.fromBuffer(vArr)
|
||||
}
|
||||
|
||||
var ecdsa = {
|
||||
getBigRandom: function (limit) {
|
||||
return new BigInteger(limit.bitLength(), rng).
|
||||
mod(limit.subtract(BigInteger.ONE)).
|
||||
add(BigInteger.ONE)
|
||||
},
|
||||
sign: function (hash, priv) {
|
||||
var d = priv
|
||||
var n = ecparams.getN()
|
||||
var e = BigInteger.fromByteArrayUnsigned(hash)
|
||||
var e = BigInteger.fromBuffer(hash)
|
||||
|
||||
var k = deterministicGenerateK(hash,priv.toByteArrayUnsigned())
|
||||
var G = ecparams.getG()
|
||||
|
@ -98,7 +95,7 @@ var ecdsa = {
|
|||
} else {
|
||||
throw new Error("Invalid format for pubkey value, must be byte array or ECPointFp")
|
||||
}
|
||||
var e = BigInteger.fromByteArrayUnsigned(hash)
|
||||
var e = BigInteger.fromBuffer(hash)
|
||||
|
||||
return ecdsa.verifyRaw(e, r, s, Q)
|
||||
},
|
||||
|
@ -188,8 +185,8 @@ var ecdsa = {
|
|||
//if (cursor != sig.length)
|
||||
// throw new Error("Extra bytes in signature")
|
||||
|
||||
var r = BigInteger.fromByteArrayUnsigned(rBa)
|
||||
var s = BigInteger.fromByteArrayUnsigned(sBa)
|
||||
var r = BigInteger.fromBuffer(rBa)
|
||||
var s = BigInteger.fromBuffer(sBa)
|
||||
|
||||
return {r: r, s: s}
|
||||
},
|
||||
|
@ -207,8 +204,8 @@ var ecdsa = {
|
|||
}
|
||||
|
||||
var n = ecparams.getN()
|
||||
var r = BigInteger.fromByteArrayUnsigned(sig.slice(1, 33)).mod(n)
|
||||
var s = BigInteger.fromByteArrayUnsigned(sig.slice(33, 65)).mod(n)
|
||||
var r = BigInteger.fromBuffer(sig.slice(1, 33)).mod(n)
|
||||
var s = BigInteger.fromBuffer(sig.slice(33, 65)).mod(n)
|
||||
|
||||
return {r: r, s: s, i: i}
|
||||
},
|
||||
|
@ -262,7 +259,7 @@ var ecdsa = {
|
|||
R.validate()
|
||||
|
||||
// 1.5 Compute e from M
|
||||
var e = BigInteger.fromByteArrayUnsigned(hash)
|
||||
var e = BigInteger.fromBuffer(hash)
|
||||
var eNeg = BigInteger.ZERO.subtract(e).mod(n)
|
||||
|
||||
// 1.6 Compute Q = r^-1 (sR - eG)
|
||||
|
|
10
src/eckey.js
10
src/eckey.js
|
@ -7,11 +7,11 @@ var secureRandom = require('secure-random')
|
|||
var Address = require('./address')
|
||||
var crypto = require('./crypto')
|
||||
|
||||
var sec = require('./jsbn/sec')
|
||||
var sec = require('./sec')
|
||||
var ecparams = sec('secp256k1')
|
||||
|
||||
var BigInteger = require('./jsbn/jsbn')
|
||||
var ECPointFp = require('./jsbn/ec').ECPointFp
|
||||
var BigInteger = require('./bigi')
|
||||
var ECPointFp = require('./ec').ECPointFp
|
||||
|
||||
function ECKey(D, compressed) {
|
||||
assert(D.compareTo(BigInteger.ZERO) > 0, 'Private key must be greater than 0')
|
||||
|
@ -28,7 +28,7 @@ ECKey.fromBuffer = function(buffer, compressed) {
|
|||
assert(Buffer.isBuffer(buffer), 'First argument must be a Buffer')
|
||||
assert.strictEqual(buffer.length, 32, 'Invalid buffer length')
|
||||
|
||||
var D = BigInteger.fromByteArrayUnsigned(buffer)
|
||||
var D = BigInteger.fromBuffer(buffer)
|
||||
return new ECKey(D, compressed)
|
||||
}
|
||||
ECKey.fromHex = function(hex, compressed) {
|
||||
|
@ -52,7 +52,7 @@ ECKey.makeRandom = function(compressed, rng) {
|
|||
rng = rng || secureRandom
|
||||
|
||||
var buffer = new Buffer(rng(32))
|
||||
var D = BigInteger.fromByteArrayUnsigned(buffer)
|
||||
var D = BigInteger.fromBuffer(buffer)
|
||||
D = D.mod(ecparams.getN())
|
||||
|
||||
return new ECKey(D, compressed)
|
||||
|
|
|
@ -3,14 +3,14 @@ var base58 = require('./base58')
|
|||
var convert = require('./convert')
|
||||
|
||||
var Address = require('./address')
|
||||
var BigInteger = require('./jsbn/jsbn')
|
||||
var BigInteger = require('./bigi')
|
||||
var CJS = require('crypto-js')
|
||||
var crypto = require('./crypto')
|
||||
var ECKey = require('./eckey').ECKey
|
||||
var ECPubKey = require('./eckey').ECPubKey
|
||||
var Network = require('./network')
|
||||
|
||||
var sec = require('./jsbn/sec')
|
||||
var sec = require('./sec')
|
||||
var ecparams = sec("secp256k1")
|
||||
|
||||
function HmacSHA512(buffer, secret) {
|
||||
|
@ -215,7 +215,7 @@ HDWallet.prototype.derive = function(i) {
|
|||
var hd = new HDWallet()
|
||||
hd.network = this.network
|
||||
|
||||
var IL = BigInteger.fromByteArrayUnsigned(ILb)
|
||||
var IL = BigInteger.fromBuffer(ILb)
|
||||
|
||||
if (this.priv) {
|
||||
// ki = IL + kpar (mod n).
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
var ec = require('./ec')
|
||||
var Key = require('./eckey')
|
||||
var T = require('./transaction')
|
||||
|
||||
|
@ -5,17 +6,19 @@ module.exports = {
|
|||
Address: require('./address'),
|
||||
base58: require('./base58'),
|
||||
base58check: require('./base58check'),
|
||||
BigInteger: require('./jsbn/jsbn'),
|
||||
BigInteger: require('./bigi'),
|
||||
convert: require('./convert'),
|
||||
crypto: require('./crypto'),
|
||||
ec: ec,
|
||||
ecdsa: require('./ecdsa'),
|
||||
ECKey: Key.ECKey,
|
||||
ECPointFp: require('./jsbn/ec').ECPointFp,
|
||||
ECPointFp: ec.ECPointFp,
|
||||
ECPubKey: Key.ECPubKey,
|
||||
Message: require('./message'),
|
||||
Opcode: require('./opcode'),
|
||||
HDWallet: require('./hdwallet'),
|
||||
Script: require('./script'),
|
||||
sec: require('./sec'),
|
||||
Transaction: T.Transaction,
|
||||
TransactionIn: T.TransactionIn,
|
||||
TransactionOut: T.TransactionOut,
|
||||
|
|
1302
src/jsbn/jsbn.js
1302
src/jsbn/jsbn.js
File diff suppressed because it is too large
Load diff
|
@ -1,8 +1,8 @@
|
|||
// Named EC curves
|
||||
|
||||
var BigInteger = require('./bigi')
|
||||
var ECCurveFp = require('./ec')
|
||||
var ECPointFp = require('./ec').ECPointFp
|
||||
var BigInteger = require('./jsbn')
|
||||
var ECPointFp = ECCurveFp.ECPointFp
|
||||
|
||||
// ----------------
|
||||
// X9ECParameters
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
var assert = require('assert')
|
||||
var Address = require('./address')
|
||||
var BigInteger = require('./jsbn/jsbn')
|
||||
var BigInteger = require('./bigi')
|
||||
var Script = require('./script')
|
||||
var convert = require('./convert')
|
||||
var crypto = require('./crypto')
|
||||
|
|
32
test/ec.js
32
test/ec.js
|
@ -1,21 +1,20 @@
|
|||
var assert = require('assert')
|
||||
var ecdsa = require('../').ecdsa
|
||||
|
||||
var sec = require('../src/jsbn/sec')
|
||||
var sec = require('../').sec
|
||||
var ecparams = sec('secp256k1')
|
||||
|
||||
var BigInteger = require('..').BigInteger
|
||||
var ECPointFp = require('../').ECPointFp
|
||||
var ECKey = require('../').ECKey
|
||||
|
||||
describe('ec', function() {
|
||||
describe('ECPointFp', function() {
|
||||
it('behaviours correctly', function() {
|
||||
it('behaves correctly', function() {
|
||||
var G = ecparams.getG()
|
||||
var n = ecparams.getN()
|
||||
|
||||
assert.ok(G.multiply(n).isInfinity(), "Gn is infinite")
|
||||
|
||||
var k = ecdsa.getBigRandom(n)
|
||||
var k = BigInteger.ONE
|
||||
var P = G.multiply(k)
|
||||
assert.ok(!P.isInfinity(), "kG is not infinite")
|
||||
assert.ok(P.isOnCurve(), "kG on curve")
|
||||
|
@ -26,19 +25,18 @@ describe('ec', function() {
|
|||
})
|
||||
|
||||
describe('decodeFrom', function() {
|
||||
it('decodes valid ECPoints', function() {
|
||||
var p1 = ECKey.makeRandom(false).pub.toBuffer()
|
||||
assert.equal(p1.length, 65)
|
||||
it('decodes compressed ECPoints', function() {
|
||||
var s = new Buffer('02789ece95adf35fb3de994b8b16c90166736d70913a18378fff79503e8c5db7fb', 'hex')
|
||||
var Q = ECPointFp.decodeFrom(ecparams.getCurve(), s)
|
||||
assert.ok(Q)
|
||||
assert.ok(Q.validate())
|
||||
})
|
||||
|
||||
var p1_q = ECPointFp.decodeFrom(ecparams.getCurve(), p1)
|
||||
assert.ok(p1_q)
|
||||
assert.ok(p1_q.validate())
|
||||
|
||||
var p2 = new Buffer('0486f356006a38b847bedec1bf47013776925d939d5a35a97a4d1263e550c7f1ab5aba44ab74d22892097a0e851addf07ba97e33416df5affaceeb35d5607cd23c', 'hex')
|
||||
|
||||
var p2_q = ECPointFp.decodeFrom(ecparams.getCurve(), p2)
|
||||
assert.ok(p2_q)
|
||||
assert.ok(p2_q.validate())
|
||||
it('decodes uncompressed ECPoints', function() {
|
||||
var s = new Buffer('0486f356006a38b847bedec1bf47013776925d939d5a35a97a4d1263e550c7f1ab5aba44ab74d22892097a0e851addf07ba97e33416df5affaceeb35d5607cd23c', 'hex')
|
||||
var Q = ECPointFp.decodeFrom(ecparams.getCurve(), s)
|
||||
assert.ok(Q)
|
||||
assert.ok(Q.validate())
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
var assert = require('assert')
|
||||
var crypto = require('../').crypto
|
||||
var ecdsa = require('..').ecdsa
|
||||
var sec = require('../src/jsbn/sec.js')
|
||||
var BigInteger = require('../src/jsbn/jsbn.js')
|
||||
var sec = require('..').sec
|
||||
var ecparams = sec("secp256k1")
|
||||
var rng = require('secure-random')
|
||||
|
||||
var BigInteger = require('..').BigInteger
|
||||
var ECKey = require('..').ECKey
|
||||
|
@ -19,7 +17,7 @@ describe('ecdsa', function() {
|
|||
var obj = ecdsa.parseSigCompact(signature)
|
||||
var pubKey = new ECPubKey(ecdsa.recoverPubKey(obj.r, obj.s, Message.magicHash('1111'), obj.i))
|
||||
|
||||
assert.equal(pubKey.toHex(true), '02e8fcf4d749b35879bc1f3b14b49e67ab7301da3558c5a9b74a54f1e6339c334c')
|
||||
assert.equal(pubKey.toHex(), '02e8fcf4d749b35879bc1f3b14b49e67ab7301da3558c5a9b74a54f1e6339c334c')
|
||||
})
|
||||
})
|
||||
|
||||
|
|
36
test/jsbn.js
36
test/jsbn.js
|
@ -1,36 +0,0 @@
|
|||
var assert = require('assert')
|
||||
var BigInteger = require('../src/jsbn/jsbn.js')
|
||||
var bytesToHex = require('../src/convert.js').bytesToHex
|
||||
var secureRandom = require('secure-random')
|
||||
|
||||
describe('BigInteger', function() {
|
||||
describe('toByteArraySigned', function() {
|
||||
it('handles examples', function() {
|
||||
function hex(num) {
|
||||
var bytes = BigInteger.valueOf(num).toByteArraySigned()
|
||||
var h = bytesToHex(bytes)
|
||||
return '0x' + h
|
||||
}
|
||||
|
||||
assert.equal(hex( 0), '0x')
|
||||
assert.equal(hex( 1), '0x01')
|
||||
assert.equal(hex(-1), '0x81')
|
||||
assert.equal(hex( 127), '0x7f')
|
||||
assert.equal(hex(-127), '0xff')
|
||||
assert.equal(hex( 255), '0x00ff')
|
||||
assert.equal(hex(-255), '0x80ff')
|
||||
assert.equal(hex( 16300), '0x3fac')
|
||||
assert.equal(hex(-16300), '0xbfac')
|
||||
assert.equal(hex( 62300), '0x00f35c')
|
||||
assert.equal(hex(-62300), '0x80f35c')
|
||||
})
|
||||
})
|
||||
|
||||
describe('with RNG passed into constructor as the 2nd argument', function(){
|
||||
it('returns a BigInteger with the limit of the specified length', function(){
|
||||
var bitLength = 256
|
||||
var i = new BigInteger(bitLength, secureRandom)
|
||||
assert(i.bitLength() <= 256)
|
||||
})
|
||||
})
|
||||
})
|
Loading…
Reference in a new issue