|
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