Skip to content

Commit

Permalink
Removed pskcrypto dependency. Pending one final code review to make s…
Browse files Browse the repository at this point in the history
…ure everything is ok.
  • Loading branch information
Christos Patsonakis committed Apr 9, 2021
1 parent 050be43 commit 993d508
Show file tree
Hide file tree
Showing 13 changed files with 145 additions and 101 deletions.
21 changes: 13 additions & 8 deletions bench/bench-ecies-doa-ds.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
const ecies = require('../ecies-doa-ds')
const crypto = require('crypto')
$$ = {Buffer};
const pskcrypto = require("../pskcrypto");
const curveName = require('../crypto').params.curveName;


const NS_PER_SEC = 1e9;
Expand All @@ -15,23 +14,29 @@ for (i = 0; i < msgNo ; ++i) {
}
encArray = new Array(msgNo)

let keyGenerator = pskcrypto.createKeyPairGenerator();
let aliceECKeyPair = keyGenerator.generateKeyPair();
let bobECKeyPair = keyGenerator.generateKeyPair();
let alicePEMKeyPair = keyGenerator.getPemKeys(aliceECKeyPair.privateKey, aliceECKeyPair.publicKey)
// Generate Alice's EC signing key pair
let aliceECSigningKeyPair = crypto.generateKeyPairSync(
'ec',
{
namedCurve: curveName
}
)
let bobECDH = crypto.createECDH(curveName)
let bobECDHPublicKey = bobECDH.generateKeys();
let bobECDHPrivateKey = bobECDH.getPrivateKey();

// Start with encyptions
var startTime = process.hrtime();
for (i = 0 ; i < msgNo ; ++i) {
encArray[i] = ecies.encrypt(alicePEMKeyPair, bobECKeyPair.publicKey, msgArray[i])
encArray[i] = ecies.encrypt(aliceECSigningKeyPair, bobECDHPublicKey, msgArray[i])
}
var totalHRTime = process.hrtime(startTime);
var encTimeSecs = (totalHRTime[0]* NS_PER_SEC + totalHRTime[1]) / NS_PER_SEC

// Do decryptions now
startTime = process.hrtime();
for (i = 0 ; i < msgNo ; ++i) {
ecies.decrypt(bobECKeyPair.privateKey, encArray[i])
ecies.decrypt(bobECDHPrivateKey, encArray[i])
}
totalHRTime = process.hrtime(startTime);
var decTimeSecs = (totalHRTime[0]* NS_PER_SEC + totalHRTime[1]) / NS_PER_SEC
Expand Down
22 changes: 14 additions & 8 deletions bench/bench-ecies-doa-kmac.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
const crypto = require('crypto')
const ecies = require('../ecies-doa-kmac')
$$ = {Buffer};
const pskcrypto = require("../pskcrypto");
const crypto = require('crypto')
const curveName = require('../crypto').params.curveName;

