home

One Time Pad Trivia

reinhard@finalmedia.de - Fr 17. Jan 01:15:53 CET 2020 - Approximated Reading Time ~30 Minutes

Some trivial XOR Cheatsheet and Codecard Generator Scripts, useable as "computerless" one time pad, with pen and paper as a giveaway for friends.

XOR and ASCII Cheatsheet

You can download this small PDF Cheatsheet to memorize ASCII table and exclusive-or-calculation for nibbles in hexadecimal notation.

Nibble  Hex                                                     +++ Rechenbeispiel +++
-----------      XOR  0 1 2 3 4 5 6 7 8 9 A B C D E F  XOR
0000    0                                                       Beispiel:  Ein Byte in beide Nibble zerlegen            #000000 black
0001    1        0    0 1 2 3 4 5 6 7 8 9 A B C D E F    0      also wenn "8a xor d7"                                   #000080 navy
0010    2        1    1 0 3 2 5 4 7 6 9 8 B A D C F E    1      8 xor d = 5                                             #008000 green
0011    3        2    2 3 0 1 6 7 4 5 A B 8 9 E F C D    2      a xor 7 = d                                             #008080 teal
-----------      3    3 2 1 0 7 6 5 4 B A 9 8 F E D C    3      Gesamtergebnis => 5d
0100    4        4    4 5 6 7 0 1 2 3 C D E F 8 9 A B    4      8a xor d7 = 5d                                          #800000 maroon
0101    5        5    5 4 7 6 1 0 3 2 D C F E 9 8 B A    5                                                              #800080 purple
0110    6        6    6 7 4 5 2 3 0 1 E F C D A B 8 9    6                                                              #808000 olive
0111    7        7    7 6 5 4 3 2 1 0 F E D C B A 9 8    7                                                              #C0C0C0 silver
-----------      8    8 9 A B C D E F 0 1 2 3 4 5 6 7    8
1000    8        9    9 8 B A D C F E 1 0 3 2 5 4 7 6    9         XOR 0 1       AND 0 1        OR 0 1                  #808080 gray
1001    9        A    A B 8 9 E F C D 2 3 0 1 6 7 4 5    A           0 0 1         0 0 0         0 1 1                  #0000FF blue
1010    A        B    B A 9 8 F E D C 3 2 1 0 7 6 5 4    B           1 1 0         1 0 1         1 1 0                  #00FF00 lime
1011    B        C    C D E F 8 9 A B 4 5 6 7 0 1 2 3    C                                                              #00FFFF aqua
-----------      D    D C F E 9 8 B A 5 4 7 6 1 0 3 2    D                                            
1100    C        E    E F C D A B 8 9 6 7 4 5 2 3 0 1    E                                                              #FF0000 red
1101    D        F    F E D C B A 9 8 7 6 5 4 3 2 1 0    F                                                              #FF00FF fuchsia
1110    E                                                                                                               #FFFF00 yellow
1111    F        XOR  0 1 2 3 4 5 6 7 8 9 A B C D E F  XOR                                                              #FFFFFF white
		
	
---------------------------	---------------------------	---------------------------	----------------------------------------
Char	Binary Code	Hex	Char	Binary Code	Hex	Char	Binary Code	Hex	Char	Binary Code	Hexadecimal Code
---------------------------	---------------------------	---------------------------	----------------------------------------
A	0100 0001	41	a	0110 0001	61	 	0010 0000	20	
B	0100 0010	42	b	0110 0010	62		
C	0100 0011	43	c	0110 0011	63	!	0010 0001	21	Deutsche Umlaute in Codepage ISO 8859-1
D	0100 0100	44	d	0110 0100	64	"	0010 0010	22	----------------------------------------
E	0100 0101	45	e	0110 0101	65	#	0010 0011	23	ö	1111 0110	F6
F	0100 0110	46	f	0110 0110	66					Ö	1101 0110	D6
G	0100 0111	47	g	0110 0111	67	(	0010 1000	28	ä	1110 0100	E4
H	0100 1000	48	h	0110 1000	68	)	0010 1001	29	Ä	1100 0100	C4
I	0100 1001	49	i	0110 1001	69					ü	1111 1100	FC
J	0100 1010	4A	j	0110 1010	6A	+	0010 1011	2B	Ü	1101 1100	DC
K	0100 1011	4B	k	0110 1011	6B	,	0010 1100	2C	ß	1101 1111	DF
L	0100 1100	4C	l	0110 1100	6C	-	0010 1101	2D	
M	0100 1101	4D	m	0110 1101	6D	.	0010 1110	2E	
N	0100 1110	4E	n	0110 1110	6E	/	0010 1111	2F	Deutsche Umlaute in UTF 8
O	0100 1111	4F	o	0110 1111	6F					-----------------------------------------
P	0101 0000	50	p	0111 0000	70	:	0011 1010	3A	ö	1100 0011 1011 0110	c3 b6
Q	0101 0001	51	q	0111 0001	71	;	0011 1011	3B	Ö	1100 0011 1001 0110	c3 96
R	0101 0010	52	r	0111 0010	72					ä	1100 0011 1010 0100	c3 a4	
S	0101 0011	53	s	0111 0011	73	?	0011 1111	3F	Ä	1100 0011 1000 0100	c3 84
T	0101 0100	54	t	0111 0100	74					ü	1100 0011 1011 1100	c3 bc
U	0101 0101	55	u	0111 0101	75	0	0011 0000	30	Ü	1100 0011 1001 1100	c3 9c
V	0101 0110	56	v	0111 0110	76	1	0011 0001	31	ß	1100 0011 1001 1111	c3 9f
W	0101 0111	57	w	0111 0111	77	2	0011 0010	32	
X	0101 1000	58	x	0111 1000	78	3	0011 0011	33	Warum hat man sich gerade c3 zur
Y	0101 1001	59	y	0111 1001	79	4	0011 0100	34	Signalisierung der utf8 folge ausgesucht?
Z	0101 1010	60	z	0111 1010	7A	5	0011 0101	35	Weil es binär 1100 0011 schick aussieht.
								6	0011 0110	36	Entspricht ja eigentlich ascii der
								7	0011 0111	37	A-Tilde Glpyhe. Nur die ersten 128 Chars,
								8	0011 1000	38	0-127 also die 7 bit des bytes sind ja
								9	0011 1001	39	für die printable chars genutzt. 
			

