- Notifications
You must be signed in to change notification settings - Fork 1.6k
/
Copy pathModularMultiplicativeInverse.cs
64 lines (55 loc) · 2.33 KB
/
ModularMultiplicativeInverse.cs
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
usingSystem;
usingSystem.Numerics;
namespaceAlgorithms.ModularArithmetic;
/// <summary>
/// Modular multiplicative inverse: https://en.wikipedia.org/wiki/Modular_multiplicative_inverse.
/// </summary>
publicstaticclassModularMultiplicativeInverse
{
/// <summary>
/// Computes the modular multiplicative inverse of a in Z/nZ, if there is any (i.e. if a and n are coprime).
/// </summary>
/// <param name="a">The number a, of which to compute the multiplicative inverse.</param>
/// <param name="n">The modulus n.</param>
/// <returns>The multiplicative inverse of a in Z/nZ, a value in the interval [0, n).</returns>
/// <exception cref="ArithmeticException">If there exists no multiplicative inverse of a in Z/nZ.</exception>
publicstaticlongCompute(longa,longn)
{
vareeaResult=ExtendedEuclideanAlgorithm.Compute(a,n);
// Check if there is an inverse:
if(eeaResult.Gcd!=1)
{
thrownewArithmeticException($"{a} is not invertible in Z/{n}Z.");
}
// Make sure, inverseOfA (i.e. the bezout coefficient of a) is in the interval [0, n).
varinverseOfA=eeaResult.BezoutA;
if(inverseOfA<0)
{
inverseOfA+=n;
}
returninverseOfA;
}
/// <summary>
/// Computes the modular multiplicative inverse of a in Z/nZ, if there is any (i.e. if a and n are coprime).
/// </summary>
/// <param name="a">The number a, of which to compute the multiplicative inverse.</param>
/// <param name="n">The modulus n.</param>
/// <returns>The multiplicative inverse of a in Z/nZ, a value in the interval [0, n).</returns>
/// <exception cref="ArithmeticException">If there exists no multiplicative inverse of a in Z/nZ.</exception>
publicstaticBigIntegerCompute(BigIntegera,BigIntegern)
{
vareeaResult=ExtendedEuclideanAlgorithm.Compute(a,n);
// Check if there is an inverse:
if(eeaResult.Gcd!=1)
{
thrownewArithmeticException($"{a} is not invertible in Z/{n}Z.");
}
// Make sure, inverseOfA (i.e. the bezout coefficient of a) is in the interval [0, n).
varinverseOfA=eeaResult.BezoutA;
if(inverseOfA<0)
{
inverseOfA+=n;
}
returninverseOfA;
}
}