; discrete logarithms

(define (expm b e m)
  (define (m* x y) (modulo (* x y) m))
  (cond ((zero? e) 1)
        ((even? e) (expm (m* b b) (/ e 2) m))
        (else (m* b (expm (m* b b) (/ (- e 1) 2) m)))))

(define (discrete-logarithm x n m)
  (do ((y 0 (+ y 1)))
      ((= (expm x y m) n) y)))

(display (discrete-logarithm 3 13 17)) (newline)
(display (expm 3 4 17)) (newline)