Take a remainder at every step of square-and-multiply and you get modular exponentiation - the operation at the heart of public-key cryptography, and here the crypto-flavored payoff of all the arithmetic you built.
Compute base to the exp modulo m, reducing after every multiply so the numbers stay small.
Modular exponentiation is square-and-multiply with a Mod after every
multiplication. That one change is what makes it practical: without it, base^exp
would balloon to thousands of digits before the final remainder; with it, every
intermediate stays below the modulus, so the numbers never grow. The Euclidean
remainder from the division chapter - always non-negative - is exactly what this
needs.
This is the payoff the whole library was quietly building toward. Raising a number to
a huge power modulo another number is the core primitive of RSA and Diffie-Hellman;
the same PowMod you just wrote, given thousand-bit inputs, is what secures real
connections. 4^13 mod 497 == 445 is the textbook check, and 10^100 mod 7 == 4
shows a googol reduced to a single digit. GCD and the grand capstone are all that
remain.
func PowMod(base BigInt, exp int, m BigInt) BigInt {result := NewFromInt64(1)base, _ = Mod(base, m) // reduce firstfor exp > 0 {if exp&1 == 1 { result, _ = Mod(Mul(result, base), m) }base, _ = Mod(Mul(base, base), m) // square then reduceexp >>= 1}return result}