ExamplesBy LevelBy TopicLearning Paths
828 Intermediate

Modular Exponentiation

Functional Programming

Tutorial Video

Text description (accessibility)

This video demonstrates the "Modular Exponentiation" functional Rust example. Difficulty level: Intermediate. Key concepts covered: Functional Programming. Computing a^b mod m naively multiplies a together b times, requiring O(b) operations — impractical for b = 10^18. Key difference from OCaml: | Aspect | Rust | OCaml |

Tutorial

The Problem

Computing a^b mod m naively multiplies a together b times, requiring O(b) operations — impractical for b = 10^18. Fast modular exponentiation (binary exponentiation / repeated squaring) achieves O(log b) by decomposing the exponent in binary: if b is even, a^b = (a^(b/2))^2; if odd, a^b = a * a^(b-1). This is the core operation in RSA encryption/decryption (a^e mod n, a^d mod n), Diffie-Hellman key exchange, primality testing (Fermat, Miller-Rabin), and computing large Fibonacci numbers via matrix exponentiation. Without it, public-key cryptography would be computationally infeasible.

🎯 Learning Outcomes

  • • Implement binary exponentiation iteratively: scan bits of exponent from LSB to MSB
  • • Understand why O(log b) squarings suffice: the exponent halves at each step
  • • Extend to matrix exponentiation: same algorithm works with matrix multiplication replacing integer multiplication
  • • Apply Fermat's little theorem: a^(p-1) ≡ 1 (mod p) for prime p implies a^(-1) ≡ a^(p-2) (mod p)
  • • Recognize the connection: fast power → modular inverse → modular division
  • Code Example

    #![allow(clippy::all)]
    //! Placeholder

    Key Differences

    AspectRustOCaml
    Overflow handlingExplicit as u128 castInt64 or Zarith
    StyleIterative while loopRecursive or iterative
    Edge casesexp = 0 → returns 1 naturallySame
    Matrix variantGeneric fn mat_pow<T: Mul>Functor over ring type
    Modular inversemod_pow(a, p-2, p) for prime pSame
    Largest safe modulus~9.2 * 10^18 (u64)~4.6 * 10^18 (63-bit int)

    OCaml Approach

    OCaml's mod_pow is naturally recursive: if exp = 0 then 1 else if exp mod 2 = 0 then let h = mod_pow base (exp/2) m in h * h mod m else base * mod_pow base (exp-1) m mod m. For tail-recursive efficiency, the accumulator version threads the result: let rec go acc base exp m. OCaml's Int64.mul handles 64-bit products; for moduli requiring 128-bit, Zarith.mpz is used. Matrix exponentiation extends naturally with OCaml's algebraic types for 2x2 or NxN matrices.

    Full Source

    #![allow(clippy::all)]
    //! Placeholder

    Deep Comparison

    OCaml vs Rust: Modular Exponentiation

    Overview

    See the example.rs and example.ml files for detailed implementations.

    Key Differences

    AspectOCamlRust
    Type systemHindley-MilnerOwnership + traits
    MemoryGCZero-cost abstractions
    MutabilityExplicit refmut keyword
    Error handlingOption/ResultResult<T, E>

    See README.md for detailed comparison.

    Exercises

  • Implement matrix exponentiation to compute the nth Fibonacci number in O(log n) using 2×2 matrix multiplication.
  • Use mod_pow(a, p-2, p) to compute modular inverse and verify a * a^(p-2) ≡ 1 (mod p) for several values.
  • Implement the Fermat primality test using mod_pow: test if a^(n-1) ≡ 1 (mod n) for multiple bases a.
  • Compute 2^(10^18) mod (10^9 + 7) and verify the result using the property 2^p-1 ≡ 1 (mod p) for Mersenne primes.
  • Generalize to a Ring trait and implement mod_pow generically over any ring (integers, matrices, polynomials).
  • Open Source Repos