-
-
Notifications
You must be signed in to change notification settings - Fork 5.8k
Expand file tree
/
Copy pathRSAAlgorithm.js
More file actions
106 lines (91 loc) · 2.36 KB
/
RSAAlgorithm.js
File metadata and controls
106 lines (91 loc) · 2.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// RSAAlgorithm.js
/**
* Generates the greatest common divisor of two numbers.
* @param {number} a - First number.
* @param {number} b - Second number.
* @returns {number} - The GCD of a and b.
*/
export function gcd(a, b) {
if (b === 0) {
return a
}
return gcd(b, a % b)
}
/**
* Calculates modular inverse using Extended Euclidean Algorithm.
* @param {number} e - The number to find inverse for.
* @param {number} phi - The modulus.
* @returns {number} - The modular inverse of e mod phi.
*/
export function modInverse(e, phi) {
let [m0, x0, x1] = [phi, 0, 1]
if (phi === 1) {
return 0
}
while (e > 1) {
let q = Math.floor(e / phi)
;[e, phi] = [phi, e % phi]
;[x0, x1] = [x1 - q * x0, x0]
}
if (x1 < 0) {
x1 += m0
}
return x1
}
/**
* Performs modular exponentiation.
* @param {number} base - Base number.
* @param {number} exponent - Exponent.
* @param {number} modulus - Modulus.
* @returns {number} - (base^exponent) % modulus.
*/
export function modPow(base, exponent, modulus) {
if (modulus === 1) return 0
let result = 1
base = base % modulus
while (exponent > 0) {
if (exponent % 2 === 1) {
result = (result * base) % modulus
}
exponent = Math.floor(exponent / 2)
base = (base * base) % modulus
}
return result
}
/**
* Generates RSA keys.
* @param {number} p - A prime number.
* @param {number} q - A prime number.
* @returns {{publicKey: {e: number, n: number}, privateKey: {d: number, n: number}}}
*/
export function generateKeys(p, q) {
const n = p * q
const phi = (p - 1) * (q - 1)
let e = 2
while (e < phi && gcd(e, phi) !== 1) {
e++
}
const d = modInverse(e, phi)
return {
publicKey: { e, n },
privateKey: { d, n }
}
}
/**
* Encrypts a message with a public key.
* @param {number} message - The message to encrypt (as a number).
* @param {{e: number, n: number}} publicKey - The public key.
* @returns {number} - The encrypted message.
*/
export function encrypt(message, publicKey) {
return modPow(message, publicKey.e, publicKey.n)
}
/**
* Decrypts a cipher with a private key.
* @param {number} cipher - The encrypted message (cipher).
* @param {{d: number, n: number}} privateKey - The private key.
* @returns {number} - The decrypted message.
*/
export function decrypt(cipher, privateKey) {
return modPow(cipher, privateKey.d, privateKey.n)
}