ElGamal and MPI use bn.js; TODO: RSA Key Generation
This commit is contained in:
parent
490b1dc0f0
commit
e1d85ba682
|
@ -32,7 +32,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import BN from 'bn.js';
|
import BN from 'bn.js';
|
||||||
import { RSA_RAW } from 'asmcrypto.js';
|
|
||||||
import publicKey from './public_key';
|
import publicKey from './public_key';
|
||||||
import cipher from './cipher';
|
import cipher from './cipher';
|
||||||
import random from './random';
|
import random from './random';
|
||||||
|
@ -68,18 +67,19 @@ export default {
|
||||||
switch (algo) {
|
switch (algo) {
|
||||||
case 'rsa_encrypt':
|
case 'rsa_encrypt':
|
||||||
case 'rsa_encrypt_sign': {
|
case 'rsa_encrypt_sign': {
|
||||||
|
const m = data.toUint8Array();
|
||||||
const n = publicParams[0].toUint8Array();
|
const n = publicParams[0].toUint8Array();
|
||||||
const e = publicParams[1].toUint8Array();
|
const e = publicParams[1].toUint8Array();
|
||||||
const m = data.toUint8Array();
|
const res = await publicKey.rsa.encrypt(m, n, e);
|
||||||
return constructParams(types, [new BN(RSA_RAW.encrypt(m, [n, e]))]);
|
return constructParams(types, [new BN(res)]);
|
||||||
}
|
}
|
||||||
case 'elgamal': {
|
case 'elgamal': {
|
||||||
const elgamal = new publicKey.elgamal();
|
const m = data.toBN();
|
||||||
const p = publicParams[0].toBigInteger();
|
const p = publicParams[0].toBN();
|
||||||
const g = publicParams[1].toBigInteger();
|
const g = publicParams[1].toBN();
|
||||||
const y = publicParams[2].toBigInteger();
|
const y = publicParams[2].toBN();
|
||||||
const m = data.toBigInteger();
|
const res = await publicKey.elgamal.encrypt(m, p, g, y);
|
||||||
return constructParams(types, elgamal.encrypt(m, g, p, y));
|
return constructParams(types, [res.c1, res.c2]);
|
||||||
}
|
}
|
||||||
case 'ecdh': {
|
case 'ecdh': {
|
||||||
const oid = publicParams[0];
|
const oid = publicParams[0];
|
||||||
|
@ -117,18 +117,14 @@ export default {
|
||||||
const p = keyIntegers[3].toUint8Array();
|
const p = keyIntegers[3].toUint8Array();
|
||||||
const q = keyIntegers[4].toUint8Array();
|
const q = keyIntegers[4].toUint8Array();
|
||||||
const u = keyIntegers[5].toUint8Array(); // q^-1 mod p
|
const u = keyIntegers[5].toUint8Array(); // q^-1 mod p
|
||||||
const dd = new BN(d);
|
return publicKey.rsa.decrypt(c, n, e, d, p, q, u);
|
||||||
const dp = dd.mod(new BN(p).subn(1)).toArrayLike(Uint8Array); // d mod (p-1)
|
|
||||||
const dq = dd.mod(new BN(q).subn(1)).toArrayLike(Uint8Array); // d mod (q-1)
|
|
||||||
return new BN(RSA_RAW.decrypt(c, [n, e, d, q, p, dq, dp, u]).slice(1)); // FIXME remove slice
|
|
||||||
}
|
}
|
||||||
case 'elgamal': {
|
case 'elgamal': {
|
||||||
const elgamal = new publicKey.elgamal();
|
const c1 = dataIntegers[0].toBN();
|
||||||
const x = keyIntegers[3].toBigInteger();
|
const c2 = dataIntegers[1].toBN();
|
||||||
const c1 = dataIntegers[0].toBigInteger();
|
const p = keyIntegers[0].toBN();
|
||||||
const c2 = dataIntegers[1].toBigInteger();
|
const x = keyIntegers[3].toBN();
|
||||||
const p = keyIntegers[0].toBigInteger();
|
return publicKey.elgamal.decrypt(c1, c2, p, x);
|
||||||
return elgamal.decrypt(c1, c2, p, x);
|
|
||||||
}
|
}
|
||||||
case 'ecdh': {
|
case 'ecdh': {
|
||||||
const oid = keyIntegers[0];
|
const oid = keyIntegers[0];
|
||||||
|
@ -263,8 +259,7 @@ export default {
|
||||||
case 'rsa_encrypt':
|
case 'rsa_encrypt':
|
||||||
case 'rsa_encrypt_sign':
|
case 'rsa_encrypt_sign':
|
||||||
case 'rsa_sign': {
|
case 'rsa_sign': {
|
||||||
const rsa = new publicKey.rsa();
|
return publicKey.rsa.generate(bits, "10001").then(function(keyObject) {
|
||||||
return rsa.generate(bits, "10001").then(function(keyObject) {
|
|
||||||
return constructParams(
|
return constructParams(
|
||||||
types, [keyObject.n, keyObject.ee, keyObject.d, keyObject.p, keyObject.q, keyObject.u]
|
types, [keyObject.n, keyObject.ee, keyObject.d, keyObject.p, keyObject.q, keyObject.u]
|
||||||
);
|
);
|
||||||
|
|
|
@ -86,7 +86,7 @@ export default {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return {r: r.fromRed(), s: s.fromRed()};
|
return { r: r.fromRed(), s: s.fromRed() };
|
||||||
},
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -18,39 +18,41 @@
|
||||||
// ElGamal implementation
|
// ElGamal implementation
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @requires crypto/public_key/jsbn
|
* @requires bn.js
|
||||||
* @requires crypto/random
|
* @requires crypto/random
|
||||||
* @requires util
|
|
||||||
* @module crypto/public_key/elgamal
|
* @module crypto/public_key/elgamal
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import BigInteger from './jsbn.js';
|
import BN from 'bn.js';
|
||||||
import random from '../random.js';
|
import random from '../random';
|
||||||
import util from '../../util.js';
|
|
||||||
|
|
||||||
export default function Elgamal() {
|
const one = new BN(1);
|
||||||
function encrypt(m, g, p, y) {
|
|
||||||
// choose k in {2,...,p-2}
|
export default {
|
||||||
const pMinus2 = p.subtract(BigInteger.TWO);
|
/*
|
||||||
let k = random.getRandomBigIntegerInRange(BigInteger.ONE, pMinus2);
|
* m, p, g, y are all BN
|
||||||
k = k.mod(pMinus2).add(BigInteger.ONE);
|
* returns { c1: BN, c2: BN }
|
||||||
const c = [];
|
*/
|
||||||
c[0] = g.modPow(k, p);
|
encrypt: function(m, p, g, y) {
|
||||||
c[1] = y.modPow(k, p).multiply(m).mod(p);
|
const redp = new BN.red(p);
|
||||||
return c;
|
const mred = m.toRed(redp);
|
||||||
|
const gred = g.toRed(redp);
|
||||||
|
const yred = y.toRed(redp);
|
||||||
|
const k = random.getRandomBN(one, p);
|
||||||
|
return {
|
||||||
|
c1: gred.redPow(k).fromRed(),
|
||||||
|
c2: yred.redPow(k).redMul(mred).fromRed()
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* c1, c2, p, x are all BN
|
||||||
|
* returns BN
|
||||||
|
*/
|
||||||
|
decrypt: function(c1, c2, p, x) {
|
||||||
|
const redp = new BN.red(p);
|
||||||
|
const c1red = c1.toRed(redp);
|
||||||
|
const c2red = c2.toRed(redp);
|
||||||
|
return c1red.redPow(x).redInvm().redMul(c2red).fromRed();
|
||||||
}
|
}
|
||||||
|
};
|
||||||
function decrypt(c1, c2, p, x) {
|
|
||||||
util.print_debug("Elgamal Decrypt:\nc1:" + util.hexstrdump(c1.toMPI()) + "\n" +
|
|
||||||
"c2:" + util.hexstrdump(c2.toMPI()) + "\n" +
|
|
||||||
"p:" + util.hexstrdump(p.toMPI()) + "\n" +
|
|
||||||
"x:" + util.hexstrdump(x.toMPI()));
|
|
||||||
return (c1.modPow(x, p).modInverse(p)).multiply(c2).mod(p);
|
|
||||||
//var c = c1.pow(x).modInverse(p); // c0^-a mod p
|
|
||||||
//return c.multiply(c2).mod(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
// signing and signature verification using Elgamal is not required by OpenPGP.
|
|
||||||
this.encrypt = encrypt;
|
|
||||||
this.decrypt = decrypt;
|
|
||||||
}
|
|
||||||
|
|
|
@ -67,7 +67,7 @@ function kdf(hash_algo, X, length, param) {
|
||||||
* @param {module:type/oid} oid Elliptic curve object identifier
|
* @param {module:type/oid} oid Elliptic curve object identifier
|
||||||
* @param {Enums} cipher_algo Symmetric cipher to use
|
* @param {Enums} cipher_algo Symmetric cipher to use
|
||||||
* @param {Enums} hash_algo Hash algorithm to use
|
* @param {Enums} hash_algo Hash algorithm to use
|
||||||
* @param {Uint8Array} m Value derived from session key (RFC 6637)
|
* @param {module:type/mpi} m Value derived from session key (RFC 6637)
|
||||||
* @param {Uint8Array} Q Recipient public key
|
* @param {Uint8Array} Q Recipient public key
|
||||||
* @param {String} fingerprint Recipient fingerprint
|
* @param {String} fingerprint Recipient fingerprint
|
||||||
* @return {{V: BN, C: BN}} Returns ephemeral key and encoded session key
|
* @return {{V: BN, C: BN}} Returns ephemeral key and encoded session key
|
||||||
|
@ -81,7 +81,7 @@ async function encrypt(oid, cipher_algo, hash_algo, m, Q, fingerprint) {
|
||||||
Q = curve.keyFromPublic(Q);
|
Q = curve.keyFromPublic(Q);
|
||||||
const S = v.derive(Q);
|
const S = v.derive(Q);
|
||||||
const Z = kdf(hash_algo, S, cipher[cipher_algo].keySize, param);
|
const Z = kdf(hash_algo, S, cipher[cipher_algo].keySize, param);
|
||||||
const C = aes_kw.wrap(Z, m.toBytes());
|
const C = aes_kw.wrap(Z, m.toString());
|
||||||
return {
|
return {
|
||||||
V: new BN(v.getPublic()),
|
V: new BN(v.getPublic()),
|
||||||
C: C
|
C: C
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
// RSA implementation
|
// RSA implementation
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @requires bn.js
|
||||||
* @requires asmcrypto.js
|
* @requires asmcrypto.js
|
||||||
* @requires crypto/public_key/jsbn
|
* @requires crypto/public_key/jsbn
|
||||||
* @requires crypto/random
|
* @requires crypto/random
|
||||||
|
@ -27,6 +28,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
import BN from 'bn.js';
|
||||||
import { RSA_RAW } from 'asmcrypto.js';
|
import { RSA_RAW } from 'asmcrypto.js';
|
||||||
import BigInteger from './jsbn';
|
import BigInteger from './jsbn';
|
||||||
import random from '../random';
|
import random from '../random';
|
||||||
|
@ -59,7 +61,7 @@ function unblind(t, n) {
|
||||||
return t.multiply(unblinder).mod(n);
|
return t.multiply(unblinder).mod(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function RSA() {
|
export default {
|
||||||
/**
|
/**
|
||||||
* This function uses jsbn Big Num library to decrypt RSA
|
* This function uses jsbn Big Num library to decrypt RSA
|
||||||
* @param m message
|
* @param m message
|
||||||
|
@ -71,7 +73,12 @@ export default function RSA() {
|
||||||
* @param u RSA u as BigInteger
|
* @param u RSA u as BigInteger
|
||||||
* @return {BigInteger} The decrypted value of the message
|
* @return {BigInteger} The decrypted value of the message
|
||||||
*/
|
*/
|
||||||
function decrypt(m, n, e, d, p, q, u) {
|
decrypt: function(m, n, e, d, p, q, u) {
|
||||||
|
const dd = new BN(d);
|
||||||
|
const dp = dd.mod(new BN(p).subn(1)).toArrayLike(Uint8Array); // d mod (p-1)
|
||||||
|
const dq = dd.mod(new BN(q).subn(1)).toArrayLike(Uint8Array); // d mod (q-1)
|
||||||
|
return new BN(RSA_RAW.decrypt(m, [n, e, d, q, p, dq, dp, u]).slice(1)); // FIXME remove slice
|
||||||
|
/*
|
||||||
if (config.rsa_blinding) {
|
if (config.rsa_blinding) {
|
||||||
m = blind(m, n, e);
|
m = blind(m, n, e);
|
||||||
}
|
}
|
||||||
|
@ -89,53 +96,39 @@ export default function RSA() {
|
||||||
}
|
}
|
||||||
t = t.multiply(p).add(xp);
|
t = t.multiply(p).add(xp);
|
||||||
|
|
||||||
// var t = RSA.decrypt(m, [n, e, d, q, p, dq, dp, u]).slice(1)
|
|
||||||
|
|
||||||
if (config.rsa_blinding) {
|
if (config.rsa_blinding) {
|
||||||
t = unblind(t, n);
|
t = unblind(t, n);
|
||||||
}
|
}
|
||||||
return t;
|
return t;
|
||||||
}
|
*/
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* encrypt message
|
* encrypt message
|
||||||
* @param m message as BigInteger
|
* @param m message as BigInteger
|
||||||
* @param e public MPI part as BigInteger
|
|
||||||
* @param n public MPI part as BigInteger
|
* @param n public MPI part as BigInteger
|
||||||
|
* @param e public MPI part as BigInteger
|
||||||
* @return BigInteger
|
* @return BigInteger
|
||||||
*/
|
*/
|
||||||
function encrypt(m, e, n) {
|
encrypt: function(m, n, e) {
|
||||||
return m.modPowInt(e, n);
|
// return m.modPowInt(e, n);
|
||||||
}
|
return RSA_RAW.encrypt(m, [n, e]);
|
||||||
|
},
|
||||||
|
|
||||||
/* Sign and Verify */
|
/* Sign and Verify */
|
||||||
function sign(m, d, n) {
|
sign: function(m, n, e, d) {
|
||||||
return m.modPow(d, n);
|
// return m.modPow(d, n);
|
||||||
// return RSA_RAW.sign(m, [n, e, d]);
|
return RSA_RAW.sign(m, [n, e, d]);
|
||||||
}
|
},
|
||||||
|
|
||||||
function verify(x, e, n) {
|
verify: function(x, n, e) {
|
||||||
return x.modPowInt(e, n);
|
// return x.modPowInt(e, n);
|
||||||
// return RSA_RAW.verify(x, [n, e]);
|
return RSA_RAW.verify(x, [n, e]);
|
||||||
}
|
},
|
||||||
|
|
||||||
// "empty" RSA key constructor
|
|
||||||
|
|
||||||
function KeyObject() {
|
|
||||||
this.n = null;
|
|
||||||
this.e = 0;
|
|
||||||
this.ee = null;
|
|
||||||
this.d = null;
|
|
||||||
this.p = null;
|
|
||||||
this.q = null;
|
|
||||||
this.dmp1 = null;
|
|
||||||
this.dmq1 = null;
|
|
||||||
this.u = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate a new random private key B bits long, using public expt E
|
// Generate a new random private key B bits long, using public expt E
|
||||||
|
|
||||||
function generate(B, E) {
|
generate: function(B, E) {
|
||||||
const webCrypto = util.getWebCryptoAll();
|
const webCrypto = util.getWebCryptoAll();
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -189,6 +182,20 @@ export default function RSA() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// "empty" RSA key constructor
|
||||||
|
|
||||||
|
function KeyObject() {
|
||||||
|
this.n = null;
|
||||||
|
this.e = 0;
|
||||||
|
this.ee = null;
|
||||||
|
this.d = null;
|
||||||
|
this.p = null;
|
||||||
|
this.q = null;
|
||||||
|
this.dmp1 = null;
|
||||||
|
this.dmq1 = null;
|
||||||
|
this.u = null;
|
||||||
|
}
|
||||||
|
|
||||||
function exportKey(keypair) {
|
function exportKey(keypair) {
|
||||||
// export the generated keys as JsonWebKey (JWK)
|
// export the generated keys as JsonWebKey (JWK)
|
||||||
// https://tools.ietf.org/html/draft-ietf-jose-json-web-key-33
|
// https://tools.ietf.org/html/draft-ietf-jose-json-web-key-33
|
||||||
|
@ -263,11 +270,4 @@ export default function RSA() {
|
||||||
resolve(key);
|
resolve(key);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
};
|
||||||
this.encrypt = encrypt;
|
|
||||||
this.decrypt = decrypt;
|
|
||||||
this.verify = verify;
|
|
||||||
this.sign = sign;
|
|
||||||
this.generate = generate;
|
|
||||||
this.keyObject = KeyObject;
|
|
||||||
}
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* @module crypto/signature
|
* @module crypto/signature
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { RSA_RAW } from 'asmcrypto.js';
|
// FIXME wrap rsa.js around this
|
||||||
import publicKey from './public_key';
|
import publicKey from './public_key';
|
||||||
import pkcs1 from './pkcs1';
|
import pkcs1 from './pkcs1';
|
||||||
import util from '../util';
|
import util from '../util';
|
||||||
|
@ -32,7 +32,7 @@ export default {
|
||||||
const m = msg_MPIs[0].toUint8Array();
|
const m = msg_MPIs[0].toUint8Array();
|
||||||
const n = publickey_MPIs[0].toUint8Array();
|
const n = publickey_MPIs[0].toUint8Array();
|
||||||
const e = publickey_MPIs[1].toUint8Array();
|
const e = publickey_MPIs[1].toUint8Array();
|
||||||
const EM = RSA_RAW.verify(m, [n, e]);
|
const EM = publicKey.rsa.verify(m, n, e);
|
||||||
const EM2 = pkcs1.emsa.encode(hash_algo, util.Uint8Array2str(data), n.length);
|
const EM2 = pkcs1.emsa.encode(hash_algo, util.Uint8Array2str(data), n.length);
|
||||||
return util.hexidump(EM) === EM2;
|
return util.hexidump(EM) === EM2;
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,8 @@ export default {
|
||||||
const m = util.hex2Uint8Array(
|
const m = util.hex2Uint8Array(
|
||||||
'00'+pkcs1.emsa.encode(hash_algo, data, n.length) // FIXME remove '00'
|
'00'+pkcs1.emsa.encode(hash_algo, data, n.length) // FIXME remove '00'
|
||||||
);
|
);
|
||||||
return util.Uint8Array2MPI(RSA_RAW.sign(m, [n, e, d]));
|
const signature = publicKey.rsa.sign(m, n, e, d);
|
||||||
|
return util.Uint8Array2MPI(signature);
|
||||||
}
|
}
|
||||||
case 17: {
|
case 17: {
|
||||||
// DSA (Digital Signature Algorithm) [FIPS186] [HAC]
|
// DSA (Digital Signature Algorithm) [FIPS186] [HAC]
|
||||||
|
|
|
@ -182,7 +182,7 @@ PublicKey.prototype.getFingerprint = function () {
|
||||||
} else if (this.version === 3) {
|
} else if (this.version === 3) {
|
||||||
const paramCount = crypto.getPubKeyParamTypes(this.algorithm).length;
|
const paramCount = crypto.getPubKeyParamTypes(this.algorithm).length;
|
||||||
for (let i = 0; i < paramCount; i++) {
|
for (let i = 0; i < paramCount; i++) {
|
||||||
toHash += this.params[i].toBytes();
|
toHash += this.params[i].toString();
|
||||||
}
|
}
|
||||||
this.fingerprint = util.Uint8Array2str(crypto.hash.md5(util.str2Uint8Array(toHash)));
|
this.fingerprint = util.Uint8Array2str(crypto.hash.md5(util.str2Uint8Array(toHash)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,7 +134,7 @@ PublicKeyEncryptedSessionKey.prototype.decrypt = async function (key) {
|
||||||
key.params,
|
key.params,
|
||||||
this.encrypted,
|
this.encrypted,
|
||||||
key.fingerprint
|
key.fingerprint
|
||||||
)).toBytes();
|
)).toString();
|
||||||
|
|
||||||
let checksum;
|
let checksum;
|
||||||
let decoded;
|
let decoded;
|
||||||
|
|
|
@ -44,12 +44,14 @@ import util from '../util';
|
||||||
*/
|
*/
|
||||||
export default function MPI(data) {
|
export default function MPI(data) {
|
||||||
/** An implementation dependent integer */
|
/** An implementation dependent integer */
|
||||||
if (data instanceof BigInteger) {
|
if (data instanceof BN) {
|
||||||
|
this.fromBN(data);
|
||||||
|
} else if (data instanceof BigInteger) {
|
||||||
this.fromBigInteger(data);
|
this.fromBigInteger(data);
|
||||||
} else if (data instanceof BN) {
|
} else if (util.isUint8Array(data)) {
|
||||||
this.fromBytes(util.Uint8Array2str(data.toArrayLike(Uint8Array)));
|
this.fromUint8Array(data);
|
||||||
} else if (util.isString(data)) {
|
} else if (util.isString(data)) {
|
||||||
this.fromBytes(data);
|
this.fromString(data);
|
||||||
} else {
|
} else {
|
||||||
this.data = null;
|
this.data = null;
|
||||||
}
|
}
|
||||||
|
@ -57,8 +59,8 @@ export default function MPI(data) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parsing function for a mpi ({@link https://tools.ietf.org/html/rfc4880#section3.2|RFC 4880 3.2}).
|
* Parsing function for a mpi ({@link https://tools.ietf.org/html/rfc4880#section3.2|RFC 4880 3.2}).
|
||||||
* @param {String} input Payload of mpi data
|
* @param {Uint8Array} input Payload of mpi data
|
||||||
* @param {String} endian Endianness of the payload; 'be' for big-endian and 'le' for little-endian
|
* @param {String} endian Endianness of the payload; 'be' for big-endian or 'le' for little-endian
|
||||||
* @return {Integer} Length of data read
|
* @return {Integer} Length of data read
|
||||||
*/
|
*/
|
||||||
MPI.prototype.read = function (bytes, endian='be') {
|
MPI.prototype.read = function (bytes, endian='be') {
|
||||||
|
@ -81,7 +83,7 @@ MPI.prototype.read = function (bytes, endian='be') {
|
||||||
const bytelen = Math.ceil(bits / 8);
|
const bytelen = Math.ceil(bits / 8);
|
||||||
let payload = bytes.subarray(2, 2 + bytelen);
|
let payload = bytes.subarray(2, 2 + bytelen);
|
||||||
if (endian === 'le') {
|
if (endian === 'le') {
|
||||||
payload = new Uint8Array(payload).reverse();
|
payload = Uint8Array.from(payload).reverse();
|
||||||
}
|
}
|
||||||
const raw = util.Uint8Array2str(payload);
|
const raw = util.Uint8Array2str(payload);
|
||||||
this.fromBytes(raw);
|
this.fromBytes(raw);
|
||||||
|
@ -89,47 +91,58 @@ MPI.prototype.read = function (bytes, endian='be') {
|
||||||
return 2 + bytelen;
|
return 2 + bytelen;
|
||||||
};
|
};
|
||||||
|
|
||||||
MPI.prototype.fromBytes = function (bytes) {
|
/**
|
||||||
this.data = new BigInteger(util.hexstrdump(bytes), 16);
|
* Converts the mpi object to a bytes as specified in
|
||||||
|
* {@link https://tools.ietf.org/html/rfc4880#section-3.2|RFC4880 3.2}
|
||||||
|
* @param {String} endian Endianness of the payload; 'be' for big-endian or 'le' for little-endian
|
||||||
|
* @param {Integer} length Length of the data part of the MPI
|
||||||
|
* @return {Uint8Aray} mpi Byte representation
|
||||||
|
*/
|
||||||
|
MPI.prototype.write = function (endian, length) {
|
||||||
|
return util.Uint8Array2MPI(this.data.toArrayLike(Uint8Array, endian, length));
|
||||||
};
|
};
|
||||||
|
|
||||||
MPI.prototype.toBytes = function () {
|
MPI.prototype.byteLength = function () {
|
||||||
return util.Uint8Array2str(this.toUint8Array());
|
return this.write().length - 2;
|
||||||
};
|
};
|
||||||
|
|
||||||
MPI.prototype.toUint8Array = function () {
|
MPI.prototype.toUint8Array = function () {
|
||||||
return this.write().slice(2);
|
return this.write().slice(2);
|
||||||
};
|
};
|
||||||
|
|
||||||
MPI.prototype.byteLength = function () {
|
MPI.prototype.fromUint8Array = function (bytes) {
|
||||||
return this.toBytes().length;
|
this.data = new BN(bytes);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
MPI.prototype.toString = function () {
|
||||||
* Converts the mpi object to a bytes as specified in {@link https://tools.ietf.org/html/rfc4880#section-3.2|RFC4880 3.2}
|
return util.Uint8Array2str(this.toUint8Array());
|
||||||
* @return {Uint8Aray} mpi Byte representation
|
|
||||||
*/
|
|
||||||
MPI.prototype.write = function () {
|
|
||||||
return util.str2Uint8Array(this.data.toMPI());
|
|
||||||
};
|
};
|
||||||
|
|
||||||
MPI.prototype.toBigInteger = function () {
|
MPI.prototype.fromString = function (str) {
|
||||||
|
this.data = new BN(util.str2Uint8Array(str));
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO remove this
|
||||||
|
MPI.prototype.fromBytes = MPI.prototype.fromString;
|
||||||
|
|
||||||
|
MPI.prototype.toBN = function () {
|
||||||
return this.data.clone();
|
return this.data.clone();
|
||||||
};
|
};
|
||||||
|
|
||||||
MPI.prototype.toBN = function (bn) {
|
MPI.prototype.fromBN = function (bn) {
|
||||||
return new BN(this.write().slice(2));
|
|
||||||
};
|
|
||||||
|
|
||||||
MPI.prototype.fromBigInteger = function (bn) {
|
|
||||||
this.data = bn.clone();
|
this.data = bn.clone();
|
||||||
};
|
};
|
||||||
|
|
||||||
MPI.fromClone = function (clone) {
|
MPI.prototype.toBigInteger = function () {
|
||||||
clone.data.copyTo = BigInteger.prototype.copyTo;
|
return new BigInteger(util.hexidump(this.write()), 16);
|
||||||
const bn = new BigInteger();
|
};
|
||||||
clone.data.copyTo(bn);
|
|
||||||
const mpi = new MPI();
|
MPI.prototype.fromBigInteger = function (bn) {
|
||||||
mpi.data = bn;
|
this.data = new BN(bn.toByteArray());
|
||||||
return mpi;
|
};
|
||||||
|
|
||||||
|
MPI.fromClone = function (clone) {
|
||||||
|
const bn = new BN();
|
||||||
|
clone.data.copy(bn);
|
||||||
|
return new MPI(bn);
|
||||||
};
|
};
|
||||||
|
|
|
@ -171,7 +171,7 @@ describe("Packet", function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Public key encrypted symmetric key packet', function() {
|
it('Public key encrypted symmetric key packet', function() {
|
||||||
const rsa = new openpgp.crypto.publicKey.rsa();
|
const rsa = openpgp.crypto.publicKey.rsa;
|
||||||
const keySize = openpgp.util.getWebCryptoAll() ? 2048 : 512; // webkit webcrypto accepts minimum 2048 bit keys
|
const keySize = openpgp.util.getWebCryptoAll() ? 2048 : 512; // webkit webcrypto accepts minimum 2048 bit keys
|
||||||
|
|
||||||
return rsa.generate(keySize, "10001").then(function(mpiGen) {
|
return rsa.generate(keySize, "10001").then(function(mpiGen) {
|
||||||
|
@ -435,7 +435,7 @@ describe("Packet", function() {
|
||||||
const key = new openpgp.packet.List();
|
const key = new openpgp.packet.List();
|
||||||
key.push(new openpgp.packet.SecretKey());
|
key.push(new openpgp.packet.SecretKey());
|
||||||
|
|
||||||
const rsa = new openpgp.crypto.publicKey.rsa();
|
const rsa = openpgp.crypto.publicKey.rsa;
|
||||||
const keySize = openpgp.util.getWebCryptoAll() ? 2048 : 512; // webkit webcrypto accepts minimum 2048 bit keys
|
const keySize = openpgp.util.getWebCryptoAll() ? 2048 : 512; // webkit webcrypto accepts minimum 2048 bit keys
|
||||||
|
|
||||||
return rsa.generate(keySize, "10001").then(function(mpiGen) {
|
return rsa.generate(keySize, "10001").then(function(mpiGen) {
|
||||||
|
@ -463,7 +463,7 @@ describe("Packet", function() {
|
||||||
it('Writing and verification of a signature packet.', function() {
|
it('Writing and verification of a signature packet.', function() {
|
||||||
const key = new openpgp.packet.SecretKey();
|
const key = new openpgp.packet.SecretKey();
|
||||||
|
|
||||||
const rsa = new openpgp.crypto.publicKey.rsa();
|
const rsa = openpgp.crypto.publicKey.rsa;
|
||||||
const keySize = openpgp.util.getWebCryptoAll() ? 2048 : 512; // webkit webcrypto accepts minimum 2048 bit keys
|
const keySize = openpgp.util.getWebCryptoAll() ? 2048 : 512; // webkit webcrypto accepts minimum 2048 bit keys
|
||||||
|
|
||||||
return rsa.generate(keySize, "10001").then(function(mpiGen) {
|
return rsa.generate(keySize, "10001").then(function(mpiGen) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user