Everything in test/crypto/elliptic.js passes; working on test/general/ecc.js
This commit is contained in:
parent
11a2d0070b
commit
12eb037ba7
|
@ -84,7 +84,8 @@ const curves = {
|
||||||
hashName: 'SHA-256',
|
hashName: 'SHA-256',
|
||||||
hash: enums.hash.sha256,
|
hash: enums.hash.sha256,
|
||||||
cipher: enums.symmetric.aes128,
|
cipher: enums.symmetric.aes128,
|
||||||
node: nodeCurves.includes('secp256k1'),
|
node: false, // FIXME nodeCurves.includes('secp256k1'),
|
||||||
|
// this is because jwk-to-pem does not support this curve.
|
||||||
web: false
|
web: false
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -110,12 +111,12 @@ Curve.prototype.keyFromPublic = function (pub) {
|
||||||
return new KeyPair(this.curve, {pub: pub});
|
return new KeyPair(this.curve, {pub: pub});
|
||||||
};
|
};
|
||||||
|
|
||||||
Curve.prototype.genKeyPair = function () {
|
Curve.prototype.genKeyPair = async function () {
|
||||||
var keyPair;
|
var keyPair;
|
||||||
if (webCrypto && config.use_native && this.web) {
|
if (webCrypto && config.use_native && this.web) {
|
||||||
keyPair = webGenKeyPair(this.namedCurve);
|
keyPair = await webGenKeyPair(this.namedCurve);
|
||||||
} else if (nodeCrypto && config.use_native && this.node) {
|
} else if (nodeCrypto && config.use_native && this.node) {
|
||||||
keyPair = nodeGenKeyPair(this.opensslCurve);
|
keyPair = await nodeGenKeyPair(this.opensslCurve);
|
||||||
} else {
|
} else {
|
||||||
var r = this.curve.genKeyPair();
|
var r = this.curve.genKeyPair();
|
||||||
keyPair = {
|
keyPair = {
|
||||||
|
@ -136,18 +137,16 @@ function get(oid_or_name) {
|
||||||
throw new Error('Not valid curve');
|
throw new Error('Not valid curve');
|
||||||
}
|
}
|
||||||
|
|
||||||
function generate(curve) {
|
async function generate(curve) {
|
||||||
return new Promise(function (resolve) {
|
|
||||||
curve = get(curve);
|
curve = get(curve);
|
||||||
var keyPair = curve.genKeyPair();
|
var keyPair = await curve.genKeyPair();
|
||||||
resolve({
|
return {
|
||||||
oid: curve.oid,
|
oid: curve.oid,
|
||||||
Q: new BigInteger(keyPair.getPublic()),
|
Q: new BigInteger(keyPair.getPublic()),
|
||||||
d: new BigInteger(keyPair.getPrivate()),
|
d: new BigInteger(keyPair.getPrivate()),
|
||||||
hash: curve.hash,
|
hash: curve.hash,
|
||||||
cipher: curve.cipher
|
cipher: curve.cipher
|
||||||
});
|
};
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
@ -164,35 +163,40 @@ module.exports = {
|
||||||
//////////////////////////
|
//////////////////////////
|
||||||
|
|
||||||
|
|
||||||
function webGenKeyPair(namedCurve) {
|
async function webGenKeyPair(namedCurve) {
|
||||||
return webCrypto.generateKey(
|
try {
|
||||||
|
var keyPair = await webCrypto.generateKey(
|
||||||
{
|
{
|
||||||
name: "ECDSA",
|
name: "ECDSA", // FIXME or "ECDH"
|
||||||
// FIXME
|
// "P-256", "P-384", or "P-521"
|
||||||
// name: "ECDH",
|
namedCurve: namedCurve
|
||||||
namedCurve: namedCurve // "P-256", "P-384", or "P-521"
|
|
||||||
},
|
},
|
||||||
// FIXME
|
// TODO whether the key is extractable (i.e. can be used in exportKey)
|
||||||
false, // whether the key is extractable (i.e. can be used in exportKey)
|
false,
|
||||||
["sign", "verify"] // can be any combination of "sign" and "verify"
|
// FIXME this can be any combination of "sign" and "verify"
|
||||||
// FIXME
|
// or "deriveKey" and "deriveBits" for ECDH
|
||||||
// ["deriveKey", "deriveBits"] // can be any combination of "deriveKey" and "deriveBits"
|
["sign", "verify"]
|
||||||
).then(function(key){
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
pub: key.publicKey.encode(), // FIXME encoding
|
pub: keyPair.publicKey.encode(), // FIXME encoding
|
||||||
priv: key.privateKey.toArray() // FIXME encoding
|
priv: keyPair.privateKey.toArray() // FIXME encoding
|
||||||
};
|
};
|
||||||
}).catch(function(err){
|
} catch(err) {
|
||||||
throw new Error(err);
|
throw new Error(err);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function nodeGenKeyPair(opensslCurve) {
|
async function nodeGenKeyPair(opensslCurve) {
|
||||||
// TODO turn this into a promise
|
try {
|
||||||
var ecc = nodeCrypto.createECDH(opensslCurve);
|
var ecdh = nodeCrypto.createECDH(opensslCurve);
|
||||||
ecc.generateKeys();
|
await ecdh.generateKeys();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
pub: ecc.getPrivateKey().toJSON().data,
|
pub: ecdh.getPublicKey().toJSON().data,
|
||||||
priv: ecc.getPublicKey().toJSON().data
|
priv: ecdh.getPrivateKey().toJSON().data
|
||||||
};
|
};
|
||||||
|
} catch(err) {
|
||||||
|
throw new Error(err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,20 +25,21 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import asn1 from 'asn1.js';
|
import BN from 'bn.js';
|
||||||
import jwk2pem from 'jwk-to-pem';
|
import ASN1 from 'asn1.js';
|
||||||
|
import jwkToPem from 'jwk-to-pem';
|
||||||
|
|
||||||
import curves from './curves.js';
|
import curves from './curves.js';
|
||||||
import BigInteger from '../jsbn.js';
|
import BigInteger from '../jsbn.js';
|
||||||
import config from '../../../config';
|
import config from '../../../config';
|
||||||
import enums from '../../../enums.js';
|
import enums from '../../../enums.js';
|
||||||
import util from '../../../util.js';
|
import util from '../../../util.js'
|
||||||
|
|
||||||
const webCrypto = util.getWebCrypto();
|
const webCrypto = util.getWebCrypto();
|
||||||
const nodeCrypto = util.getNodeCrypto();
|
const nodeCrypto = util.getNodeCrypto();
|
||||||
|
|
||||||
var ECDSASignature = asn1.define('ecdsa-sig', function() {
|
var ECDSASignature = ASN1.define('ecdsa-sig', function() {
|
||||||
return this.seq().obj(
|
this.seq().obj(
|
||||||
this.key('r').int(), // FIXME int or BN?
|
this.key('r').int(), // FIXME int or BN?
|
||||||
this.key('s').int() // FIXME int or BN?
|
this.key('s').int() // FIXME int or BN?
|
||||||
);
|
);
|
||||||
|
@ -52,16 +53,16 @@ var ECDSASignature = asn1.define('ecdsa-sig', function() {
|
||||||
* @param {BigInteger} d Private key used to sign
|
* @param {BigInteger} d Private key used to sign
|
||||||
* @return {{r: BigInteger, s: BigInteger}} Signature of the message
|
* @return {{r: BigInteger, s: BigInteger}} Signature of the message
|
||||||
*/
|
*/
|
||||||
function sign(oid, hash_algo, m, d) {
|
async function sign(oid, hash_algo, m, d) {
|
||||||
var signature;
|
var signature;
|
||||||
const curve = curves.get(oid);
|
const curve = curves.get(oid);
|
||||||
if (webCrypto && config.use_native && curve.web) {
|
|
||||||
signature = webSign(curve, hash_algo, m, d);
|
|
||||||
} else if (nodeCrypto && config.use_native && curve.node) {
|
|
||||||
signature = nodeSign(curve, hash_algo, m, d);
|
|
||||||
} else {
|
|
||||||
const key = curve.keyFromPrivate(d.toByteArray());
|
const key = curve.keyFromPrivate(d.toByteArray());
|
||||||
signature = key.sign(m, hash_algo);
|
if (webCrypto && config.use_native && curve.web) {
|
||||||
|
signature = await webSign(curve, hash_algo, m, key.keyPair);
|
||||||
|
} else if (nodeCrypto && config.use_native && curve.node) {
|
||||||
|
signature = await nodeSign(curve, hash_algo, m, key.keyPair);
|
||||||
|
} else {
|
||||||
|
signature = await key.sign(m, hash_algo);
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
r: new BigInteger(signature.r),
|
r: new BigInteger(signature.r),
|
||||||
|
@ -78,16 +79,20 @@ function sign(oid, hash_algo, m, d) {
|
||||||
* @param {BigInteger} Q Public key used to verify the message
|
* @param {BigInteger} Q Public key used to verify the message
|
||||||
* @return {Boolean}
|
* @return {Boolean}
|
||||||
*/
|
*/
|
||||||
function verify(oid, hash_algo, signature, m, Q) {
|
async function verify(oid, hash_algo, signature, m, Q) {
|
||||||
|
var result;
|
||||||
const curve = curves.get(oid);
|
const curve = curves.get(oid);
|
||||||
if (webCrypto && config.use_native && curve.web) {
|
|
||||||
return webVerify(curve, hash_algo, signature, m, Q);
|
|
||||||
} else if (nodeCrypto && config.use_native && curve.node) {
|
|
||||||
return nodeVerify(curve, hash_algo, signature, m, Q);
|
|
||||||
} else {
|
|
||||||
const key = curve.keyFromPublic(Q.toByteArray());
|
const key = curve.keyFromPublic(Q.toByteArray());
|
||||||
return key.verify(m, {r: signature.r.toByteArray(), s: signature.s.toByteArray()}, hash_algo);
|
if (webCrypto && config.use_native && curve.web) {
|
||||||
|
result = await webVerify(curve, hash_algo, signature, m, key.keyPair.getPublic());
|
||||||
|
} else if (nodeCrypto && config.use_native && curve.node) {
|
||||||
|
result = await nodeVerify(curve, hash_algo, signature, m, key.keyPair.getPublic());
|
||||||
|
} else {
|
||||||
|
result = await key.verify(
|
||||||
|
m, {r: signature.r.toByteArray(), s: signature.s.toByteArray()}, hash_algo
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
@ -103,16 +108,16 @@ module.exports = {
|
||||||
//////////////////////////
|
//////////////////////////
|
||||||
|
|
||||||
|
|
||||||
async function webSign(curve, hash_algo, m, d) {
|
async function webSign(curve, hash_algo, m, keyPair) {
|
||||||
const publicKey = curve.keyFromPrivate(d).getPublic();
|
try {
|
||||||
const privateKey = await webCrypto.importKey(
|
const key = await webCrypto.importKey(
|
||||||
"jwk",
|
"jwk",
|
||||||
{
|
{
|
||||||
"kty": "EC",
|
"kty": "EC",
|
||||||
"crv": curve.namedCurve,
|
"crv": curve.namedCurve,
|
||||||
"x": publicKey.getX().toBuffer().base64Slice(),
|
"x": keyPair.getPublic().getX().toBuffer().base64Slice(),
|
||||||
"y": publicKey.getY().toBuffer().base64Slice(),
|
"y": keyPair.getPublic().getY().toBuffer().base64Slice(),
|
||||||
"d": d.toBuffer().base64Slice(),
|
"d": keyPair.getPrivate().toBuffer().base64Slice(),
|
||||||
"use": "sig",
|
"use": "sig",
|
||||||
"kid": "ECDSA Private Key"
|
"kid": "ECDSA Private Key"
|
||||||
},
|
},
|
||||||
|
@ -125,14 +130,13 @@ async function webSign(curve, hash_algo, m, d) {
|
||||||
["sign"]
|
["sign"]
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
|
||||||
return await webCrypto.sign(
|
return await webCrypto.sign(
|
||||||
{
|
{
|
||||||
"name": 'ECDSA',
|
"name": 'ECDSA',
|
||||||
"namedCurve": curve.namedCurve,
|
"namedCurve": curve.namedCurve,
|
||||||
"hash": { name: enums.read(enums.hash, hash_algo) }
|
"hash": { name: enums.read(enums.hash, hash_algo) }
|
||||||
},
|
},
|
||||||
privateKey,
|
key,
|
||||||
m
|
m
|
||||||
);
|
);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
|
@ -140,14 +144,15 @@ async function webSign(curve, hash_algo, m, d) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function webVerify(curve, hash_algo, signature, m, Q) {
|
async function webVerify(curve, hash_algo, signature, m, publicKey) {
|
||||||
const publicKey = await webCrypto.importKey(
|
try {
|
||||||
|
const key = await webCrypto.importKey(
|
||||||
"jwk",
|
"jwk",
|
||||||
{
|
{
|
||||||
"kty": "EC",
|
"kty": "EC",
|
||||||
"crv": curve.namedCurve,
|
"crv": curve.namedCurve,
|
||||||
"x": Q.getX().toBuffer().base64Slice(),
|
"x": publicKey.getX().toBuffer().base64Slice(),
|
||||||
"y": Q.getY().toBuffer().base64Slice(),
|
"y": publicKey.getY().toBuffer().base64Slice(),
|
||||||
"use": "sig",
|
"use": "sig",
|
||||||
"kid": "ECDSA Public Key"
|
"kid": "ECDSA Public Key"
|
||||||
},
|
},
|
||||||
|
@ -160,14 +165,13 @@ async function webVerify(curve, hash_algo, signature, m, Q) {
|
||||||
["verify"]
|
["verify"]
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
|
||||||
return await webCrypto.verify(
|
return await webCrypto.verify(
|
||||||
{
|
{
|
||||||
"name": 'ECDSA',
|
"name": 'ECDSA',
|
||||||
"namedCurve": curve.namedCurve,
|
"namedCurve": curve.namedCurve,
|
||||||
"hash": { name: enums.read(enums.hash, hash_algo) }
|
"hash": { name: enums.read(enums.hash, hash_algo) }
|
||||||
},
|
},
|
||||||
publicKey,
|
key,
|
||||||
signature,
|
signature,
|
||||||
m
|
m
|
||||||
);
|
);
|
||||||
|
@ -177,40 +181,60 @@ async function webVerify(curve, hash_algo, signature, m, Q) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async function nodeSign(curve, hash_algo, m, d) {
|
async function nodeSign(curve, hash_algo, message, keyPair) {
|
||||||
const publicKey = curve.keyFromPrivate(d).getPublic();
|
if (typeof message === 'string') {
|
||||||
const privateKey = jwk2pem(
|
message = util.str2Uint8Array(message);
|
||||||
{"kty": "EC",
|
}
|
||||||
|
const key = jwkToPem(
|
||||||
|
{
|
||||||
|
"kty": "EC",
|
||||||
"crv": curve.namedCurve,
|
"crv": curve.namedCurve,
|
||||||
"x": publicKey.getX().toBuffer().base64Slice(),
|
"x": keyPair.getPublic().getX().toBuffer().base64Slice(),
|
||||||
"y": publicKey.getY().toBuffer().base64Slice(),
|
"y": keyPair.getPublic().getY().toBuffer().base64Slice(),
|
||||||
"d": d.toBuffer().base64Slice(),
|
"d": keyPair.getPrivate().toBuffer().base64Slice(),
|
||||||
"use": "sig",
|
"use": "sig",
|
||||||
"kid": "ECDSA Private Key"},
|
"kid": "ECDSA Private Key"
|
||||||
|
},
|
||||||
{ private: true }
|
{ private: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// FIXME what happens when hash_algo = undefined?
|
||||||
const sign = nodeCrypto.createSign(enums.read(enums.hash, hash_algo));
|
const sign = nodeCrypto.createSign(enums.read(enums.hash, hash_algo));
|
||||||
sign.write(m);
|
sign.write(message);
|
||||||
sign.end();
|
sign.end();
|
||||||
const signature = await sign.sign(privateKey);
|
const signature = await ECDSASignature.decode(sign.sign(key), 'der');
|
||||||
return ECDSASignature.decode(signature, 'der');
|
return {
|
||||||
|
r: signature.r.toArray(),
|
||||||
|
s: signature.s.toArray()
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function nodeVerify(curve, hash_algo, signature, m, Q) {
|
async function nodeVerify(curve, hash_algo, signature, message, publicKey) {
|
||||||
const publicKey = jwk2pem(
|
signature = ECDSASignature.encode(
|
||||||
{"kty": "EC",
|
{
|
||||||
|
r: new BN(signature.r.toByteArray()),
|
||||||
|
s: new BN(signature.s.toByteArray())
|
||||||
|
},
|
||||||
|
'der');
|
||||||
|
if (typeof message === 'string') {
|
||||||
|
message = util.str2Uint8Array(message);
|
||||||
|
}
|
||||||
|
const key = jwkToPem(
|
||||||
|
{
|
||||||
|
"kty": "EC",
|
||||||
"crv": curve.namedCurve,
|
"crv": curve.namedCurve,
|
||||||
"x": Q.getX().toBuffer().base64Slice(),
|
"x": publicKey.getX().toBuffer().base64Slice(),
|
||||||
"y": Q.getY().toBuffer().base64Slice(),
|
"y": publicKey.getY().toBuffer().base64Slice(),
|
||||||
"use": "sig",
|
"use": "sig",
|
||||||
"kid": "ECDSA Public Key"},
|
"kid": "ECDSA Public Key"
|
||||||
|
},
|
||||||
{ private: false }
|
{ private: false }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// FIXME what happens when hash_algo = undefined?
|
||||||
const verify = nodeCrypto.createVerify(enums.read(enums.hash, hash_algo));
|
const verify = nodeCrypto.createVerify(enums.read(enums.hash, hash_algo));
|
||||||
verify.write(m);
|
verify.write(message);
|
||||||
verify.end();
|
verify.end();
|
||||||
const result = await verify.verify(publicKey, signature);
|
const result = await verify.verify(key, signature);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,12 @@ export default openpgp;
|
||||||
* import { encryptMessage } from 'openpgp.js'
|
* import { encryptMessage } from 'openpgp.js'
|
||||||
* encryptMessage(keys, text)
|
* encryptMessage(keys, text)
|
||||||
*/
|
*/
|
||||||
// export * from './openpgp';
|
export {
|
||||||
|
encrypt, decrypt, sign, verify,
|
||||||
|
generateKey, reformatKey, decryptKey,
|
||||||
|
encryptSessionKey, decryptSessionKey,
|
||||||
|
initWorker, getWorker, destroyWorker
|
||||||
|
} from './openpgp';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see module:key
|
* @see module:key
|
||||||
|
|
|
@ -2,7 +2,11 @@
|
||||||
|
|
||||||
var openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../../dist/openpgp');
|
var openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../../dist/openpgp');
|
||||||
|
|
||||||
var expect = require('chai').expect;
|
var chai = require('chai');
|
||||||
|
var chaiAsPromised = require('chai-as-promised');
|
||||||
|
chai.use(chaiAsPromised);
|
||||||
|
const expect = chai.expect;
|
||||||
|
|
||||||
|
|
||||||
var bin2bi = function (bytes) {
|
var bin2bi = function (bytes) {
|
||||||
var mpi = new openpgp.MPI();
|
var mpi = new openpgp.MPI();
|
||||||
|
@ -149,9 +153,10 @@ describe('Elliptic Curve Cryptography', function () {
|
||||||
var names = ['p256', 'p384', 'p521', 'secp256k1'];
|
var names = ['p256', 'p384', 'p521', 'secp256k1'];
|
||||||
names.forEach(function (name) {
|
names.forEach(function (name) {
|
||||||
var curve = elliptic_curves.get(name);
|
var curve = elliptic_curves.get(name);
|
||||||
var keyPair = curve.genKeyPair();
|
curve.genKeyPair().then(keyPair => {
|
||||||
expect(keyPair).to.exist;
|
expect(keyPair).to.exist;
|
||||||
expect(keyPair.isValid()).to.be.true;
|
expect(keyPair.isValid()).to.be.true; // FIXME done will skip this.
|
||||||
|
});
|
||||||
});
|
});
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
@ -201,21 +206,22 @@ describe('Elliptic Curve Cryptography', function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('ECDSA signature', function () {
|
describe('ECDSA signature', function () {
|
||||||
var verify_signature = function (oid, hash, r, s, pub, message) {
|
var verify_signature = function (oid, hash, r, s, message, pub) {
|
||||||
if (openpgp.util.isString(message)) {
|
if (openpgp.util.isString(message)) {
|
||||||
message = openpgp.util.str2Uint8Array(message);
|
message = openpgp.util.str2Uint8Array(message);
|
||||||
} else if (!openpgp.util.isUint8Array(message)) {
|
} else if (!openpgp.util.isUint8Array(message)) {
|
||||||
message = new Uint8Array(message);
|
message = new Uint8Array(message);
|
||||||
}
|
}
|
||||||
return function () {
|
return Promise.resolve().then(() => {
|
||||||
var ecdsa = elliptic_curves.ecdsa;
|
var ecdsa = elliptic_curves.ecdsa;
|
||||||
return ecdsa.verify(oid,
|
return ecdsa.verify(
|
||||||
|
oid,
|
||||||
hash,
|
hash,
|
||||||
{r: bin2bi(r), s: bin2bi(s)},
|
{r: bin2bi(r), s: bin2bi(s)},
|
||||||
message,
|
message,
|
||||||
bin2bi(pub)
|
bin2bi(pub)
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
};
|
};
|
||||||
var secp256k1_dummy_value = new Uint8Array([
|
var secp256k1_dummy_value = new Uint8Array([
|
||||||
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
@ -236,24 +242,30 @@ describe('Elliptic Curve Cryptography', function () {
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
|
||||||
it('Invalid curve oid', function (done) {
|
it('Invalid curve oid', function () {
|
||||||
var res = verify_signature('invalid oid', 8, [], [], [], []);
|
return Promise.all([
|
||||||
expect(res).to.throw(Error, /Not valid curve/);
|
expect(verify_signature(
|
||||||
res = verify_signature("\x00", 8, [], [], [], []);
|
'invalid oid', 8, [], [], [], []
|
||||||
expect(res).to.throw(Error, /Not valid curve/);
|
)).to.be.rejectedWith(Error, /Not valid curve/),
|
||||||
done();
|
expect(verify_signature(
|
||||||
|
"\x00", 8, [], [], [], []
|
||||||
|
)).to.be.rejectedWith(Error, /Not valid curve/)
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
it('Invalid public key', function (done) {
|
it('Invalid public key', function () {
|
||||||
var res = verify_signature('secp256k1', 8, [], [], [], []);
|
return Promise.all([
|
||||||
expect(res).to.throw(Error, /Unknown point format/);
|
expect(verify_signature(
|
||||||
res = verify_signature('secp256k1', 8, [], [], secp256k1_invalid_point, []);
|
'secp256k1', 8, [], [], [], []
|
||||||
expect(res).to.throw(Error, /Unknown point format/);
|
)).to.be.rejectedWith(Error, /Unknown point format/),
|
||||||
done();
|
expect(verify_signature(
|
||||||
|
'secp256k1', 8, [], [], [], secp256k1_invalid_point
|
||||||
|
)).to.be.rejectedWith(Error, /Unknown point format/)
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
it('Invalid signature', function (done) {
|
it('Invalid signature', function (done) {
|
||||||
var res = verify_signature('secp256k1', 8, [], [], secp256k1_dummy_point, []);
|
expect(verify_signature(
|
||||||
expect(res()).to.be.false;
|
'secp256k1', 8, [], [], [], secp256k1_dummy_point
|
||||||
done();
|
)).to.eventually.equal(false).notify(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
var p384_message = new Uint8Array([
|
var p384_message = new Uint8Array([
|
||||||
|
@ -274,23 +286,28 @@ describe('Elliptic Curve Cryptography', function () {
|
||||||
0x68, 0x58, 0x23, 0x1D, 0x11, 0xEF, 0x3D, 0x21,
|
0x68, 0x58, 0x23, 0x1D, 0x11, 0xEF, 0x3D, 0x21,
|
||||||
0x30, 0x75, 0x24, 0x39, 0x48, 0x89, 0x03, 0xDC]);
|
0x30, 0x75, 0x24, 0x39, 0x48, 0x89, 0x03, 0xDC]);
|
||||||
it('Valid signature', function (done) {
|
it('Valid signature', function (done) {
|
||||||
var res = verify_signature('p384', 8, p384_r, p384_s, key_data.p384.pub, p384_message);
|
verify_signature('p384', 8, p384_r, p384_s, p384_message, key_data.p384.pub)
|
||||||
expect(res()).to.be.true;
|
.then(res => {
|
||||||
|
expect(res).to.be.true;
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
});
|
||||||
it('Sign and verify message', function (done) {
|
it('Sign and verify message', function (done) {
|
||||||
var curve = elliptic_curves.get('p521');
|
var curve = elliptic_curves.get('p521');
|
||||||
var keyPair = curve.genKeyPair();
|
curve.genKeyPair().then(keyPair => {
|
||||||
var keyPublic = bin2bi(keyPair.getPublic());
|
var keyPublic = bin2bi(keyPair.getPublic());
|
||||||
var keyPrivate = bin2bi(keyPair.getPrivate());
|
var keyPrivate = bin2bi(keyPair.getPrivate());
|
||||||
var oid = curve.oid;
|
var oid = curve.oid;
|
||||||
var message = p384_message;
|
var message = p384_message;
|
||||||
var signature = elliptic_curves.ecdsa.sign(oid, 10, message, keyPrivate);
|
elliptic_curves.ecdsa.sign(oid, 10, message, keyPrivate).then(signature => {
|
||||||
var verified = elliptic_curves.ecdsa.verify(oid, 10, signature, message, keyPublic);
|
elliptic_curves.ecdsa.verify(oid, 10, signature, message, keyPublic).then(verified => {
|
||||||
expect(verified).to.be.true;
|
expect(verified).to.be.true;
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
describe('ECDH key exchange', function () {
|
describe('ECDH key exchange', function () {
|
||||||
var decrypt_message = function (oid, hash, cipher, priv, ephemeral, data, fingerprint) {
|
var decrypt_message = function (oid, hash, cipher, priv, ephemeral, data, fingerprint) {
|
||||||
if (typeof data === 'string') {
|
if (typeof data === 'string') {
|
||||||
|
@ -298,7 +315,7 @@ describe('Elliptic Curve Cryptography', function () {
|
||||||
} else {
|
} else {
|
||||||
data = new Uint8Array(data);
|
data = new Uint8Array(data);
|
||||||
}
|
}
|
||||||
return function () {
|
return Promise.resolve().then(() => {
|
||||||
var ecdh = elliptic_curves.ecdh;
|
var ecdh = elliptic_curves.ecdh;
|
||||||
return ecdh.decrypt(
|
return ecdh.decrypt(
|
||||||
oid,
|
oid,
|
||||||
|
@ -309,7 +326,7 @@ describe('Elliptic Curve Cryptography', function () {
|
||||||
bin2bi(priv),
|
bin2bi(priv),
|
||||||
fingerprint
|
fingerprint
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
};
|
};
|
||||||
var secp256k1_value = new Uint8Array([
|
var secp256k1_value = new Uint8Array([
|
||||||
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
@ -330,19 +347,19 @@ describe('Elliptic Curve Cryptography', function () {
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
|
||||||
|
|
||||||
it('Invalid curve oid', function (done) {
|
it('Invalid curve oid', function (done) {
|
||||||
var res = decrypt_message('', 2, 7, [], [], [], '');
|
expect(decrypt_message(
|
||||||
expect(res).to.throw(Error, /Not valid curve/);
|
'', 2, 7, [], [], [], ''
|
||||||
done();
|
)).to.be.rejectedWith(Error, /Not valid curve/).notify(done);
|
||||||
});
|
});
|
||||||
it('Invalid ephemeral key', function (done) {
|
it('Invalid ephemeral key', function (done) {
|
||||||
var res = decrypt_message('secp256k1', 2, 7, [], [], [], '');
|
expect(decrypt_message(
|
||||||
expect(res).to.throw(Error, /Unknown point format/);
|
'secp256k1', 2, 7, [], [], [], ''
|
||||||
done();
|
)).to.be.rejectedWith(Error, /Unknown point format/).notify(done);;
|
||||||
});
|
});
|
||||||
it('Invalid key data integrity', function (done) {
|
it('Invalid key data integrity', function (done) {
|
||||||
var res = decrypt_message('secp256k1', 2, 7, secp256k1_value, secp256k1_point, secp256k1_data, '');
|
expect(decrypt_message(
|
||||||
expect(res).to.throw(Error, /Key Data Integrity failed/);
|
'secp256k1', 2, 7, secp256k1_value, secp256k1_point, secp256k1_data, ''
|
||||||
done();
|
)).to.be.rejectedWith(Error, /Key Data Integrity failed/).notify(done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue
Block a user