; reversible random number generator

(define (euclid x y)
  (let loop ((a 1) (b 0) (g x) (u 0) (v 1) (w y))
    (if (zero? w) (values a b g)
      (let ((q (quotient g w)))
        (loop u v w (- a (* q u)) (- b (* q v)) (- g (* q w)))))))

(define (inverse x m)
  (if (not (= (gcd x m) 1))
      (error 'inverse "divisor must be coprime to modulus")
      (call-with-values
        (lambda () (euclid x m))
        (lambda (a b g) (modulo a m)))))

(define next #f)
(define prev #f)

(let ((a 69069) (c 1234567) (m (expt 2 32)))
  (set! next (lambda (x) (modulo (+ (* a x) c) m)))
  (set! prev (lambda (x) (modulo (* (inverse a m) (- x c)) m))))

(display (next 2718281828)) (newline)
(display (next 3103402651)) (newline)
(display (next 4281062310)) (newline)
(display (prev 1670430837)) (newline)
(display (prev 4281062310)) (newline)
(display (prev 3103402651)) (newline)