JavaScript RSA using bn.js, without asmcrypto.js
This commit is contained in:
parent
9943379cb7
commit
7a3a75a7df
|
@ -53,7 +53,6 @@ export default {
|
||||||
let r;
|
let r;
|
||||||
let s;
|
let s;
|
||||||
let t;
|
let t;
|
||||||
// TODO benchmark BN.mont vs BN.red
|
|
||||||
const redp = new BN.red(p);
|
const redp = new BN.red(p);
|
||||||
const redq = new BN.red(q);
|
const redq = new BN.red(q);
|
||||||
const gred = g.toRed(redp);
|
const gred = g.toRed(redp);
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
|
|
||||||
/** @see module:crypto/public_key/rsa */
|
/** @see module:crypto/public_key/rsa */
|
||||||
import rsa from './rsa';
|
import rsa from './rsa';
|
||||||
import prime from './prime';
|
|
||||||
/** @see module:crypto/public_key/elgamal */
|
/** @see module:crypto/public_key/elgamal */
|
||||||
import elgamal from './elgamal';
|
import elgamal from './elgamal';
|
||||||
/** @see module:crypto/public_key/elliptic */
|
/** @see module:crypto/public_key/elliptic */
|
||||||
|
@ -18,7 +17,6 @@ import dsa from './dsa';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
rsa: rsa,
|
rsa: rsa,
|
||||||
prime: prime,
|
|
||||||
elgamal: elgamal,
|
elgamal: elgamal,
|
||||||
elliptic: elliptic,
|
elliptic: elliptic,
|
||||||
dsa: dsa
|
dsa: dsa
|
||||||
|
|
|
@ -29,14 +29,12 @@
|
||||||
|
|
||||||
|
|
||||||
import BN from 'bn.js';
|
import BN from 'bn.js';
|
||||||
import { RSA_RAW } from 'asmcrypto.js/src/rsa/exports-raw';
|
|
||||||
import prime from './prime';
|
import prime from './prime';
|
||||||
import random from '../random';
|
import random from '../random';
|
||||||
import config from '../../config';
|
import config from '../../config';
|
||||||
import util from '../../util';
|
import util from '../../util';
|
||||||
|
|
||||||
const two = new BN(2);
|
const two = new BN(2);
|
||||||
const zero = new BN(0);
|
|
||||||
|
|
||||||
// TODO use this is ../../encoding/base64.js and ./elliptic/{key,curve}.js
|
// TODO use this is ../../encoding/base64.js and ./elliptic/{key,curve}.js
|
||||||
function b64toBN(base64url) {
|
function b64toBN(base64url) {
|
||||||
|
@ -54,11 +52,11 @@ export default {
|
||||||
* @return BN
|
* @return BN
|
||||||
*/
|
*/
|
||||||
sign: function(m, n, e, d) {
|
sign: function(m, n, e, d) {
|
||||||
m = m.toArrayLike(Uint8Array);
|
if (n.cmp(m) <= 0) {
|
||||||
n = n.toArrayLike(Uint8Array);
|
throw new Error('Data too large.');
|
||||||
e = e.toArrayLike(Uint8Array);
|
}
|
||||||
d = d.toArrayLike(Uint8Array);
|
const nred = new BN.red(n);
|
||||||
return RSA_RAW.sign(m, [n, e, d]);
|
return m.toRed(nred).redPow(d).toArrayLike(Uint8Array, 'be', n.byteLength());
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -69,10 +67,11 @@ export default {
|
||||||
* @return BN
|
* @return BN
|
||||||
*/
|
*/
|
||||||
verify: function(s, n, e) {
|
verify: function(s, n, e) {
|
||||||
s = s.toArrayLike(Uint8Array);
|
if (n.cmp(s) <= 0) {
|
||||||
n = n.toArrayLike(Uint8Array);
|
throw new Error('Data too large.');
|
||||||
e = e.toArrayLike(Uint8Array);
|
}
|
||||||
return RSA_RAW.verify(s, [n, e]);
|
const nred = new BN.red(n);
|
||||||
|
return s.toRed(nred).redPow(e).toArrayLike(Uint8Array, 'be', n.byteLength());
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -83,10 +82,11 @@ export default {
|
||||||
* @return BN
|
* @return BN
|
||||||
*/
|
*/
|
||||||
encrypt: function(m, n, e) {
|
encrypt: function(m, n, e) {
|
||||||
m = m.toArrayLike(Uint8Array);
|
if (n.cmp(m) <= 0) {
|
||||||
n = n.toArrayLike(Uint8Array);
|
throw new Error('Data too large.');
|
||||||
e = e.toArrayLike(Uint8Array);
|
}
|
||||||
return RSA_RAW.encrypt(m, [n, e]);
|
const nred = new BN.red(n);
|
||||||
|
return m.toRed(nred).redPow(e).toArrayLike(Uint8Array, 'be', n.byteLength());
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -101,37 +101,35 @@ export default {
|
||||||
* @return {BN} The decrypted value of the message
|
* @return {BN} The decrypted value of the message
|
||||||
*/
|
*/
|
||||||
decrypt: function(m, n, e, d, p, q, u) {
|
decrypt: function(m, n, e, d, p, q, u) {
|
||||||
let blinder = zero;
|
if (n.cmp(m) <= 0) {
|
||||||
let unblinder = zero;
|
throw new Error('Data too large.');
|
||||||
|
}
|
||||||
|
const dq = d.mod(q.subn(1)); // d mod (q-1)
|
||||||
|
const dp = d.mod(p.subn(1)); // d mod (p-1)
|
||||||
|
const pred = new BN.red(p);
|
||||||
|
const qred = new BN.red(q);
|
||||||
const nred = new BN.red(n);
|
const nred = new BN.red(n);
|
||||||
|
|
||||||
config.rsa_blinding = false; // FIXME
|
let blinder;
|
||||||
|
let unblinder;
|
||||||
if (config.rsa_blinding) {
|
if (config.rsa_blinding) {
|
||||||
if (unblinder.bitLength() === n.bitLength()) {
|
unblinder = random.getRandomBN(two, n).toRed(nred);
|
||||||
unblinder = unblinder.sqr().mod(n);
|
blinder = unblinder.redInvm().redPow(e);
|
||||||
} else {
|
m = m.toRed(nred).redMul(blinder).fromRed();
|
||||||
unblinder = random.getRandomBN(two, n);
|
|
||||||
}
|
|
||||||
blinder = unblinder.toRed(nred).redInvm().redPow(e).fromRed();
|
|
||||||
m = m.mul(blinder).mod(n);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const dq = d.mod(q.subn(1)).toArrayLike(Uint8Array); // d mod (q-1)
|
const mp = m.toRed(pred).redPow(dp);
|
||||||
const dp = d.mod(p.subn(1)).toArrayLike(Uint8Array); // d mod (p-1)
|
const mq = m.toRed(qred).redPow(dq);
|
||||||
const nn = n.toArrayLike(Uint8Array);
|
const t = mq.redSub(mp.fromRed().toRed(qred));
|
||||||
m = m.toArrayLike(Uint8Array);
|
const h = u.toRed(qred).redMul(t).fromRed();
|
||||||
e = e.toArrayLike(Uint8Array);
|
|
||||||
d = d.toArrayLike(Uint8Array);
|
let result = h.mul(p).add(mp).toRed(nred);
|
||||||
q = q.toArrayLike(Uint8Array);
|
|
||||||
p = p.toArrayLike(Uint8Array);
|
|
||||||
u = u.toArrayLike(Uint8Array);
|
|
||||||
let result = new BN(RSA_RAW.decrypt(m, [nn, e, d, q, p, dq, dp, u]).slice(1)); // FIXME remove slice
|
|
||||||
|
|
||||||
if (config.rsa_blinding) {
|
if (config.rsa_blinding) {
|
||||||
result = result.mul(unblinder).mod(n);
|
result = result.redMul(unblinder);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result.toArrayLike(Uint8Array, 'be', n.byteLength());
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue
Block a user