A friend of mine is taking a cryptography course this semester. One of his current homework problems involves creating ,
, and
values for RSA Encryption. Always one to play the home game when math is involved, I found myself rewriting two snippets of code that I always end up writing any time I do any number-theory related coding.
One of them is simple EXPONENT-MODULO
that takes a base , an exponent
, and a modulus
and returns
. There are more efficient ways to do this, but this one is much faster than the naïve method and quite easy to rewrite every time that I need it. The idea is that when
is odd, you recursively calculate
and return
. When
is even, you recursively calculate
and return
.
(cond
((zerop e) 1)
((evenp e) (let ((a (expt-mod b (/ e 2) m)))
(mod (* a a) m)))
(t (mod (* b (expt-mod b (1- e) m)) m))))
The other snippet of code is a good deal trickier. Every time I need it, I spend way more time than I want to futzing with examples, getting lost in subscripts, etc. So, while I could rewrite the above in a moment, what’s below, I hope I have the search-fu to find this post next time I need it.
If you have a number and some number
which is relatively prime to (shares no factors except for one with)
, then there exists some number
such that
. And, in fact, all such numbers
for a given
differ by a multiple of
, so there is a unique such
.
Another way of saying and
are relatively prime is to say that their greatest common divisor
is one. Besides being the biggest number that divides into both
and
, the
is also the smallest positive number expressible as
for integers
and
. If you keep track of the steps you use when calculating the greatest common divisor (which in this case is
) while using the Euclidean algorithm you can (with enough care) backtrack through the steps and determine
and
for your given
and
.
For example, suppose you had and
. You want to know what
you’d need for
.
The steps in the Euclidean algorithm show:
Working backwards, you can express as a combination of
. Then, you can express
as a combination of
and so on:
Wheee… in my example chosen to be easy to backtrack, the answer comes out to be which is equal to
modulo
. So,
. I picked a lucky number that is its own inverse modulo
. It’s not usually like that. For example,
.
So, anyhow, here’s a function that takes and
and returns two values
and
so that
.
(multiple-value-bind (q r) (truncate n a)
(if (zerop r)
(values 1 0)
(multiple-value-bind (x y) (gcd-as-linear-combination r a)
(values (- y (* q x)) x)))))
Assuming that and
are relatively prime with
, the first value returned is
‘s inverse modulo
.