2023-03-04 00:25:54 +00:00
|
|
|
import { generate_prime } from "./random_primes.js";
|
|
|
|
import { mod_exp, mod_inv } from "./math.js";
|
|
|
|
|
2023-03-04 14:19:26 +00:00
|
|
|
export class RsaPubKey {
|
|
|
|
constructor(n, e) {
|
|
|
|
this.n = n;
|
|
|
|
this.e = e;
|
2023-03-04 00:25:54 +00:00
|
|
|
}
|
|
|
|
|
2023-03-04 10:50:49 +00:00
|
|
|
encrypt(m) {
|
2023-03-04 00:25:54 +00:00
|
|
|
return mod_exp(m, this.e, this.n);
|
|
|
|
}
|
2023-03-04 14:19:26 +00:00
|
|
|
|
|
|
|
toJSON() {
|
|
|
|
return {
|
|
|
|
n: "0x" + this.n.toString(16),
|
|
|
|
e: "0x" + this.e.toString(16),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
static fromJSON(data) {
|
|
|
|
return new RsaPubKey(BigInt(data.n), BigInt(data.e));
|
|
|
|
}
|
2023-03-04 00:25:54 +00:00
|
|
|
}
|
|
|
|
|
2023-03-04 14:19:26 +00:00
|
|
|
class RsaPrivKey {
|
2023-03-04 00:25:54 +00:00
|
|
|
constructor(p, q) {
|
|
|
|
this.n = p * q;
|
2023-03-04 10:50:49 +00:00
|
|
|
this.d = mod_inv(65537n, (q - 1n) * (p - 1n));
|
2023-03-04 00:25:54 +00:00
|
|
|
}
|
|
|
|
|
2023-03-04 10:50:49 +00:00
|
|
|
decrypt(c) {
|
2023-03-04 00:25:54 +00:00
|
|
|
return mod_exp(c, this.d, this.n);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export function generate_rsa_keypair() {
|
2023-03-13 14:52:14 +00:00
|
|
|
let p, q, pubKey, privKey;
|
|
|
|
|
2023-03-04 00:25:54 +00:00
|
|
|
if (window.sessionStorage.getItem("rsa_p") === null) {
|
|
|
|
p = generate_prime();
|
|
|
|
window.sessionStorage.setItem("rsa_p", p);
|
|
|
|
} else {
|
|
|
|
p = BigInt(window.sessionStorage.getItem("rsa_p"));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (window.sessionStorage.getItem("rsa_q") === null) {
|
|
|
|
q = generate_prime();
|
|
|
|
window.sessionStorage.setItem("rsa_q", q);
|
|
|
|
} else {
|
|
|
|
q = BigInt(window.sessionStorage.getItem("rsa_q"));
|
|
|
|
}
|
|
|
|
|
2023-03-04 14:19:26 +00:00
|
|
|
pubKey = new RsaPubKey(p * q, 65537n);
|
|
|
|
privKey = new RsaPrivKey(p, q);
|
2023-03-04 00:25:54 +00:00
|
|
|
|
|
|
|
return { pubKey, privKey };
|
|
|
|
}
|