const NS_PER_SEC = 1e9;
const msgNo = 500
Expand All @@ -15,22 +14,29 @@ for (i = 0; i < msgNo ; ++i) {
encArray = new Array(msgNo)


let keyGenerator = pskcrypto.createKeyPairGenerator();
let aliceECKeyPair = keyGenerator.generateKeyPair();
let bobECKeyPair = keyGenerator.generateKeyPair();
let aliceECDH = crypto.createECDH(curveName)
let aliceECDHPublicKey = aliceECDH.generateKeys();
let aliceECDHPrivateKey = aliceECDH.getPrivateKey();
let aliceECDHKeyPair = {
publicKey: aliceECDHPublicKey,
privateKey: aliceECDHPrivateKey
}
let bobECDH = crypto.createECDH(curveName)
let bobECDHPublicKey = bobECDH.generateKeys();
let bobECDHPrivateKey = bobECDH.getPrivateKey();

// Start with encyptions
var startTime = process.hrtime();
for (i = 0 ; i < msgNo ; ++i) {
encArray[i] = ecies.encrypt(aliceECKeyPair, bobECKeyPair.publicKey, msgArray[i])
encArray[i] = ecies.encrypt(aliceECDHKeyPair, bobECDHPublicKey, msgArray[i])
}
var totalHRTime = process.hrtime(startTime);
var encTimeSecs = (totalHRTime[0]* NS_PER_SEC + totalHRTime[1]) / NS_PER_SEC

// Do decryptions now
startTime = process.hrtime();
for (i = 0 ; i < msgNo ; ++i) {
ecies.decrypt(bobECKeyPair.privateKey, encArray[i])
ecies.decrypt(bobECDHPrivateKey, encArray[i])
}
totalHRTime = process.hrtime(startTime);
var decTimeSecs = (totalHRTime[0]* NS_PER_SEC + totalHRTime[1]) / NS_PER_SEC
Expand Down
26 changes: 17 additions & 9 deletions bench/ecdh-ecdsa-comp.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,36 @@
const crypto = require('crypto')
const mycrypto = require('../crypto')

$$ = {Buffer};
const pskcrypto = require("../pskcrypto");
const curveName = require('../crypto').params.curveName; //get the default named curve

const NS_PER_SEC = 1e9;
const iterations = 1000

let message = crypto.pseudoRandomBytes(32)
let keyGenerator = pskcrypto.createKeyPairGenerator();
let aliceECKeyPair = keyGenerator.generateKeyPair();
let bobECKeyPair = keyGenerator.generateKeyPair();
let aliceECKeyPairPEM = keyGenerator.getPemKeys(aliceECKeyPair.privateKey, aliceECKeyPair.publicKey)

let aliceECDH = crypto.createECDH(curveName)
aliceECDH.generateKeys()
let aliceECDHPrivateKey = aliceECDH.getPrivateKey()
let aliceECSigningKeyPair = crypto.generateKeyPairSync(
'ec',
{
namedCurve: curveName
}
)
// Generate Bob's ECDH key pair (message receiver)
let bobECDH = crypto.createECDH(curveName)
let bobECDHPublicKey = bobECDH.generateKeys();

var startTime = process.hrtime();
for (i = 0 ; i < iterations ; ++i) {
mycrypto.ECEphemeralKeyAgreement.computeSharedSecretFromKeyPair(aliceECKeyPair.privateKey, bobECKeyPair.publicKey)
let ephemeralKA = new mycrypto.ECEphemeralKeyAgreement()
ephemeralKA.computeSharedSecretFromKeyPair(aliceECDHPrivateKey, bobECDHPublicKey)
}
var totalHRTime = process.hrtime(startTime);
var ecdhTimeSecs = (totalHRTime[0]* NS_PER_SEC + totalHRTime[1]) / NS_PER_SEC

var startTime = process.hrtime();
for (i = 0 ; i < iterations ; ++i) {
mycrypto.computeDigitalSignature(aliceECKeyPairPEM.privateKey, message)
mycrypto.computeDigitalSignature(aliceECSigningKeyPair.privateKey, message)
}
var totalHRTime = process.hrtime(startTime);
var ecdsaTimeSecs = (totalHRTime[0]* NS_PER_SEC + totalHRTime[1]) / NS_PER_SEC
Expand Down
13 changes: 12 additions & 1 deletion common/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,20 @@ function checkEncryptedEnvelopeMandatoryProperties(encryptedEnvelope) {
})
}

function createEncryptedEnvelopeObject(receiverECDHPublicKey, ephemeralECDHPublicKey, ciphertext, iv, tag) {
return {
to_ecdh: receiverECDHPublicKey.toString(mycrypto.encodingFormat),
r: ephemeralECDHPublicKey.toString(mycrypto.encodingFormat),
ct: ciphertext.toString(mycrypto.encodingFormat),
iv: iv.toString(mycrypto.encodingFormat),
tag: tag.toString(mycrypto.encodingFormat)
}
}

