#!/usr/bin/guile -s !# ;; ;; mti's Crypto Sweet: Human Typable Shared Secret (System Scheme) ;; (make-passwd.scm) ;; ;; Functional Programming seemed to be orthogonal to system ;; programming where data is passed in /pipelines/ and similar ;; concepts. ;; ;; This software is in the Public Domain as granted by the original ;; author. ;; ;; This implementation creates a human typable shared secret ;; especially for protecting online accounts and it should be used in ;; conjunction with keychains or password managers. It is defined to ;; not use certain special characters which are known to be difficult ;; to find if the keyboard layout in software doesn't match the actual ;; inscriptions on the keys. It is designed to be usable with ;; secondary backups. Its shared secrets have the property of being ;; hard (but not impossible) to communicate by oral speech. They are ;; also hard to memorize especially when you can look at them only for ;; a short time. There might be other algorithms based on the ;; knowledge of the syllable structure of common western (and perhaps ;; other) languages that could produce secure /master passwords/ not ;; be held within keychains and password managers. ;; ;; The magnitude of the space of distinct shared secrets is high ;; enough to be considered secure with current authentication routines ;; in use on the Internet. For the original implementation with 65 ;; characters and 12 positions it should be: (expt 65 12) which is ;; greater than ;; ;; (expt 64 12) => (expt (expt 2 6) 12) => (expt 2 72) ;; ;; You can improve it by adding your own preferred special ;; characters. TODO: It should take a command line argument ;; representing the length of the desired shared secret. ;; ;; Please consider changing the shared secrets (Soup of Letters) to ;; your needs: sometimes they force you to use special characters in ;; passwords although real randomness - as employed by this ;; implementation - allows shared secrets without them. Do not change ;; this implementation but add the needed characters to the final ;; shared secret yourself at some random position. A further useful ;; adaption would be insert spaces but beware that they might be ;; difficult to read on secondary backups. ;; ;; No abbreviations here: I want to see the characters. (define *characters* (append (string->list "ABCDEFGHIJKLMNOPQRSTUVWXYZ") (string->list "abcdefghijklmnopqrstuvwxyz") (string->list "1234567890") (string->list "!,."))) (define *number-of-characters* (length *characters*)) (define *length-of-password* 12) (display "make-passwd: number-of-characters: ") (display *number-of-characters*) (display "; shared secret size: ") (display *length-of-password*) (newline) (define (throw-dices randomness-port) (let throw-dices ((n *length-of-password*)) (if (<= n 0) '() (cons (read-char randomness-port) (throw-dices (- n 1))) ))) (define dices->seed list->string) (display "make-passwd: Throwing Dices") (define randomness-device "/dev/urandom") ; should be non-blocking pool access ;; /call-with-input-file/ opens the input device in text mode but see ;; the description of binary mode: no difference on UNIX systems. If ;; this changes perhaps due to Unicode system libraries we might get a ;; bias into our random data but as we use the dices only as the seed ;; for the randomizer we might get away with it. Please check your ;; system's source code for further information. (define my-dices (call-with-input-file randomness-device throw-dices)) (display " => the seeds have been thrown: #") (display (length my-dices)) (newline) (define (get-new-state) (if (null? my-dices) (display "make-passwd: Oh dear, we failed! --") (let ((dice (car my-dices))) (set! my-dices (cdr my-dices)) (seed->random-state (dices->seed (list dice))) ))) (define (x n) "This procedure is undocumented." (if (<= n 0) '() (cons (random *number-of-characters* (get-new-state)) (x (- n 1))) )) (define (soup n) (map (lambda (index) (list-ref *characters* index)) (x n))) (define (make-passwd) (display "Soup of Letters: ") (display (list->string (soup 12))) (newline)) (make-passwd)