Added Native RSA Key Generation

This commit is contained in:
Mahrud Sayrafi 2018-02-24 22:00:20 -05:00
parent 168a6b0bb8
commit 9943379cb7
No known key found for this signature in database
GPG Key ID: C24071B956C3245F
3 changed files with 60 additions and 40 deletions

View File

@ -7,16 +7,18 @@
*/
/** @see module:crypto/public_key/rsa */
import rsa from './rsa.js';
import rsa from './rsa';
import prime from './prime';
/** @see module:crypto/public_key/elgamal */
import elgamal from './elgamal.js';
import elgamal from './elgamal';
/** @see module:crypto/public_key/elliptic */
import elliptic from './elliptic';
/** @see module:crypto/public_key/dsa */
import dsa from './dsa.js';
import dsa from './dsa';
export default {
rsa: rsa,
prime: prime,
elgamal: elgamal,
elliptic: elliptic,
dsa: dsa

View File

@ -15,7 +15,7 @@
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
// Algorithms for probabilistic primality testing
// Algorithms for probabilistic prime generation
/**
* @requires bn.js
@ -26,21 +26,32 @@
import BN from 'bn.js';
import random from '../random';
function randomProbablePrime(b) {
let n;
const min = new BN(1).shln(b-1);
do {
n = random.getRandomBN(min, min.shln(1));
if (n.isEven()) {
n.iaddn(1); // force odd
export default {
randomProbablePrime, isProbablePrime, fermat, millerRabin
};
function randomProbablePrime(bits, e) {
const min = new BN(1).shln(bits - 1);
let n = random.getRandomBN(min, min.shln(1));
if (n.isEven()) {
n.iaddn(1); // force odd
}
while (!isProbablePrime(n, e)) {
n.iaddn(2);
// If reached the maximum, go back to the minimum.
if (n.bitLength() > bits) {
n = n.mod(min.shln(1)).iadd(min);
}
} while (!isProbablePrime(n));
// this.dAddOffset(2, 0);
// if (this.bitLength() > b)
// this.subTo(BigInteger.ONE.shiftLeft(b - 1), this);
}
return n;
}
function isProbablePrime(n) {
function isProbablePrime(n, e) {
if (e && !n.subn(1).gcd(e).eqn(1)) {
return false;
}
if (!fermat(n)) {
return false;
}
@ -54,9 +65,9 @@ function isProbablePrime(n) {
* Tests whether n is probably prime or not using Fermat's test with b = 2.
* Fails if b^(n-1) mod n === 1.
*/
export function fermat(n, b) {
function fermat(n, b) {
b = b || new BN(2);
return b.toRed(BN.mont(n)).redPow(n.subn(1)).cmpn(1) === 0;
return b.toRed(BN.mont(n)).redPow(n.subn(1)).fromRed().cmpn(1) === 0;
}
@ -93,7 +104,7 @@ export function fermat(n, b) {
* Tests whether n is probably prime or not using the Miller-Rabin test.
* See HAC Remark 4.28.
*/
export function millerRabin(n, k, cb) {
function millerRabin(n, k, cb) {
var len = n.bitLength();
var red = BN.mont(n);
var rone = new BN(1).toRed(red);

View File

@ -29,9 +29,7 @@
import BN from 'bn.js';
import { RSA } from 'asmcrypto.js/src/rsa/exports-keygen';
import { RSA_RAW } from 'asmcrypto.js/src/rsa/exports-raw';
import { random as asmcrypto_random } from 'asmcrypto.js/src/random/exports';
import prime from './prime';
import random from '../random';
import config from '../../config';
@ -40,6 +38,13 @@ import util from '../../util';
const two = new BN(2);
const zero = new BN(0);
// TODO use this is ../../encoding/base64.js and ./elliptic/{key,curve}.js
function b64toBN(base64url) {
const base64 = base64url.replace(/\-/g, '+').replace(/_/g, '/');
const hex = util.hexstrdump(atob(base64));
return new BN(hex, 16);
}
export default {
/** Create signature
* @param m message as BN
@ -189,25 +194,27 @@ export default {
return key;
}
// TODO use this is ../../encoding/base64.js and ./elliptic/{key,curve}.js
function b64toBN(base64url) {
const base64 = base64url.replace(/\-/g, '+').replace(/_/g, '/');
const hex = util.hexstrdump(atob(base64));
return new BN(hex, 16);
}
while (true) {
let p = prime.randomProbablePrime(B - (B >> 1), E);
let q = prime.randomProbablePrime(B >> 1, E);
// asmcrypto fallback
await asmcrypto_random.seed(await random.getRandomBytes(1024)); // FIXME how much randomness?
key = await RSA.generateKey(B, E.toArrayLike(Uint8Array));
return {
n: new BN(key[0]),
e: new BN(key[1]),
d: new BN(key[2]),
q: new BN(key[3]),
p: new BN(key[4]),
// dq: new BN(key[5]),
// dp: new BN(key[6]),
u: new BN(key[7])
};
if (p.cmp(q) < 0) {
const t = p;
p = q;
q = t;
}
const phi = p.subn(1).mul(q.subn(1));
return {
n: p.mul(q),
e: E,
d: E.invm(phi),
q: q,
p: p,
// dq: d.mod(q.subn(1)),
// dp: d.mod(p.subn(1)),
u: p.invm(q)
};
}
}
};