Addresses @sanjanarajan's review comments
This commit is contained in:
parent
b518d27ff0
commit
d529edfdda
|
@ -32,7 +32,7 @@ import random from '../random';
|
|||
import config from '../../config';
|
||||
import util from '../../util';
|
||||
|
||||
const two = new BN(2);
|
||||
const one = new BN(1);
|
||||
const zero = new BN(0);
|
||||
|
||||
/*
|
||||
|
@ -72,8 +72,8 @@ export default {
|
|||
// signature shall be recalculated. It is extremely unlikely that r = 0
|
||||
// or s = 0 if signatures are generated properly.
|
||||
while (true) {
|
||||
// TODO confirm this range
|
||||
k = random.getRandomBN(two, q.subn(1)); // returns in [2, q-2]
|
||||
// See Appendix B here: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf
|
||||
k = random.getRandomBN(one, q); // returns in [1, q-1]
|
||||
r = gred.redPow(k).fromRed().toRed(redq); // (g**k mod p) mod q
|
||||
if (zero.cmp(r) === 0) {
|
||||
continue;
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
import BN from 'bn.js';
|
||||
import random from '../random';
|
||||
|
||||
const two = new BN(2);
|
||||
const zero = new BN(0);
|
||||
|
||||
export default {
|
||||
/*
|
||||
|
@ -38,8 +38,8 @@ export default {
|
|||
const mred = m.toRed(redp);
|
||||
const gred = g.toRed(redp);
|
||||
const yred = y.toRed(redp);
|
||||
// TODO confirm this range
|
||||
const k = random.getRandomBN(two, p.subn(1)); // returns in [2, p-2]
|
||||
// See Section 11.5 here: https://crypto.stanford.edu/~dabo/cryptobook/BonehShoup_0_4.pdf
|
||||
const k = random.getRandomBN(zero, p); // returns in [0, p-1]
|
||||
return {
|
||||
c1: gred.redPow(k).fromRed(),
|
||||
c2: yred.redPow(k).redMul(mred).fromRed()
|
||||
|
|
|
@ -75,6 +75,8 @@ function isProbablePrime(n, e, k) {
|
|||
if (!millerRabin(n, k)) {
|
||||
return false;
|
||||
}
|
||||
// TODO implement the Lucas test
|
||||
// See Section C.3.3 here: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -127,16 +129,13 @@ const lowprimes = [
|
|||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
// Adapted on Jan 2018 from version 4.0.1 at https://github.com/indutny/miller-rabin
|
||||
// TODO check this against jsbn's bnpMillerRabin
|
||||
// TODO implement fixed base Miller-Rabin; for instance by writing a function that
|
||||
// picks a number within the given range from a precomputed list of primes.
|
||||
|
||||
/**
|
||||
* Tests whether n is probably prime or not using the Miller-Rabin test.
|
||||
* See HAC Remark 4.28.
|
||||
* @param {BN} n Number to test
|
||||
* @param {Integer} k Optional number of iterations of Miller-Rabin test
|
||||
* @param {Function} w Optional function to generate potential witnesses
|
||||
* @param {BN} n Number to test
|
||||
* @param {Integer} k Optional number of iterations of Miller-Rabin test
|
||||
* @param {Function} rand Optional function to generate potential witnesses
|
||||
* @return {boolean}
|
||||
*/
|
||||
function millerRabin(n, k, rand) {
|
||||
|
@ -159,16 +158,16 @@ function millerRabin(n, k, rand) {
|
|||
let a = rand ? rand() : random.getRandomBN(new BN(2), n1);
|
||||
|
||||
let x = a.toRed(red).redPow(d);
|
||||
if (x.cmp(rone) === 0 || x.cmp(rn1) === 0)
|
||||
if (x.eq(rone) || x.eq(rn1))
|
||||
continue;
|
||||
|
||||
let i;
|
||||
for (i = 1; i < s; i++) {
|
||||
x = x.redSqr();
|
||||
|
||||
if (x.cmp(rone) === 0)
|
||||
if (x.eq(rone))
|
||||
return false;
|
||||
if (x.cmp(rn1) === 0)
|
||||
if (x.eq(rn1))
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -213,6 +213,7 @@ export default {
|
|||
|
||||
// RSA keygen fallback using 40 iterations of the Miller-Rabin test
|
||||
// See https://stackoverflow.com/a/6330138 for justification
|
||||
// Also see section C.3 here: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST
|
||||
let p = prime.randomProbablePrime(B - (B >> 1), E, 40);
|
||||
let q = prime.randomProbablePrime(B >> 1, E, 40);
|
||||
|
||||
|
@ -225,10 +226,10 @@ export default {
|
|||
n: p.mul(q),
|
||||
e: E,
|
||||
d: E.invm(phi),
|
||||
q: q,
|
||||
p: p,
|
||||
// dq: d.mod(q.subn(1)),
|
||||
q: q,
|
||||
// dp: d.mod(p.subn(1)),
|
||||
// dq: d.mod(q.subn(1)),
|
||||
u: p.invm(q)
|
||||
};
|
||||
},
|
||||
|
|
|
@ -108,17 +108,19 @@ export default {
|
|||
}
|
||||
|
||||
let r;
|
||||
const modulus = max.sub(min);
|
||||
const bits = modulus.bitLength();
|
||||
const bytes = modulus.byteLength();
|
||||
const diff = max.sub(min);
|
||||
const bits = diff.bitLength();
|
||||
const bytes = diff.byteLength();
|
||||
|
||||
// Using a while loop is necessary to avoid bias
|
||||
// TODO consider using 64 extra random bits and taking mod
|
||||
// Section B.1.1 here: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf
|
||||
do {
|
||||
r = new BN(this.getRandomBytes(bytes));
|
||||
if (r.bitLength() > bits) {
|
||||
r.ishrn(r.bitLength() - bits);
|
||||
}
|
||||
} while (r.cmp(modulus) >= 0);
|
||||
} while (r.cmp(diff) >= 0);
|
||||
|
||||
return r.iadd(min);
|
||||
},
|
||||
|
|
22
src/key.js
22
src/key.js
|
@ -696,25 +696,31 @@ Key.prototype.verifyPrimaryUser = async function(keys) {
|
|||
return;
|
||||
}
|
||||
const dataToVerify = { userid: user.userId || user.userAttribute, key: primaryKey };
|
||||
// TODO: fix the race condition, this should be a forEach
|
||||
await Promise.all(user.selfCertifications.map(async function(selfCertification) {
|
||||
// TODO replace when Promise.forEach is implemented
|
||||
for (let i = 0; i < user.selfCertifications.length; i++) {
|
||||
const selfCertification = user.selfCertifications[i];
|
||||
// skip if certificate is not the most recent
|
||||
if ((selfCertification.isPrimaryUserID &&
|
||||
selfCertification.isPrimaryUserID < lastPrimaryUserID) ||
|
||||
(!lastPrimaryUserID && selfCertification.created < lastCreated)) {
|
||||
return;
|
||||
}
|
||||
// TODO break apart the .verify/isRevoked/isExpired checks
|
||||
// skip if certificates is not valid
|
||||
if (!(selfCertification.verified || await selfCertification.verify(primaryKey, dataToVerify)) ||
|
||||
(selfCertification.revoked || await user.isRevoked(primaryKey, selfCertification)) ||
|
||||
selfCertification.isExpired()) {
|
||||
// skip if certificates is invalid, revoked, or expired
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
if (!(selfCertification.verified || await selfCertification.verify(primaryKey, dataToVerify))) {
|
||||
return;
|
||||
}
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
if (selfCertification.revoked || await user.isRevoked(primaryKey, selfCertification)) {
|
||||
return;
|
||||
}
|
||||
if (selfCertification.isExpired()) {
|
||||
return;
|
||||
}
|
||||
lastPrimaryUserID = selfCertification.isPrimaryUserID;
|
||||
lastCreated = selfCertification.created;
|
||||
primaryUsers.push(user);
|
||||
}));
|
||||
}
|
||||
}));
|
||||
const user = primaryUsers.pop();
|
||||
const results = !user ? [] : keys ? await user.verifyAllCertifications(primaryKey, keys) :
|
||||
|
|
Loading…
Reference in New Issue
Block a user