Skip to content

Commit b6ff175

Browse files
committed
key: explicit methods for priv/pub/object
fix #21
1 parent 17dc013 commit b6ff175

File tree

6 files changed

+88
-64
lines changed

6 files changed

+88
-64
lines changed

lib/elliptic/curve/edwards.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ function EdwardsCurve(conf) {
1313
this.mOneA = this.twisted && conf.a == -1;
1414
this.extended = this.mOneA;
1515

16-
Base.call(this, 'mont', conf);
16+
Base.call(this, 'edwards', conf);
1717

1818
this.a = new bn(conf.a, 16).mod(this.red.m).toRed(this.red);
1919
this.c = new bn(conf.c, 16).toRed(this.red);

lib/elliptic/curve/mont.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ MontCurve.prototype.point = function point(x, z) {
2525

2626
MontCurve.prototype.pointFromJSON = function pointFromJSON(obj) {
2727
return Point.fromJSON(this, obj);
28-
}
28+
};
2929

3030
MontCurve.prototype.validate = function validate(point) {
3131
var x = point.normalize().x;

lib/elliptic/ec/index.js

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,16 @@ function EC(options) {
3535
}
3636
module.exports = EC;
3737

38-
EC.prototype.keyPair = function keyPair(priv, pub) {
39-
return new KeyPair(this, priv, pub);
38+
EC.prototype.keyPair = function keyPair(options) {
39+
return new KeyPair(this, options);
40+
};
41+
42+
EC.prototype.keyFromPrivate = function keyFromPrivate(priv, enc) {
43+
return KeyPair.fromPrivate(this, priv, enc);
44+
};
45+
46+
EC.prototype.keyFromPublic = function keyFromPublic(pub, enc) {
47+
return KeyPair.fromPublic(this, pub, enc);
4048
};
4149

4250
EC.prototype.genKeyPair = function genKeyPair(options) {
@@ -59,7 +67,7 @@ EC.prototype.genKeyPair = function genKeyPair(options) {
5967
continue;
6068

6169
priv.iaddn(1);
62-
return this.keyPair(priv);
70+
return this.keyFromPrivate(priv);
6371
} while (true);
6472
};
6573

@@ -73,12 +81,17 @@ EC.prototype._truncateToN = function truncateToN(msg, truncOnly) {
7381
return msg;
7482
};
7583

76-
EC.prototype.sign = function sign(msg, key, options) {
77-
key = this.keyPair(key, 'hex');
78-
msg = this._truncateToN(new bn(msg, 16));
84+
EC.prototype.sign = function sign(msg, key, enc, options) {
85+
if (typeof enc === 'object') {
86+
options = enc;
87+
enc = null;
88+
}
7989
if (!options)
8090
options = {};
8191

92+
key = this.keyFromPrivate(key, enc);
93+
msg = this._truncateToN(new bn(msg, 16));
94+
8295
// Zero-extend key to provide enough entropy
8396
var bytes = this.n.byteLength();
8497
var bkey = key.getPrivate().toArray();
@@ -125,9 +138,9 @@ EC.prototype.sign = function sign(msg, key, options) {
125138
} while (true);
126139
};
127140

128-
EC.prototype.verify = function verify(msg, signature, key) {
141+
EC.prototype.verify = function verify(msg, signature, key, enc) {
129142
msg = this._truncateToN(new bn(msg, 16));
130-
key = this.keyPair(key, 'hex');
143+
key = this.keyFromPublic(key, enc);
131144
signature = new Signature(signature, 'hex');
132145

133146
// Perform primitive values validation

lib/elliptic/ec/key.js

Lines changed: 53 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -4,47 +4,39 @@ var elliptic = require('../../elliptic');
44
var utils = elliptic.utils;
55
var assert = utils.assert;
66

7-
function KeyPair(ec, priv, pub) {
8-
if (priv instanceof KeyPair)
9-
return priv;
10-
if (pub instanceof KeyPair)
11-
return pub;
12-
13-
if (!priv) {
14-
priv = pub;
15-
pub = null;
16-
}
17-
if (priv !== null && typeof priv === 'object') {
18-
if (priv.x) {
19-
// KeyPair(public)
20-
pub = priv;
21-
priv = null;
22-
} else if (priv.priv || priv.pub) {
23-
// KeyPair({ priv: ..., pub: ... })
24-
pub = priv.pub;
25-
priv = priv.priv;
26-
}
27-
}
28-
7+
function KeyPair(ec, options) {
298
this.ec = ec;
309
this.priv = null;
3110
this.pub = null;
3211

33-
// KeyPair(public, 'hex')
34-
if (this._importPublicHex(priv, pub))
35-
return;
36-
37-
if (pub === 'hex')
38-
pub = null;
39-
40-
// KeyPair(priv, pub)
41-
if (priv)
42-
this._importPrivate(priv);
43-
if (pub)
44-
this._importPublic(pub);
12+
// KeyPair(ec, { priv: ..., pub: ... })
13+
if (options.priv)
14+
this._importPrivate(options.priv, options.privEnc);
15+
if (options.pub)
16+
this._importPublic(options.pub, options.pubEnc);
4517
}
4618
module.exports = KeyPair;
4719

20+
KeyPair.fromPublic = function fromPublic(ec, pub, enc) {
21+
if (pub instanceof KeyPair)
22+
return pub;
23+
24+
return new KeyPair(ec, {
25+
pub: pub,
26+
pubEnc: enc
27+
});
28+
};
29+
30+
KeyPair.fromPrivate = function fromPrivate(ec, priv, enc) {
31+
if (priv instanceof KeyPair)
32+
return priv;
33+
34+
return new KeyPair(ec, {
35+
priv: priv,
36+
privEnc: enc
37+
});
38+
};
39+
4840
KeyPair.prototype.validate = function validate() {
4941
var pub = this.getPublic();
5042

@@ -77,14 +69,19 @@ KeyPair.prototype.getPublic = function getPublic(compact, enc) {
7769
for (var i = x.length; i < len; i++)
7870
x.unshift(0);
7971

80-
if (compact) {
81-
var res = [ this.pub.getY().isEven() ? 0x02 : 0x03 ].concat(x);
72+
if (this.ec.curve.type !== 'mont') {
73+
if (compact) {
74+
var res = [ this.pub.getY().isEven() ? 0x02 : 0x03 ].concat(x);
75+
} else {
76+
var y = this.pub.getY().toArray();
77+
for (var i = y.length; i < len; i++)
78+
y.unshift(0);
79+
var res = [ 0x04 ].concat(x, y);
80+
}
8281
} else {
83-
var y = this.pub.getY().toArray();
84-
for (var i = y.length; i < len; i++)
85-
y.unshift(0);
86-
var res = [ 0x04 ].concat(x, y);
82+
res = x;
8783
}
84+
8885
return utils.encode(res, enc);
8986
};
9087

@@ -95,20 +92,28 @@ KeyPair.prototype.getPrivate = function getPrivate(enc) {
9592
return this.priv;
9693
};
9794

98-
KeyPair.prototype._importPrivate = function _importPrivate(key) {
95+
KeyPair.prototype._importPrivate = function _importPrivate(key, enc) {
9996
this.priv = new bn(key, 16);
10097

10198
// Ensure that the priv won't be bigger than n, otherwise we may fail
10299
// in fixed multiplication method
103100
this.priv = this.priv.mod(this.ec.curve.n);
104101
};
105102

106-
KeyPair.prototype._importPublic = function _importPublic(key) {
107-
this.pub = this.ec.curve.point(key.x, key.y);
108-
};
103+
KeyPair.prototype._importPublic = function _importPublic(key, enc) {
104+
if (key.x || key.y) {
105+
this.pub = this.ec.curve.point(key.x, key.y);
106+
return;
107+
}
109108

110-
KeyPair.prototype._importPublicHex = function _importPublic(key, enc) {
111109
key = utils.toArray(key, enc);
110+
if (this.ec.curve.type !== 'mont')
111+
return this._importPublicShort(key);
112+
else
113+
return this._importPublicMont(key);
114+
};
115+
116+
KeyPair.prototype._importPublicShort = function _importPublicShort(key) {
112117
var len = this.ec.curve.p.byteLength();
113118
if (key[0] === 0x04 && key.length - 1 === 2 * len) {
114119
this.pub = this.ec.curve.point(
@@ -117,11 +122,11 @@ KeyPair.prototype._importPublicHex = function _importPublic(key, enc) {
117122
} else if ((key[0] === 0x02 || key[0] === 0x03) && key.length - 1 === len) {
118123
this.pub = this.ec.curve.pointFromX(key[0] === 0x03,
119124
key.slice(1, 1 +len));
120-
} else {
121-
return false;
122125
}
126+
};
123127

124-
return true;
128+
KeyPair.prototype._importPublicMont = function _importPublicMont(key) {
129+
this.pub = this.ec.curve.point(key, 1);
125130
};
126131

127132
// ECDH

test/ecdh-test.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ describe('ECDH', function() {
1212
var sh2 = s2.derive(s1.getPublic());
1313

1414
assert.equal(sh1.toString(16), sh2.toString(16));
15+
16+
var sh1 = s1.derive(ecdh.keyFromPublic(s2.getPublic('hex'), 'hex')
17+
.getPublic());
18+
var sh2 = s2.derive(ecdh.keyFromPublic(s1.getPublic('hex'), 'hex')
19+
.getPublic());
20+
assert.equal(sh1.toString(16), sh2.toString(16));
1521
});
1622
}
1723

test/ecdsa-test.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,15 @@ describe('ECDSA', function() {
3434
assert(keys.verify(msg, signature), 'On-key verify');
3535

3636
// Load private key from hex
37-
var keys = ecdsa.keyPair(keys.getPrivate('hex'), 'hex');
37+
var keys = ecdsa.keyFromPrivate(keys.getPrivate('hex'), 'hex');
3838
var signature = ecdsa.sign(msg, keys);
3939
assert(ecdsa.verify(msg, signature, keys), 'hex-private verify');
4040

4141
// Load public key from compact hex
42-
var keys = ecdsa.keyPair(keys.getPublic(true, 'hex'), 'hex');
42+
var keys = ecdsa.keyFromPublic(keys.getPublic(true, 'hex'), 'hex');
4343

4444
// Load public key from hex
45-
var keys = ecdsa.keyPair(keys.getPublic('hex'), 'hex');
45+
var keys = ecdsa.keyFromPublic(keys.getPublic('hex'), 'hex');
4646

4747
// DER encoding
4848
var dsign = signature.toDER('hex');
@@ -55,8 +55,8 @@ describe('ECDSA', function() {
5555
assert(!ecdsa.verify(msg, signature, keys), 'Wrong key verify');
5656

5757
// Invalid private key
58-
var keys = ecdsa.keyPair(keys.getPrivate('hex') + keys.getPrivate('hex'),
59-
'hex');
58+
var keys = ecdsa.keyFromPrivate(keys.getPrivate('hex') +
59+
keys.getPrivate('hex'));
6060
assert(!ecdsa.verify(msg, signature, keys), 'Wrong key verify');
6161
});
6262
}
@@ -77,7 +77,7 @@ describe('ECDSA', function() {
7777
var sign = ecdsa.sign(dgst, opt.key);
7878
assert.equal(sign.r.toString(16), c.r);
7979
assert.equal(sign.s.toString(16), c.s);
80-
assert.ok(ecdsa.keyPair(opt.pub).validate().result,
80+
assert.ok(ecdsa.keyFromPublic(opt.pub).validate().result,
8181
'Invalid public key');
8282
assert.ok(ecdsa.verify(dgst, sign, opt.pub),
8383
'Invalid signature');

0 commit comments

Comments
 (0)