Diana Cryptosystem
December 19, 2014
Ben provides two functions: make-pad makes a one-time pad, and tri-lookup enciphers/deciphers a message:
;;
;; Implement a version of One Time Pad encryption.
;; Use a trigraph / diana pad method
;; http://danmorgan76.wordpress.com/2013/09/30/encryption-via-a-one-time-pad/
;; http://home.earthlink.net/~specforces/spdiana.htm
;;
(define (a->i letter)
(- (char->integer letter) 65))
(define (i->a index)
(integer->char (+ 65 index)))
(define (rand-char)
(i->a (random-integer 26)))
(define (range low high)
(if (> low high) '() (cons low (range (+ 1 low) high))))
(define (head items)
(let loop ((i 0) (items items) (accum '()))
(cond ((or (null? items) (= i 5)) (reverse accum))
(else
(loop (+ i 1) (cdr items) (cons (car items) accum))))))
(define (tail items)
(reverse (head (reverse items))))
(define (make-pad rows cols)
(define (make-block)
(apply string (map (lambda (i) (rand-char)) (range 1 5))))
(define (make-row)
(for-each (lambda (i)
(if (> i 1) (display " "))
(display (make-block)))
(range 1 cols)))
(for-each (lambda (i)
(make-row) (newline))
(range 1 rows)))
(define (tri-row i)
(reverse (map (lambda (pos)
(i->a (modulo (- pos i) 26)))
(range 0 25))))
(define (tri-lookup key plain)
(let loop ((key (string->list key))
(plain (string->list plain))
(coded '()))
(cond ((null? plain) (apply string (reverse coded)))
((equal? #\space (car plain))
(loop (cdr key) (cdr plain)
(cons #\space coded)))
(else
(let ((row (a->i (car plain)))
(col (a->i (car key))))
(loop (cdr key) (cdr plain)
(cons (list-ref (tri-row row) col) coded)))))))
Although it’s fine for an exercise, you shouldn’t use this make-pad for any secret communication, as the random-number generator is not cryptographically secure. Ben gives this example:
> (make-pad 4 4) QNQWW BRBSQ GBNSR IZJKA ZRNQX SHEYI UQVTW AETTV EUNBP HSWAS OYSOH IDXRX SXBMN GXKQX HLTAM EBDRG > (define k "ASDFA POUYK") > (tri-lookup k "HELLO WORLD") "SDLJL OXOQM" > (tri-lookup k "SDLJL OXOQM") "HELLO WORLD"
You can run Ben’s program at http://programmingpraxis.codepad.org/U5LJ7AqL.
Haskell
import Control.Monad (replicateM) import System.Random (randomRIO) import Data.Function (on) t a b = let (i,f) = splitAt (d a) ['z','y'..'a'] in head . drop (d b) $ f ++ i where d i = on (-) fromEnum i 'a' mkPad c r = replicateM r . replicateM c . replicateM 5 $ randomRIO ('a', 'z') trans pad msg = zipWith t pad msg main = mkPad 3 2 >>= print >> let otp = "rtlesohpctdgvyx"; mess = "ciaomamma" enc = trans otp mess; tra = trans otp enc in putStrLn ("otp: " ++ otp ++ " enc: " ++ enc ++ " dec: " ++ tra)[…] found this on the […]
In Python.
from string import ascii_uppercase from random import choice def code(t, k): return ascii_uppercase[(25 - ord(k) - ord(t)) % 26] def split5(txt): return " ".join("".join(txt[i:i+5]) for i in range(0, len(txt), 5)) def cgen(txt): for c in txt: if c.isalpha(): yield c def tri_lookup(msg, key): return split5([code(t, k) for t, k in zip(cgen(msg), cgen(key))]) def make_otp(rows=4, columns=4, size=5): output = [] for row in range(rows): o = [choice(ascii_uppercase) for _ in range(size * columns)] output.append(split5(o)) return "\n".join(output) def print_trigraph(): print " " + " ".join(ascii_uppercase) for line in ascii_uppercase: print line + ":", " ".join(code(line, c) for c in ascii_uppercase) otp = make_otp() print otp msg = "HELLO WORLD" enc = tri_lookup(msg, otp) print enc print tri_lookup(enc, otp)[…] a previous exercise Ben Simon showed us how to use a trigraph for secret communication. For illustration, he used a […]
In “C”, the following code can be used. One time pad has to be entered by the user manually though since it is more flexible to the user (i guess so).
#include
#include
void morse (char);
char dna(char, char);
void main()
{
char line[20];
char crypt[20];
char newc[20];
int letter_no,i;
clrscr();
printf(“\n………………………….DIANA CRYPTOSYSTEM……………………….\n”);
printf(“\nEnter the number of letters you want to add and then press Enter:”);
scanf(“%d”,&letter_no);
printf(“\nEnter your Sentence(in block letters. Without Spaces) :\n”);
for(i=0;i<letter_no;i++)
{
line[i]=getche();
}
printf("\nEnter a one time pad (without spaces. Do remember the pad).:\n");
for(i=0;i<letter_no;i++)
{
crypt[i]=getche();
}
for(i=0;i<letter_no;i++)
{
newc[i]=dna(line[i],crypt[i]);
}
printf("\nYour Substitution\n");
for(i=0;i<letter_no;i++)
{
printf("%c",newc[i]);
}
getch();
}
char dna(char ui, char tg)
{
int c1,c2,c3,flag,x=0;
char a,b,c,e;
for(c=65;c<=90;c++)
{
x++;
c1=0;c2=0;c3=0;flag=0;
for(a=65;a=65;b–)
{
c2++;
if(b==tg)
{
flag=1;
break;
}
}
if(flag==0)
{
for(e=90;e>=65;e–)
{
c3++;
if(e==tg)
break;
}
}
if(c1==c2+c3)
return c;
}
}
Reblogged this on Computer geek.
I’m curious how they transmitted numbers via this cipher – presumably just by expanding it to 36 characters?
@Michael: The usual answer is to spell out numbers as words. Thus, 227 is encoded as TWO TWO SEVEN.