module.exports = {
computeKDFInput,
computeSymmetricEncAndMACKeys,
getDecodedECDHPublicKeyFromEncEnvelope,
checkEncryptedEnvelopeMandatoryProperties
checkEncryptedEnvelopeMandatoryProperties,
createEncryptedEnvelopeObject
}
2 changes: 1 addition & 1 deletion crypto/digitalsig.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ function computeDigitalSignature(privateECSigningKey, buffer) {

function verifyDigitalSignature(publicECVerificationKey, signature, buffer) {
let encodingFormat = require('./index').encodingFormat;
let verifyObject = crypto.createVerify(signAlgoName)
let verifyObject = crypto.createVerify(config.signAlgoName)
verifyObject.update(buffer)
verifyObject.end()
return verifyObject.verify(publicECVerificationKey, signature)
Expand Down
28 changes: 13 additions & 15 deletions ecies-doa-ds/decrypt.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,25 @@

const mycrypto = require('../crypto')
const common = require('../common')

function checkEncryptedEnvelopeMandatoryProperties(encryptedEnvelope) {
const mandatoryProperties = ["to", "r", "ct", "iv", "tag"];
mandatoryProperties.forEach((property) => {
if (typeof encryptedEnvelope[property] === undefined) {
throw new Error("Mandatory property " + property + " is missing from input encrypted envelope");
}
})
}
const crypto = require('crypto')

function checkWrappedMessageMandatoryProperties(wrappedMessage) {
const mandatoryProperties = ["from", "msg", "sig"];
const mandatoryProperties = ["from_ecsig", "msg", "sig"];
mandatoryProperties.forEach((property) => {
if (typeof wrappedMessage[property] === undefined) {
throw new Error("Mandatory property " + property + " is missing from wrapped message");
}
})
}

module.exports.decrypt = function (receiverPrivateKey, encEnvelope) {
module.exports.decrypt = function (receiverECDHPrivateKey, encEnvelope) {

checkEncryptedEnvelopeMandatoryProperties(encEnvelope)
common.checkEncryptedEnvelopeMandatoryProperties(encEnvelope)

const ephemeralPublicKey = Buffer.from(encEnvelope.r, mycrypto.encodingFormat)

const sharedSecret = mycrypto.ECEphemeralKeyAgreement.computeSharedSecretFromKeyPair(receiverPrivateKey, ephemeralPublicKey)
const ephemeralKeyAgreement = new mycrypto.ECEphemeralKeyAgreement()
const sharedSecret = ephemeralKeyAgreement.computeSharedSecretFromKeyPair(receiverECDHPrivateKey, ephemeralPublicKey)

const kdfInput = common.computeKDFInput(ephemeralPublicKey, sharedSecret)
const { symmetricEncryptionKey, macKey } = common.computeSymmetricEncAndMACKeys(kdfInput)
Expand All @@ -44,14 +37,19 @@ module.exports.decrypt = function (receiverPrivateKey, encEnvelope) {

let wrappedMessageObject = JSON.parse(mycrypto.symmetricDecrypt(symmetricEncryptionKey, ciphertext, iv).toString())
checkWrappedMessageMandatoryProperties(wrappedMessageObject)
const senderECSigVerPublicKey = crypto.createPublicKey({
key: wrappedMessageObject.from_ecsig,
format: 'pem',
type: 'spki'
})

if (!mycrypto.verifyDigitalSignature(wrappedMessageObject.from,
if (!mycrypto.verifyDigitalSignature(senderECSigVerPublicKey,
Buffer.from(wrappedMessageObject.sig, mycrypto.encodingFormat),
sharedSecret)) {
throw new Error("Bad signature")
}
return {
from: wrappedMessageObject.from,
from_ecsig: senderECSigVerPublicKey,
message: Buffer.from(wrappedMessageObject.msg, mycrypto.encodingFormat)
};
}
57 changes: 42 additions & 15 deletions ecies-doa-ds/encrypt.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,60 @@
'use strict';

const mycrypto = require('../crypto')
const common = require('../common')
const common = require('../common');

function senderMessageWrapAndSerialization(senderPublicKey, message, signature) {
function senderMessageWrapAndSerialization(senderECSigVerPublicKey, message, signature) {
return JSON.stringify({
from: senderPublicKey,
from_ecsig: senderECSigVerPublicKey.export({
type: 'spki',
format: 'pem'
}),
msg: message.toString(mycrypto.encodingFormat),
sig: signature.toString(mycrypto.encodingFormat)
});
}

module.exports.encrypt = function(senderECKeyPairPEM, receiverECPublicKey, message) {
function checkECSigningKeyPairTypeInput(senderECSigningKeyPair) {
if (typeof senderECSigningKeyPair.publicKey === undefined) {
throw new Error("Mandatory property publicKey is missing from input EC signing key pair object");
}
if (typeof senderECSigningKeyPair.publicKey.type === undefined ||
senderECSigningKeyPair.publicKey.type !== 'public') {
throw new Error("Public key is not of type public")
}
if (typeof senderECSigningKeyPair.publicKey.asymmetricKeyType === undefined ||
senderECSigningKeyPair.publicKey.asymmetricKeyType !== 'ec') {
throw new Error("Invalid asymmetric type for EC public key")
}
if (typeof senderECSigningKeyPair.privateKey === undefined) {
throw new Error("Mandatory property privateKey is missing from input EC signing key pair object");
}
if (typeof senderECSigningKeyPair.privateKey.type === undefined ||
senderECSigningKeyPair.privateKey.type !== 'private') {
throw new Error("Private key is not of type public")
}
if (typeof senderECSigningKeyPair.privateKey.asymmetricKeyType === undefined ||
senderECSigningKeyPair.publicKey.asymmetricKeyType !== 'ec') {
throw new Error("Invalid asymmetric type for EC private key")
}


}

module.exports.encrypt = function (senderECSigningKeyPair, receiverECDHPublicKey, message) {

if (!Buffer.isBuffer(message)) {
throw new Error('Input message has to be of type Buffer')
}

const ephemeralPublicKey = mycrypto.ECEphemeralKeyAgreement.generateEphemeralPublicKey()
const sharedSecret = mycrypto.ECEphemeralKeyAgreement.generateSharedSecretForPublicKey(receiverECPublicKey)
checkECSigningKeyPairTypeInput(senderECSigningKeyPair)

const signature = mycrypto.computeDigitalSignature(senderECKeyPairPEM.privateKey, sharedSecret)
const senderAuthMsgEnvelopeSerialized = senderMessageWrapAndSerialization(senderECKeyPairPEM.publicKey, message, signature)
const ephemeralKeyAgreement = new mycrypto.ECEphemeralKeyAgreement()
const ephemeralPublicKey = ephemeralKeyAgreement.generateEphemeralPublicKey()
const sharedSecret = ephemeralKeyAgreement.generateSharedSecretForPublicKey(receiverECDHPublicKey)

const signature = mycrypto.computeDigitalSignature(senderECSigningKeyPair.privateKey, sharedSecret)
const senderAuthMsgEnvelopeSerialized = senderMessageWrapAndSerialization(senderECSigningKeyPair.publicKey, message, signature)

const kdfInput = common.computeKDFInput(ephemeralPublicKey, sharedSecret)
const { symmetricEncryptionKey, macKey } = common.computeSymmetricEncAndMACKeys(kdfInput)
Expand All @@ -30,11 +63,5 @@ module.exports.encrypt = function(senderECKeyPairPEM, receiverECPublicKey, messa
const ciphertext = mycrypto.symmetricEncrypt(symmetricEncryptionKey, senderAuthMsgEnvelopeSerialized, iv)
const tag = mycrypto.KMAC.computeKMAC(macKey, Buffer.concat([ciphertext, iv], ciphertext.length + iv.length))

return {
to: receiverECPublicKey.toString(mycrypto.encodingFormat),
r: ephemeralPublicKey.toString(mycrypto.encodingFormat),
ct: ciphertext.toString(mycrypto.encodingFormat),
iv: iv.toString(mycrypto.encodingFormat),
tag: tag.toString(mycrypto.encodingFormat)
}
return common.createEncryptedEnvelopeObject(receiverECDHPublicKey, ephemeralPublicKey, ciphertext, iv, tag)
};
3 changes: 2 additions & 1 deletion ecies-doa-ds/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@

module.exports = {
encrypt: require('./encrypt').encrypt,
decrypt: require('./decrypt').decrypt
decrypt: require('./decrypt').decrypt,
getDecodedECDHPublicKeyFromEncEnvelope: require('../common').getDecodedECDHPublicKeyFromEncEnvelope
}
8 changes: 1 addition & 7 deletions ecies-doa-kmac/encrypt.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,5 @@ module.exports.encrypt = function (senderECDHKeyPair, receiverECDHPublicKey, mes
ciphertext.length + iv.length + senderDerivedSharedSecret.length)
)

return {
to_ecdh: receiverECDHPublicKey.toString(mycrypto.encodingFormat),
r: ephemeralPublicKey.toString(mycrypto.encodingFormat),
ct: ciphertext.toString(mycrypto.encodingFormat),
iv: iv.toString(mycrypto.encodingFormat),
tag: tag.toString(mycrypto.encodingFormat)
}
return common.createEncryptedEnvelopeObject(receiverECDHPublicKey, ephemeralPublicKey, ciphertext, iv, tag)
};
10 changes: 2 additions & 8 deletions ecies/encrypt.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,6 @@ module.exports.encrypt = function(receiverECDHPublicKey, message) {
const iv = mycrypto.getRandomBytes(mycrypto.params.ivSize)
const ciphertext = mycrypto.symmetricEncrypt(symmetricEncryptionKey, message, iv)
const tag = mycrypto.KMAC.computeKMAC(macKey, Buffer.concat([ciphertext, iv], ciphertext.length + iv.length))

return {
to_ecdh: receiverECDHPublicKey.toString(mycrypto.encodingFormat),
r: ephemeralPublicKey.toString(mycrypto.encodingFormat),
ct: ciphertext.toString(mycrypto.encodingFormat),
iv: iv.toString(mycrypto.encodingFormat),
tag: tag.toString(mycrypto.encodingFormat)
}

return common.createEncryptedEnvelopeObject(receiverECDHPublicKey, ephemeralPublicKey, ciphertext, iv, tag)
}
Loading

0 comments on commit 993d508

Please sign in to comment.