Ryan X. Charles
11 years ago
9 changed files with 255 additions and 48 deletions
@ -0,0 +1,92 @@ |
|||||
|
var bn = require('./bn'); |
||||
|
var point = require('./point'); |
||||
|
var Signature = require('./signature'); |
||||
|
var Privkey = require('./privkey'); |
||||
|
var Pubkey = require('./pubkey'); |
||||
|
var Random = require('./random'); |
||||
|
|
||||
|
var ECDSA = function(hash, key, sig, k) { |
||||
|
this.hash = hash; |
||||
|
this.key = key; |
||||
|
this.sig = sig; |
||||
|
this.k = k; |
||||
|
}; |
||||
|
|
||||
|
ECDSA.prototype.sigError = function() { |
||||
|
if (!Buffer.isBuffer(this.hash) || this.hash.length !== 32) |
||||
|
return 'Invalid hash'; |
||||
|
|
||||
|
try { |
||||
|
this.key.pubkey.validate(); |
||||
|
} catch (e) { |
||||
|
return 'Invalid pubkey: ' + e; |
||||
|
}; |
||||
|
|
||||
|
var r = this.sig.r; |
||||
|
var s = this.sig.s; |
||||
|
if (!(r.gt(0) && r.lt(point.getN())) |
||||
|
|| !(s.gt(0) && s.lt(point.getN()))) |
||||
|
return 'r and s not in range'; |
||||
|
|
||||
|
var e = bn.fromBuffer(this.hash); |
||||
|
var n = point.getN(); |
||||
|
var sinv = s.invm(n); |
||||
|
var u1 = sinv.mul(e).mod(n); |
||||
|
var u2 = sinv.mul(r).mod(n); |
||||
|
|
||||
|
var p = point.getG().mulAdd(u1, this.key.pubkey.p, u2); |
||||
|
if (p.isInfinity()) |
||||
|
return 'p is infinity'; |
||||
|
|
||||
|
if (!(p.getX().mod(n).cmp(r) === 0)) |
||||
|
return 'Invalid signature'; |
||||
|
else |
||||
|
return false; |
||||
|
}; |
||||
|
|
||||
|
ECDSA.prototype.randomK = function() { |
||||
|
var N = point.getN(); |
||||
|
var k; |
||||
|
do { |
||||
|
k = bn.fromBuffer(Random.getRandomBuffer(32)); |
||||
|
} while (!(k.lt(N) && k.gt(0))); |
||||
|
this.k = k; |
||||
|
return this; |
||||
|
}; |
||||
|
|
||||
|
ECDSA.prototype.sign = function() { |
||||
|
var hash = this.hash; |
||||
|
var privkey = this.key.privkey; |
||||
|
var k = this.k; |
||||
|
var d = privkey.n; |
||||
|
|
||||
|
if (!hash || !privkey || !k || !d) |
||||
|
throw new Error('ecdsa: invalid parameters'); |
||||
|
|
||||
|
var N = point.getN(); |
||||
|
var G = point.getG(); |
||||
|
var e = bn(hash); |
||||
|
|
||||
|
do { |
||||
|
var Q = G.mul(k); |
||||
|
var r = Q.x.mod(N); |
||||
|
var s = k.invm(N).mul(e.add(d.mul(r))).mod(N); |
||||
|
} while (r.cmp(0) <= 0 || s.cmp(0) <= 0); |
||||
|
|
||||
|
this.sig = new Signature(r, s); |
||||
|
return this.sig; |
||||
|
}; |
||||
|
|
||||
|
ECDSA.prototype.signRandomK = function() { |
||||
|
var k = this.randomK(); |
||||
|
return this.sign(); |
||||
|
}; |
||||
|
|
||||
|
ECDSA.prototype.verify = function() { |
||||
|
if (!this.sigError()) |
||||
|
return true; |
||||
|
else |
||||
|
return false; |
||||
|
}; |
||||
|
|
||||
|
module.exports = ECDSA; |
@ -0,0 +1,41 @@ |
|||||
|
var ECDSA = require('../lib/ecdsa'); |
||||
|
var Hash = require('../lib/hash'); |
||||
|
var Key = require('../lib/key'); |
||||
|
var Privkey = require('../lib/privkey'); |
||||
|
var Pubkey = require('../lib/pubkey'); |
||||
|
var bn = require('../lib/bn'); |
||||
|
var point = require('../lib/point'); |
||||
|
var should = require('chai').should(); |
||||
|
|
||||
|
describe("ecdsa", function() { |
||||
|
|
||||
|
it('should create a blank ecdsa', function() { |
||||
|
var ecdsa = new ECDSA(); |
||||
|
}); |
||||
|
|
||||
|
var ecdsa = new ECDSA(); |
||||
|
ecdsa.hash = Hash.sha256(new Buffer('test data')); |
||||
|
ecdsa.key = new Key(); |
||||
|
ecdsa.key.privkey = new Privkey(bn.fromBuffer(new Buffer('fee0a1f7afebf9d2a5a80c0c98a31c709681cce195cbcd06342b517970c0be1e', 'hex'))); |
||||
|
ecdsa.key.pubkey = new Pubkey(point(bn.fromBuffer(new Buffer('ac242d242d23be966085a2b2b893d989f824e06c9ad0395a8a52f055ba39abb2', 'hex')), |
||||
|
bn.fromBuffer(new Buffer('4836ab292c105a711ed10fcfd30999c31ff7c02456147747e03e739ad527c380', 'hex')))); |
||||
|
|
||||
|
describe('#signRandomK', function() { |
||||
|
|
||||
|
it('should produce a signature', function() { |
||||
|
ecdsa.signRandomK(); |
||||
|
should.exist(ecdsa.sig); |
||||
|
}); |
||||
|
|
||||
|
}); |
||||
|
|
||||
|
describe('#verify', function() { |
||||
|
|
||||
|
it('should verify a signature that was just signed', function() { |
||||
|
ecdsa.signRandomK(); |
||||
|
ecdsa.verify().should.equal(true); |
||||
|
}); |
||||
|
|
||||
|
}); |
||||
|
|
||||
|
}); |
Loading…
Reference in new issue