Codecard Examples

Important hint for any real world usecase: choose a better random number generator for your keycode. Do NOT USE pseudo random number generator /dev/urandom like in this example. don't use computers at all. use pen, paper and 16 sided dices. xor your random keycode with multiple other random keycodes, to get "better" randomness at all. then use it as key. just for fun.

feel free to use this oneliner to generate some small and convenient one-time-pad codecards for testing purpose, suitable for your wallet.
just generate your pdf file, print it twice, put it in your wallet and give the copy to a friend.

NEVER EVER use a codepage twice!

Method A - Code Cards

the following onliner uses the following tools a2ps, xxd, and ps2pdf from ghostscript

head -c 3120 < /dev/urandom | xxd -ps | \ tr -dc "0-9a-f" | fold -w 2 | \ tr "\n" " " | a2ps --stdin="alice:bob" \ -q -8 --left-footer="" --footer="" \ --header "" --landscape -f 8 -j -o- | \ ps2pdf - codecard_example.pdf

and will generate such a codecard_example.pdf (page format A4 landscape). You'll have to use a separate sheet of paper for encrypting/decrypting.

Method B - Code Sheets

Use text2pdf.c and this oneliner to directly generate a pdf file

tr -dc "0-9A-F" < /dev/urandom | \ head -c 2048 | fold -w 2 | tr "\n" " " | \ ./text2pdf -2 -v24 -c48 -s8 -A4 > codesheet_example.pdf

