## 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
;;

(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))))

(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)

(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.

Pages: 1 2

### 8 Responses to “Diana Cryptosystem”

1. Francesco said

```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')

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)
```
2. […] found this on the […]

3. Paul said

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)
```
4. […] a previous exercise Ben Simon showed us how to use a trigraph for secret communication. For illustration, he used a […]

5. Anish Sharma said

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();
}
for(i=0;i<letter_no;i++)
{
crypt[i]=getche();
}
for(i=0;i<letter_no;i++)
{
newc[i]=dna(line[i],crypt[i]);
}
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;
}
}

6. Michael said

I’m curious how they transmitted numbers via this cipher – presumably just by expanding it to 36 characters?

7. programmingpraxis said

@Michael: The usual answer is to spell out numbers as words. Thus, 227 is encoded as TWO TWO SEVEN.