How I generate passphrases added by C-Keen on Wed Jun 20 11:11:02 2018

(import foreign)
(use (srfi 1 4 13))

(define (random-bytes len)
  (cond-expand (openbsd:
                (arc4random len))
               (linux:
                (with-input-from-file "/dev/urandom" (lambda () (read-u8vector len))))
               (else
                (with-input-from-file "/dev/random" (lambda () (read-u8vector len))))))
#+openbsd
(define (arc4random len)
  (let ((buf (make-blob len)))
    ((foreign-lambda
      void
      "arc4random_buf"
      (scheme-pointer void)
      size_t) buf len)
    (blob->u8vector buf)))

(define wordlist-file "/usr/share/dict/ngerman")
(define words (with-input-from-file wordlist-file read-lines))
(define number-of-words (length words))
(define entropy-per-word
  (inexact->exact (floor (* (/ (log number-of-words) (log 2)) 100))))


(define (main entropy)
  (let ((needed-words (inexact->exact (ceiling (/ entropy entropy-per-word)))))
    (print "Loaded word list (" wordlist-file ") with " number-of-words " words.")
    (print "Generating a phrase of " needed-words " words with an entropy of " entropy-per-word " bits per word.")
    (let loop ((phrase '())
               (n needed-words))
      (let* ((r (u8vector->list (random-bytes 2)))
             (i (+ (arithmetic-shift (car r) 8) (cadr r))))
        (if (zero? n)
            (print "Phrase: '"(string-join (reverse phrase)) "'")
            (loop (cons (list-ref words (modulo i number-of-words)) phrase) (sub1 n)))))))

(main (string->number (cadr (argv))))