this will generate a page like this codesheet_example.pdf. print the page twice. keep one, give the copy to your friend. You can directly encrypt and decrypt on this printed page. nibble by nibble, line by line, page by page. The follwing example is using this method.

Encrypting a Message

In a nutshell: Use the codesheet_example.pdf linked above. Use a red pen to write clear text hex nibbles above the black lined keycode. xor each nibble of each byte vertically and write the result with a green pen below the black lined key hex nibbles. then green code is your encrypted message. send it to your friend. you can use any unsecure channel.

Example: You want to encrypt The following Message "Hello Bob. The Weather is nice"

So look at a ASCII-table. Character by Character. This Message in cleartext ascii hex:
48 65 6C 6C 6F 20 42 6F 62 2E 20 54 68 65 20 57 65 61 74 68 65 72 20 69 73 20 6E 69 63 65.

You write this ASCII HEX with a red pen above the black lined keycode hex.

Here, the first line:

H  e  l  l  o     B  o  b  .     T  h  e     W
48 65 6C 6C 6F 20 42 6F 62 2E 20 54 68 65 20 57 	cleartext
93 31 4F 1D D1 0F F1 7D 47 A6 F7 AF 3F 7B AD 37		keycode

now, do the xor boogie. calculate nibble by nibble of each byte vertically:
First byte of the cleartext (48) xored with the first byte of the keycode (93) means
individually xoring the nibbles:

  • First nibble of first Byte (4) to first nibble of first byte of keycode(9): 4 XOR 9 = D
  • Second nibble of first Byte (8) to second nibble of first byte of keycode(3): 8 XOR 3 = B

  • so the first encrypted byte is DB

    Have a Look at the XOR Table. X-Axis and Y-Axis for better understanding:

     XOR  0 1 2 3 4 5 6 7 8 9 A B C D E F  XOR
    
     0    0 1 2 3 4 5 6 7 8 9 A B C D E F    0
     1    1 0 3 2 5 4 7 6 9 8 B A D C F E    1
     2    2 3 0 1 6 7 4 5 A B 8 9 E F C D    2
     3    3 2 1 0 7 6 5 4 B A 9 8 F E D C    3
     4    4 5 6 7 0 1 2 3 C D E F 8 9 A B    4
     5    5 4 7 6 1 0 3 2 D C F E 9 8 B A    5
     6    6 7 4 5 2 3 0 1 E F C D A B 8 9    6
     7    7 6 5 4 3 2 1 0 F E D C B A 9 8    7
     8    8 9 A B C D E F 0 1 2 3 4 5 6 7    8
     9    9 8 B A D C F E 1 0 3 2 5 4 7 6    9
     A    A B 8 9 E F C D 2 3 0 1 6 7 4 5    A
     B    B A 9 8 F E D C 3 2 1 0 7 6 5 4    B
     C    C D E F 8 9 A B 4 5 6 7 0 1 2 3    C
     D    D C F E 9 8 B A 5 4 7 6 1 0 3 2    D
     E    E F C D A B 8 9 6 7 4 5 2 3 0 1    E
     F    F E D C B A 9 8 7 6 5 4 3 2 1 0    F
    
     XOR  0 1 2 3 4 5 6 7 8 9 A B C D E F  XOR
    

    Now we xor the second byte. First Nibble 6 XOR 3 = 5 and second nibble
    5 XOR 1 = 4, resulting in the second encrypted byte 54. and so on...

    H  e  l  l  o     B  o  b  .     T  h  e     W
    48 65 6C 6C 6F 20 42 6F 62 2E 20 54 68 65 20 57 	cleartext
    
    93 31 4F 1D D1 0F F1 7D 47 A6 F7 AF 3F 7B AD 37		keycode
    
    ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓
    
    DB 54 23 71 BE 2F B3 12 25 88 D7 FB 57 1E 8D 60		encrypted
    

    For the whole message this is:

    H  e  l  l  o     B  o  B  .     T  h  e     W
    48 65 6C 6C 6F 20 42 6F 62 2E 20 54 68 65 20 57 	cleartext line 1
    ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻
    93 31 4F 1D D1 0F F1 7D 47 A6 F7 AF 3F 7B AD 37 	keycode
    ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓
    DB 54 23 71 BE 2F B3 12 25 88 D7 FB 57 1E 8D 60		encrypted
    
    e  a  t  h  e  r     i  s     n  i  c  e
    65 61 74 68 65 72 20 69 73 20 6E 69 63 65		cleartext line 2
    ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻		
    82 D5 82 FB 7A C8 43 00 68 E8 38 5E FE 6B 4B 23		keycode
    ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓		
    E7 B4 F6 93 1F BA 63 69 1B C8 56 37 9D 0E		encrypted
    

    So your encrypted message is: DB 54 23 71 BE 2F B3 12 25 88 D7 FB 57 1E 8D 60 E7 B4 F6 93 1F BA 63 69 1B C8 56 37 9D 0E

    Decrypting a Message

    Just like Encrypting, but in reverse. Use a green pen to write the encrypted hex above over the black line of keycode. do the xor nibble boogie and take a red pen to write the clear text hex nibbles below the black lined hex codes.

    DB 54 23 71 BE 2F B3 12 25 88 D7 FB 57 1E 8D 60		encrypted
    ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻
    93 31 4F 1D D1 0F F1 7D 47 A6 F7 AF 3F 7B AD 37 	keycode
    ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓
    48 65 6C 6C 6F 20 42 6F 62 2E 20 54 68 65 20 57 	cleartext line 1
    H  e  l  l  o     B  o  B  .     T  h  e     W
    
    
    E7 B4 F6 93 1F BA 63 69 1B C8 56 37 9D 0E		encrypted
    ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻ ⊻⊻		
    82 D5 82 FB 7A C8 43 00 68 E8 38 5E FE 6B 4B 23		keycode
    ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓ ↓↓		
    65 61 74 68 65 72 20 69 73 20 6E 69 63 65		cleartext line 2
    e  a  t  h  e  r     i  s     n  i  c  e
    
    

    Conclusion

    It is safe, if and because:

  • your key is truly random. (Never use anything else than randomly generated keycode sequence! you can use a 16 sided dice to aquire lots of random 0-F)
  • your key has the same length as the message.
  • you will never use the same key again. throw away the page after decrypting/encrypting. or burn the whole sheet.
  • How to do XOR between two nibbles by hand?

    Math Formular is:

        x xor y = y xor x
        x xor (y xor z) = (x xor y) xor z
        x xor 0 = x
        x xor y xor y = x
        x xor x = 0
        x xor 0xFFFF = not x
    

    Additionally, XOR can be composed using the 3 basic operations (AND, OR, NOT)

        a xor b = (a or b) and ((not a) or (not b))
        a xor b = (a and (not b)) or ((not a) and b)
    

    1. Practical Approach A: Quick HEX-XOR-Boogie by hand, using 3-Hex-Tuples Lookup Table Notation

    You can quickly lookup xor of two hex nibbles using the following 3-tuples list. Memorize the following combinations or use it as a short lookup table:

    -1-	-2-	-3-	-4-	-5-	-6-	-7- 
    123  |	246  |	347  |	48C  |	58D  |	68E  |	78F
    145  |	257  |	356  |	49D  |	59C  |	69F  |	79E
    167  |	28A  |	38B  |	4AE  |	5AF  |	6AC  |	7AD
    189  |	29B  |	39A  |	4BF  |	5BE  |	6BD  |	7BC
    1AB  |	2EC  |	3CF
    1CD  |	2DF  |	3DE
    1EF  |
    
    if x==y then x xor y = 0
    x xor 0 = x  ( and 0 xor x = x)
    

    RULE 1: "Same Hex?> Result is Zero (0)" - Example: So F xor F is 0. 1 xor 1 is 0, 2 xor 2 is 0... and so on... so just remember: same hex? result is 0.

    RULE 2: "Any Zero? Result is the other part" - Example: 0 xor A is A, 4 xor 0 is 4, 7 xor 0 is 7.... so just just remember: any of them is 0, just omit 0 and take the non-zero part as result.

    RULE 3: Any other combination? -> Three-Tuple-Lookup-Method! Example 8 xor 1 is 9.

    8 xor 1? All you have to do: choose the least number, which is 1, and look in column 1 above. pick the tuple "189", since there you'l find 8. so 8 xor 1 is 9, since it is the third and last element in this 3-tuple. This also means: 8 xor 9 is 1. and 9 xor 1 is 8, and 1 xor 8 is 9, and 1 xor 9 is 8, ...

    Example: D xor E is 3. since there is no D or E in lookuptable, begin in column 7, see there is no DE in any tuple, go back to column 6, se there is also no DE, go back to column 5, so there is also no DE, go back to column 4, see there is also no DE, go to column 3 and see there is 3DE, so D xor E is 3. Same for E xor D.

    2. Practical Approach B: Calculate XOR between two HEX Nibbles, using Conversion

    Just convert the Nibble from HEX to Binary Notation, xor them and convert it back to HEX Notation!

    XOR means EXLUSIVE OR, so you can use the nmemonic: "the result is only 1 if there is no part exclusively!". Meaning 0 xor 0 is 0, and 1 xor 1 is 0, since yin and yang are never together. every part IS present exclusively". Another nmemonic:

    "Only if there exists a yin (0) AND a yang (1), the result is fine (1)". So only 1 xor 0 is 1. 0 xor 1 is 1.

    You can also nmemonic "FAIL, if same input!" or another nmemonic: "It just WINS, if there a no TWINS.".

    Just have a look at this so called Truth table for binary logic operation:

    0 xor 0 = 0	input is the same. only yin twins, fail.
    0 xor 1 = 1	input is yin and yang! bingo! no twins. fine.
    1 xor 0 = 1	input is yang any yin! bingo! no twins. fine.
    1 xor 1 = 0	input is the same. only yang twins, fail.
    

    Just Write any HEX Nibble in Binary notation. (Have a look a the cheat sheet table, upper left corner) Example: 2 (0010) xor D (1101) is F (1111)...

    now just do binary xor (from top to bottom) with the following rule: So the result for 2 xor D is.. 0 xor 1 = 1, 0 xor 1 = 1, 1 xor 0 = 1, 0 xor 1 = 1, so 1111, so F.

    2 = 0010
    D = 1101
    --------
        ↓↓↓↓
        1111 = F
    

    Gadgets

    to memorize the xor table. symmetry is clearly recognizable.

    xor.pnm

    P2
    16 16
    16
    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 
    1 0 3 2 5 4 7 6 9 8 11 10 13 12 15 14 
    2 3 0 1 6 7 4 5 10 11 8 9 14 15 12 13 
    3 2 1 0 7 6 5 4 11 10 9 8 15 14 13 12 
    4 5 6 7 0 1 2 3 12 13 14 15 8 9 10 11 
    5 4 7 6 1 0 3 2 13 12 15 14 9 8 11 10 
    6 7 4 5 2 3 0 1 14 15 12 13 10 11 8 9 
    7 6 5 4 3 2 1 0 15 14 13 12 11 10 9 8 
    8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 
    9 8 11 10 13 12 15 14 1 0 3 2 5 4 7 6 
    10 11 8 9 14 15 12 13 2 3 0 1 6 7 4 5 
    11 10 9 8 15 14 13 12 3 2 1 0 7 6 5 4 
    12 13 14 15 8 9 10 11 4 5 6 7 0 1 2 3 
    13 12 15 14 9 8 11 10 5 4 7 6 1 0 3 2 
    14 15 12 13 10 11 8 9 6 7 4 5 2 3 0 1 
    15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
    

    Small utility for XOR Calculation of bytestreams

    You can find sourcecode xor.c right here. this tool will xor stdin or infile against keyfile and will output the xored result to stdout.