Permalink
Browse files

partially using the dss packing

  • Loading branch information...
1 parent f2f98eb commit 6b2d68c1f1e2b7d1b02dcd8d2578c01b2ab4c2e1 @substack committed Mar 1, 2011
Showing with 143 additions and 113 deletions.
  1. +36 −12 dss.js
  2. +86 −1 index.js
  3. +0 −86 key.js
  4. +4 −2 package.json
  5. +17 −12 test/keys.js
View
48 dss.js
@@ -1,10 +1,44 @@
+var assert = require('assert');
+
var bigint = require('bigint');
var put = require('put');
-var assert = require('assert');
+var Hash = require('hashish');
+var Buffers = require('buffers');
// Generate two primes p and q to the Digital Signature Standard (DSS)
// http://www.itl.nist.gov/fipspubs/fip186.htm appendix 2.2
+var exports = module.exports = DSS;
+
+function DSS (fields) {
+ if (!(this instanceof DSS)) return new DSS(fields);
+
+ this.fields = Hash.merge(fields, {
+ k : function (e) { return e.powm(ref.y, ref.p) },
+ f : fields.g.powm(fields.y, fields.p),
+ });
+}
+
+DSS.prototype.data = function (privPub) {
+ var p = (privPub || '').toUpperCase();
+
+ if (p === 'PRIVATE') {
+ return this.fields.x.toBuffer().toString('base64');
+ }
+ else if (p === 'PUBLIC') {
+ var fields = this.fields;
+ return Buffers(exports.fields.public.map(function (name) {
+ return fields[name].toBuffer('mpint')
+ })).slice();
+ }
+ else throw new Error('Specify "private" or "public"')
+};
+
+exports.fields = {
+ public : [ 'p', 'q', 'g', 'y' ],
+ private : [ 'x' ],
+};
+
exports.generate = function () {
var q = bigint(2).pow(159).add(1).rand(bigint(2).pow(160)).nextPrime();
var L = 512 + 64 * Math.floor(Math.random() * 8);
@@ -29,16 +63,6 @@ exports.generate = function () {
var x = q.sub(1).rand().add(1); // private key
var y = g.powm(x, p); // public key
- var f = g.powm(y, p);
- return {
- // p, q, and g can be shared and re-used
- p : p, q : q, g : g, y : y,
-
- session : function () {
- return {
- k : function (e) { return e.powm(y, p) },
- };
- },
- };
+ return module.exports({ p : p, q : q, g : g, y : y, x : x });
};
View
@@ -1 +1,86 @@
-exports.dss = require('./dss');
+var Buffers = require('buffers');
+
+module.exports = Key;
+
+function Key (keyData, format) {
+ if (!(this instanceof Key)) return new Key(keyData, format);
+ this.algorithm = format.split('-')[0];
+
+ if (typeof keyData === 'string') {
+ var encoding = format && format.split('-')[1] || 'base64';
+ this.data = new Buffer(keyData, encoding);
+ }
+ else if (Buffer.isBuffer(keyData)) {
+ this.data = keyData;
+ }
+ else {
+ throw new Error('keyData must be a string or Buffer');
+ }
+}
+
+Key.pack = function (algorithm, vars) {
+ var bufs = vars.map(function (bigi) { return bigi.toBuffer('mpint') });
+ var packed = Buffers(bufs).slice();
+ return new Key(packed, algorithm);
+};
+
+Key.parse = function (body) {
+ var ssh2 = body.match(/^-----BEGIN (\S+) (PRIVATE|PUBLIC) KEY-----\n/);
+ if (ssh2) {
+ return new Key(
+ body
+ .toString()
+ .split('\n')
+ .filter(function (line) {
+ return line.match(/^\S+\s*$/)
+ })
+ .join('')
+ .replace(/\s+/g,'')
+ , ssh2[1]
+ );
+ }
+
+ var openssh = body.match(/^ssh-(\S+)\s+(\S+)/);
+ if (openssh) {
+ return new Key(openssh[2], openssh[1]);
+ }
+
+ return undefined;
+};
+
+Key.prototype.toString = function (encoding) {
+ return this.data.toString(encoding || 'base64')
+};
+
+Key.prototype.format = function (format, aux) {
+ var fmt = (format || 'ssh2').toLowerCase();
+ if (fmt === 'ssh2') {
+ var p = (aux || '').toUpperCase();
+ if (p !== 'PRIVATE' && p !== 'PUBLIC') {
+ throw new Error('Must specify private or public for ssh2');
+ }
+
+ var algo = this.algorithm.toUpperCase();
+ if (algo === 'DSS') algo = 'DSA';
+
+ var wrapped = [];
+ var data = this.data.toString('base64');
+ for (var i = 0; i < data.length; i += 64) {
+ wrapped.push(data.slice(i, i + 64));
+ }
+
+ return [
+ [ '-----BEGIN', algo, p, 'KEY-----' ].join(' '),
+ wrapped.join('\n'),
+ [ '-----END', algo, p, 'KEY-----' ].join(' '),
+ ''
+ ].join('\n');
+ }
+ else if (fmt === 'openssh') {
+ var id = this.algorithm;
+ if (id === 'dsa') id = 'dss';
+ var data = this.data.toString('base64');
+ return [ 'ssh-' + id, data, aux || '' ].join(' ') + '\r\n';
+ }
+ else throw new Error('Unrecognized format ' + format.toString());
+};
View
86 key.js
@@ -1,86 +0,0 @@
-var Buffers = require('buffers');
-
-module.exports = Key;
-
-function Key (keyData, format) {
- if (!(this instanceof Key)) return new Key(keyData, format);
- this.algorithm = format.split('-')[0];
-
- if (typeof keyData === 'string') {
- var encoding = format && format.split('-')[1] || 'base64';
- this.data = new Buffer(keyData, encoding);
- }
- else if (Buffer.isBuffer(keyData)) {
- this.data = keyData;
- }
- else {
- throw new Error('keyData must be a string or Buffer');
- }
-}
-
-Key.pack = function (algorithm, vars) {
- var bufs = vars.map(function (bigi) { return bigi.toBuffer('mpint') });
- var packed = Buffers(bufs).slice();
- return new Key(packed, algorithm);
-};
-
-Key.parse = function (body) {
- var ssh2 = body.match(/^-----BEGIN (\S+) (PRIVATE|PUBLIC) KEY-----\n/);
- if (ssh2) {
- return new Key(
- body
- .toString()
- .split('\n')
- .filter(function (line) {
- return line.match(/^\S+\s*$/)
- })
- .join('')
- .replace(/\s+/g,'')
- , ssh2[1]
- );
- }
-
- var openssh = body.match(/^ssh-(\S+)\s+(\S+)/);
- if (openssh) {
- return new Key(openssh[2], openssh[1]);
- }
-
- return undefined;
-};
-
-Key.prototype.toString = function (encoding) {
- return this.data.toString(encoding || 'base64')
-};
-
-Key.prototype.format = function (format, aux) {
- var fmt = (format || 'ssh2').toLowerCase();
- if (fmt === 'ssh2') {
- var p = (aux || '').toUpperCase();
- if (p !== 'PRIVATE' && p !== 'PUBLIC') {
- throw new Error('Must specify private or public for ssh2');
- }
-
- var algo = this.algorithm.toUpperCase();
- if (algo === 'DSS') algo = 'DSA';
-
- var wrapped = [];
- var data = this.data.toString('base64');
- for (var i = 0; i < data.length; i += 64) {
- wrapped.push(data.slice(i, i + 64));
- }
-
- return [
- [ '-----BEGIN', algo, p, 'KEY-----' ].join(' '),
- wrapped.join('\n'),
- [ '-----END', algo, p, 'KEY-----' ].join(' '),
- ''
- ].join('\n');
- }
- else if (fmt === 'openssh') {
- var id = this.algorithm;
- if (id === 'dsa') id = 'dss';
- var data = this.data.toString('base64');
- return [ 'ssh-' + id, data, aux || '' ].join(' ') + '\r\n';
- }
- else throw new Error('Unrecognized format ' + format.toString());
-};
View
@@ -14,7 +14,8 @@
"dependencies" : {
"bigint" : ">=0.0.9",
"buffers" : ">=0.0.1",
- "put" : ">=0.0.3"
+ "put" : ">=0.0.3",
+ "hashish" : ">=0.0.2"
},
"devDependencies" : {
"expresso" : ">=0.6.0"
@@ -29,5 +30,6 @@
},
"engines" : {
"node" : ">=0.4.0"
- }
+ },
+ "license" : "MIT/X11"
}
View
@@ -1,4 +1,4 @@
-var Key = require('keyx/key');
+var keyx = require('keyx');
var dss = require('keyx/dss');
var assert = require('assert');
@@ -7,45 +7,50 @@ var Buffers = require('buffers');
exports.createKey = function () {
assert.eql(
- new Key('test', 'dss').data,
+ new keyx('test', 'dss').data,
new Buffer('test', 'base64')
);
assert.eql(
- new Key('test', 'dss-base64').data,
+ new keyx('test', 'dss-base64').data,
new Buffer('test', 'base64')
);
assert.eql(
- new Key('abcdef', 'dss-hex').data,
+ new keyx('abcdef', 'dss-hex').data,
new Buffer('abcdef', 'hex')
);
};
exports.packParseKey = function () {
- var pubkey = dss.generate();
- var vars = [ pubkey.p, pubkey.q, pubkey.g, pubkey.y ];
- var data = Buffers(vars.map(function (x) {
+ var keypair = dss.generate();
+ var pubkey = keypair.data('public');
+ var privkey = keypair.data('private');
+
+ var fields = keypair.fields;
+
+ var vars = [ fields.p, fields.q, fields.g, fields.y ];
+ var pubdata = Buffers(vars.map(function (x) {
return x.toBuffer('mpint')
})).slice();
- var key = Key.pack('dss', vars);
- assert.eql(key.data, data);
+ var key = keyx.pack('dss', vars);
+ assert.eql(key.data, pubdata);
- assert.eql(key.toString(), data.toString('base64'));
+ assert.eql(key.toString(), pubdata.toString('base64'));
assert.throws(function () {
key.format('ssh2');
});
var ssh2 = key.format('ssh2', 'private');
- var kssh2 = Key.parse(ssh2);
+ var kssh2 = keyx.parse(ssh2);
assert.eql(
key.data,
kssh2.data
);
var openssh = key.format('openssh', 'moo@moo.com');
- var kopenssh = Key.parse(openssh);
+ var kopenssh = keyx.parse(openssh);
assert.eql(key.data, kopenssh.data);
};

0 comments on commit 6b2d68c

Please sign in to comment.