| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 | 
							- 'use strict';
 
- // much of this based on https://github.com/indutny/self-signed/blob/gh-pages/lib/rsa.js
 
- var Buffer = require('safe-buffer').Buffer;
 
- var BN = require('bn.js');
 
- var EC = require('elliptic').ec;
 
- var parseKeys = require('parse-asn1');
 
- var curves = require('./curves.json');
 
- function verify(sig, hash, key, signType, tag) {
 
-   var pub = parseKeys(key);
 
-   if (pub.type === 'ec') {
 
-     // rsa keys can be interpreted as ecdsa ones in openssl
 
-     if (signType !== 'ecdsa' && signType !== 'ecdsa/rsa') { throw new Error('wrong public key type'); }
 
-     return ecVerify(sig, hash, pub);
 
-   } else if (pub.type === 'dsa') {
 
-     if (signType !== 'dsa') { throw new Error('wrong public key type'); }
 
-     return dsaVerify(sig, hash, pub);
 
-   }
 
-   if (signType !== 'rsa' && signType !== 'ecdsa/rsa') { throw new Error('wrong public key type'); }
 
-   hash = Buffer.concat([tag, hash]);
 
-   var len = pub.modulus.byteLength();
 
-   var pad = [1];
 
-   var padNum = 0;
 
-   while (hash.length + pad.length + 2 < len) {
 
-     pad.push(0xff);
 
-     padNum += 1;
 
-   }
 
-   pad.push(0x00);
 
-   var i = -1;
 
-   while (++i < hash.length) {
 
-     pad.push(hash[i]);
 
-   }
 
-   pad = Buffer.from(pad);
 
-   var red = BN.mont(pub.modulus);
 
-   sig = new BN(sig).toRed(red);
 
-   sig = sig.redPow(new BN(pub.publicExponent));
 
-   sig = Buffer.from(sig.fromRed().toArray());
 
-   var out = padNum < 8 ? 1 : 0;
 
-   len = Math.min(sig.length, pad.length);
 
-   if (sig.length !== pad.length) { out = 1; }
 
-   i = -1;
 
-   while (++i < len) { out |= sig[i] ^ pad[i]; }
 
-   return out === 0;
 
- }
 
- function ecVerify(sig, hash, pub) {
 
-   var curveId = curves[pub.data.algorithm.curve.join('.')];
 
-   if (!curveId) { throw new Error('unknown curve ' + pub.data.algorithm.curve.join('.')); }
 
-   var curve = new EC(curveId);
 
-   var pubkey = pub.data.subjectPrivateKey.data;
 
-   return curve.verify(hash, sig, pubkey);
 
- }
 
- function dsaVerify(sig, hash, pub) {
 
-   var p = pub.data.p;
 
-   var q = pub.data.q;
 
-   var g = pub.data.g;
 
-   var y = pub.data.pub_key;
 
-   var unpacked = parseKeys.signature.decode(sig, 'der');
 
-   var s = unpacked.s;
 
-   var r = unpacked.r;
 
-   checkValue(s, q);
 
-   checkValue(r, q);
 
-   var montp = BN.mont(p);
 
-   var w = s.invm(q);
 
-   var v = g.toRed(montp)
 
-     .redPow(new BN(hash).mul(w).mod(q))
 
-     .fromRed()
 
-     .mul(y.toRed(montp).redPow(r.mul(w).mod(q)).fromRed())
 
-     .mod(p)
 
-     .mod(q);
 
-   return v.cmp(r) === 0;
 
- }
 
- function checkValue(b, q) {
 
-   if (b.cmpn(0) <= 0) { throw new Error('invalid sig'); }
 
-   if (b.cmp(q) >= 0) { throw new Error('invalid sig'); }
 
- }
 
- module.exports = verify;
 
 
  |