TFS_ANTIGUO/SIGPC/ProyectoSIGPC/hfda/scripts/ecdh.js
kledezma 7fdadc4709 KLB
git-tfs-id: [http://192.168.1.10:8080/tfs/AyA]$/SINORT;C519
2021-01-22 15:05:35 +00:00

233 lines
No EOL
7.1 KiB
JavaScript

//*******************************************************************************
//
// Copyright 2014 Microsoft
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//*******************************************************************************
/// #region JSCop/JsHint
/* global operations */
/* global cryptoMath */
/* global cryptoECC */
/* global msrcryptoPseudoRandom */
/* global msrcryptoJwk */
/// <dictionary>btd,dtb,Ecdh,ecop,msrcrypto</dictionary>
/// <disable>DeclareVariablesBeforeUse</disable>
/// #endregion JSCop/JsHint
var msrcryptoEcdh = function (curve) {
var btd = cryptoMath.bytesToDigits,
dtb = cryptoMath.digitsToBytes,
e = curve,
ecop = new cryptoECC.EllipticCurveOperatorFp(curve);
function generateKey() {
var privateKey = [],
randomBytes = msrcryptoPseudoRandom.getBytes(
curve.order.length * cryptoMath.DIGIT_NUM_BYTES);
cryptoMath.reduce(
cryptoMath.bytesToDigits(randomBytes),
e.order,
privateKey);
if (!e.generator.isInMontgomeryForm) {
ecop.convertToMontgomeryForm(e.generator);
}
var publicKey = e.allocatePointStorage();
ecop.convertToJacobianForm(publicKey);
ecop.convertToMontgomeryForm(publicKey);
ecop.scalarMultiply(privateKey, e.generator, publicKey);
ecop.convertToAffineForm(publicKey);
ecop.convertToStandardForm(publicKey);
return {
privateKey: {
x: dtb(publicKey.x),
y: dtb(publicKey.y),
d: dtb(privateKey)
},
publicKey: {
x: dtb(publicKey.x),
y: dtb(publicKey.y)
}
};
}
function deriveBits(privateKey, publicKey, length) {
var publicPoint = new cryptoECC.EllipticCurvePointFp(
e, false, btd(publicKey.x), btd(publicKey.y), null, false);
if (!publicPoint.isInMontgomeryForm) {
ecop.convertToMontgomeryForm(publicPoint);
}
if (!publicPoint.isAffine) {
ecop.convertToAffineForm(publicPoint);
}
var sharedSecretPoint = e.allocatePointStorage();
ecop.convertToJacobianForm(sharedSecretPoint);
ecop.convertToMontgomeryForm(sharedSecretPoint);
ecop.scalarMultiply(btd(privateKey.d), publicPoint, sharedSecretPoint);
ecop.convertToAffineForm(sharedSecretPoint);
ecop.convertToStandardForm(sharedSecretPoint);
var secretBytes = cryptoMath.digitsToBytes(sharedSecretPoint.x);
if (length && secretBytes.length < length) {
throw new Error("DataError");
}
return length ? secretBytes.slice(0, length) : secretBytes;
}
function computePublicKey(privateKeyBytes) {
if (!e.generator.isInMontgomeryForm) {
ecop.convertToMontgomeryForm(e.generator);
}
var publicKey = e.allocatePointStorage();
ecop.convertToJacobianForm(publicKey);
ecop.convertToMontgomeryForm(publicKey);
ecop.scalarMultiply(btd(privateKeyBytes), e.generator, publicKey);
return {
x: dtb(publicKey.x),
y: dtb(publicKey.y)
};
}
return {
generateKey: generateKey,
deriveBits: deriveBits,
computePublicKey: computePublicKey
};
};
var ecdhInstance = null;
if (typeof operations !== "undefined") {
msrcryptoEcdh.curves = {
"P-256": cryptoECC.createP256,
"P-384": cryptoECC.createP384,
"P-521": cryptoECC.createP521
};
msrcryptoEcdh.deriveBits = function (p) {
var curve = msrcryptoEcdh.curves[p.algorithm.namedCurve.toUpperCase()]();
var privateKey = p.keyData;
var publicKey = p.additionalKeyData;
ecdhInstance = msrcryptoEcdh(curve);
var secretBytes = ecdhInstance.deriveBits(privateKey, publicKey, p.length);
return secretBytes;
};
msrcryptoEcdh.generateKey = function (p) {
var curve = msrcryptoEcdh.curves[p.algorithm.namedCurve.toUpperCase()]();
ecdhInstance = msrcryptoEcdh(curve);
var keyPairData = ecdhInstance.generateKey();
return {
type: "keyPairGeneration",
keyPair: {
publicKey: {
keyData: keyPairData.publicKey,
keyHandle: {
algorithm: p.algorithm,
extractable: p.extractable,
keyUsage: null || p.keyUsage,
type: "public"
}
},
privateKey: {
keyData: keyPairData.privateKey,
keyHandle: {
algorithm: p.algorithm,
extractable: p.extractable,
keyUsage: null || p.keyUsage,
type: "private"
}
}
}
};
};
msrcryptoEcdh.importKey = function (p) {
var keyObject = msrcryptoJwk.jwkToKey(p.keyData, p.algorithm, ["x", "y", "d", "crv"]);
// If only private key data 'd' is imported, create x and y
if (keyObject.d && (!keyObject.x || !keyObject.y)) {
var curve = msrcryptoEcdh.curves[p.algorithm.namedCurve]();
ecdhInstance = msrcryptoEcdh(curve);
var publicKey = ecdhInstance.computePublicKey(keyObject.d);
keyObject.x = publicKey.x;
keyObject.y = publicKey.y;
}
return {
type: "keyImport",
keyData: keyObject,
keyHandle: {
algorithm: p.algorithm,
extractable: p.extractable || keyObject.extractable,
keyUsage: null || p.keyUsage, // IE11 returns null here
type: (keyObject.d) ? "private" : "public"
}
};
};
msrcryptoEcdh.exportKey = function (p) {
var jsonKeyStringArray = msrcryptoJwk.keyToJwk(p.keyHandle, p.keyData);
return { type: "keyExport", keyHandle: jsonKeyStringArray };
};
operations.register("importKey", "ecdh", msrcryptoEcdh.importKey);
operations.register("exportKey", "ecdh", msrcryptoEcdh.exportKey);
operations.register("generateKey", "ecdh", msrcryptoEcdh.generateKey);
operations.register("deriveBits", "ecdh", msrcryptoEcdh.deriveBits);
}