@cdottori/ecdsa-node
Version:
fast openSSL-compatible implementation of the Elliptic Curve Digital Signature Algorithm (ECDSA)
96 lines (74 loc) • 2.97 kB
JavaScript
var der = require("./utils/der");
var BinaryAscii = require("./utils/binary");
var Point = require("./point").Point;
var EcdsaCurve = require("./curve");
class PublicKey {
constructor (point, curve) {
this.point = point;
this.curve = curve;
};
toString (encoded=false) {
let xString = BinaryAscii.stringFromNumber(this.point.x, this.curve.length());
let yString = BinaryAscii.stringFromNumber(this.point.y, this.curve.length());
if (encoded) {
return "\x00\x04" + xString + yString;
}
return xString + yString;
};
toDer () {
let encodeEcAndOid = der.encodeSequence(der.encodeOid([1, 2, 840, 10045, 2, 1]), der.encodeOid(this.curve.oid));
return der.encodeSequence(encodeEcAndOid, der.encodeBitstring(this.toString(true)))
};
toPem () {
return der.toPem(this.toDer(), "PUBLIC KEY")
};
static fromPem (string) {
return this.fromDer(der.fromPem(string));
};
static fromDer (string) {
let result = der.removeSequence(string);
let s1 = result[0];
let empty = result[1];
if (empty) {
throw new Error("trailing junk after DER public key: " + BinaryAscii.hexFromBinary(empty));
};
result = der.removeSequence(s1);
let s2 = result[0];
let pointStrBitstring = result[1];
result = der.removeObject(s2);
let rest = result[1];
result = der.removeObject(rest);
let oidCurve = result[0];
empty = result[1];
if (empty) {
throw new Error("trailing junk after DER public key objects: " + BinaryAscii.hexFromBinary(empty));
};
let curve = EcdsaCurve.curvesByOid[oidCurve];
if (!curve) {
let supportedCurvesNames = [];
EcdsaCurve.supportedCurves.forEach((x) => {supportedCurvesNames.push(x.name)})
throw new Error(
"Unknown curve with oid " + oidCurve
+ ". Only the following are available: " + supportedCurvesNames
);
};
result = der.removeBitString(pointStrBitstring);
let pointStr = result[0];
empty = result[1];
if (empty) {
throw new Error("trailing junk after public key point-string: " + BinaryAscii.hexFromBinary(empty));
};
return this.fromString(pointStr.slice(2), curve);
};
static fromString (string, curve=EcdsaCurve.secp256k1, validatePoint=true) {
let baseLen = curve.length();
let xs = string.slice(null, baseLen);
let ys = string.slice(baseLen);
let p = new Point(BinaryAscii.numberFromString(xs), BinaryAscii.numberFromString(ys));
if (validatePoint & !curve.contains(p)) {
throw new Error("point (" + p.x + "," + p.y + ") is not valid");
}
return new PublicKey(p, curve);
};
};
exports.PublicKey = PublicKey;