|
1 | 1 | /** |
2 | 2 | * Problem statement and explanation: https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm |
3 | | - * |
| 3 | + * |
4 | 4 | * This algorithm plays an important role for modular arithmetic, and by extension for cyptography algorithms |
5 | | - * |
| 5 | + * |
6 | 6 | * This implementation uses an iterative approach to calculate |
7 | 7 | */ |
8 | 8 |
|
9 | 9 | /** |
10 | | - * |
| 10 | + * |
11 | 11 | * @param {Number} arg1 first argument |
12 | 12 | * @param {Number} arg2 second argument |
13 | 13 | * @returns Array with GCD and first and second Bézout coefficients |
14 | 14 | */ |
15 | 15 | const extendedEuclideanGCD = (arg1, arg2) => { |
16 | | - if(typeof arg1 != 'number' || typeof arg2 != 'number') throw new TypeError('Not a Number'); |
17 | | - if(arg1 < 1 || arg2 < 1) throw new TypeError('Must be positive numbers'); |
18 | | - |
19 | | - // Make the order of coefficients correct, as the algorithm assumes r0 > r1 |
20 | | - if (arg1 < arg2) { |
21 | | - const res = extendedEuclideanGCD(arg2,arg1) |
22 | | - const temp = res[1] |
23 | | - res[1] = res[2] |
24 | | - res[2] = temp |
25 | | - return res; |
26 | | - } |
27 | | - |
28 | | - // At this point arg1 > arg2 |
29 | | - |
30 | | - // Remainder values |
31 | | - let r0 = arg1 |
32 | | - let r1 = arg2 |
33 | | - |
34 | | - // Coefficient1 values |
35 | | - let s0 = 1 |
36 | | - let s1 = 0 |
37 | | - |
38 | | - // Coefficient 2 values |
39 | | - let t0 = 0 |
40 | | - let t1 = 1 |
41 | | - |
42 | | - while(r1 != 0) { |
43 | | - const q = Math.floor(r0 / r1); |
44 | | - |
45 | | - const r2 = r0 - r1*q; |
46 | | - const s2 = s0 - s1*q; |
47 | | - const t2 = t0 - t1*q; |
48 | | - |
49 | | - r0 = r1 |
50 | | - r1 = r2 |
51 | | - s0 = s1 |
52 | | - s1 = s2 |
53 | | - t0 = t1 |
54 | | - t1 = t2 |
55 | | - } |
56 | | - return [r0,s0,t0]; |
| 16 | + if (typeof arg1 !== 'number' || typeof arg2 !== 'number') throw new TypeError('Not a Number') |
| 17 | + if (arg1 < 1 || arg2 < 1) throw new TypeError('Must be positive numbers') |
| 18 | + |
| 19 | + // Make the order of coefficients correct, as the algorithm assumes r0 > r1 |
| 20 | + if (arg1 < arg2) { |
| 21 | + const res = extendedEuclideanGCD(arg2, arg1) |
| 22 | + const temp = res[1] |
| 23 | + res[1] = res[2] |
| 24 | + res[2] = temp |
| 25 | + return res |
| 26 | + } |
| 27 | + |
| 28 | + // At this point arg1 > arg2 |
| 29 | + |
| 30 | + // Remainder values |
| 31 | + let r0 = arg1 |
| 32 | + let r1 = arg2 |
| 33 | + |
| 34 | + // Coefficient1 values |
| 35 | + let s0 = 1 |
| 36 | + let s1 = 0 |
| 37 | + |
| 38 | + // Coefficient 2 values |
| 39 | + let t0 = 0 |
| 40 | + let t1 = 1 |
| 41 | + |
| 42 | + while (r1 != 0) { |
| 43 | + const q = Math.floor(r0 / r1) |
| 44 | + |
| 45 | + const r2 = r0 - r1 * q |
| 46 | + const s2 = s0 - s1 * q |
| 47 | + const t2 = t0 - t1 * q |
| 48 | + |
| 49 | + r0 = r1 |
| 50 | + r1 = r2 |
| 51 | + s0 = s1 |
| 52 | + s1 = s2 |
| 53 | + t0 = t1 |
| 54 | + t1 = t2 |
| 55 | + } |
| 56 | + return [r0, s0, t0] |
57 | 57 | } |
58 | 58 |
|
59 | | -export { extendedEuclideanGCD }; |
| 59 | +export { extendedEuclideanGCD } |
60 | 60 | // ex |
0 commit comments