documentation for Little Fermat's Thm

This commit is contained in:
Krishna Vedala 2020-05-27 16:09:50 -04:00
parent 4d272210fc
commit 6173a6a701
No known key found for this signature in database
GPG Key ID: BA19ACF8FC8792F7

View File

@ -1,44 +1,59 @@
/* /**
* C++ Program to find the modular inverse using Fermat's Little Theorem. * @file
* Fermat's Little Theorem state that => ϕ(m) = m-1, where m is a prime number. * @brief C++ Program to find the modular inverse using [Fermat's Little
* * Theorem](https://en.wikipedia.org/wiki/Fermat%27s_little_theorem)
* (a * x) 1 mod m.
* x (a^(-1)) mod m.
* *
* Fermat's Little Theorem state that \f[ϕ(m) = m-1\f]
* where \f$m\f$ is a prime number.
* \f{eqnarray*}{
* a \cdot x && 1 \;\text{mod}\; m\\
* x && a^{-1} \;\text{mod}\; m
* \f}
* Using Euler's theorem we can modify the equation. * Using Euler's theorem we can modify the equation.
*\f[
* a^{ϕ(m)} 1 \;\text{mod}\; m
* \f]
* (Where '^' denotes the exponent operator)
* *
* (a^ϕ(m)) 1 mod m (Where '^' denotes the exponent operator) * Here 'ϕ' is Euler's Totient Function. For modular inverse existence 'a' and
* Here 'ϕ' is Euler's Totient Function. For modular inverse existence 'a' and 'm' must be relatively primes numbers. * 'm' must be relatively primes numbers. To apply Fermat's Little Theorem is
* To apply Fermat's Little Theorem is necessary that 'm' must be a prime number. * necessary that 'm' must be a prime number. Generally in many competitive
* Generally in many competitive programming competitions 'm' is either 1000000007 (1e9+7) or 998244353. * programming competitions 'm' is either 1000000007 (1e9+7) or 998244353.
* *
* We considered m as large prime (1e9+7). * We considered m as large prime (1e9+7).
* (a^ϕ(m)) 1 mod m (Using Euler's Theorem) * \f$a^{ϕ(m)} 1 \;\text{mod}\; m\f$ (Using Euler's Theorem)
* ϕ(m) = m-1 using Fermat's Little Theorem. * \f$ϕ(m) = m-1\f$ using Fermat's Little Theorem.
* (a^(m-1)) 1 mod m * \f$a^{m-1} 1 \;\text{mod}\; m\f$
* Now multiplying both side by (a^(-1)). * Now multiplying both side by \f$a^{-1}\f$.
* (a^(m-1)) * (a^(-1)) (a^(-1)) mod m * \f{eqnarray*}{
* (a^(m-2)) (a^(-1)) mod m * a^{m-1} \cdot a^{-1} && a^{-1} \;\text{mod}\; m\\
* a^{m-2} && a^{-1} \;\text{mod}\; m
* \f}
* *
* We will find the exponent using binary exponentiation. Such that the algorithm works in O(log(m)) time. * We will find the exponent using binary exponentiation. Such that the
* algorithm works in \f$O(\log m)\f$ time.
* *
* Example: - * Examples: -
* a = 3 and m = 7 * * a = 3 and m = 7
* (a^(-1) mod m) is equivalent to (a^(m-2) mod m) * * \f$a^{-1} \;\text{mod}\; m\f$ is equivalent to
* (3^(5) mod 7) = (243 mod 7) = 5 * \f$a^{m-2} \;\text{mod}\; m\f$
* Hence, ( 3^(-1) mod 7 ) = 5 * * \f$3^5 \;\text{mod}\; 7 = 243 \;\text{mod}\; 7 = 5\f$
* or ( 3 * 5 ) mod 7 = 1 mod 7 (as a*(a^(-1)) = 1) * <br/>Hence, \f$3^{-1} \;\text{mod}\; 7 = 5\f$
* or \f$3 \times 5 \;\text{mod}\; 7 = 1 \;\text{mod}\; 7\f$
* (as \f$a\times a^{-1} = 1\f$)
*/ */
#include<iostream> #include <iostream>
#include<vector> #include <vector>
// Recursive function to calculate exponent in O(log(n)) using binary exponent. /** Recursive function to calculate exponent in \f$O(\log n)\f$ using binary
* exponent.
*/
int64_t binExpo(int64_t a, int64_t b, int64_t m) { int64_t binExpo(int64_t a, int64_t b, int64_t m) {
a %= m; a %= m;
int64_t res = 1; int64_t res = 1;
while (b > 0) { while (b > 0) {
if (b%2) { if (b % 2) {
res = res * a % m; res = res * a % m;
} }
a = a * a % m; a = a * a % m;
@ -48,13 +63,14 @@ int64_t binExpo(int64_t a, int64_t b, int64_t m) {
return res; return res;
} }
// Prime check in O(sqrt(m)) time. /** Prime check in \f$O(\sqrt{m})\f$ time.
*/
bool isPrime(int64_t m) { bool isPrime(int64_t m) {
if (m <= 1) { if (m <= 1) {
return false; return false;
} else { } else {
for (int i=2; i*i <= m; i++) { for (int64_t i = 2; i * i <= m; i++) {
if (m%i == 0) { if (m % i == 0) {
return false; return false;
} }
} }
@ -62,6 +78,9 @@ bool isPrime(int64_t m) {
return true; return true;
} }
/**
* Main function
*/
int main() { int main() {
int64_t a, m; int64_t a, m;
// Take input of a and m. // Take input of a and m.
@ -71,7 +90,7 @@ int main() {
std::cin >> a >> m; std::cin >> a >> m;
if (isPrime(m)) { if (isPrime(m)) {
std::cout << "The modular inverse of a with mod m is (a^(m-2)) : "; std::cout << "The modular inverse of a with mod m is (a^(m-2)) : ";
std::cout << binExpo(a, m-2, m) << std::endl; std::cout << binExpo(a, m - 2, m) << std::endl;
} else { } else {
std::cout << "m must be a prime number."; std::cout << "m must be a prime number.";
std::cout << std::endl; std::cout << std::endl;