Stream ciphers and bitwise XOR
Math 202 Cryptography
Week 2 Tutorials, 2020

T. Ratliff, Wheaton College
ratliff_thomas@wheatoncollege.edu

Basics of bitwise XOR, one character at a time

Remember that a stream cipher encrypts by XORing the plaintext bits x_i with the key stream bit s_i

Let’s do this for a single plaintext character “E”. 
When we convert “E” to UTF-8, the plaintext will become an 8-bits long since the Latin alphabet has small Unicode values. 
We will need an 8-bit long key stream, so any 8-bit number will do. 
I’ll “randomly” pick s=196

Let’s get the UTF-8 value for “E” and set the value for s

x=ToCharacterCode["E", "UTF-8"]
s={196}

Let’s check the binary versions of x and s

BaseForm[x,2]
BaseForm[s,2]

We encrypt by using XOR

y=BitXor[x,s]

Let’s check by comparing the binary version of y

BaseForm[y,2]

Remember we decrypt the ciphertext the same way we encrypt

plaintext=BitXor[y,s]

And let’s convert back to a letter

FromCharacterCode[plaintext, "UTF-8"]

Apply to a longer string

Let’s apply the same idea to a longer message.
We’ll need a longer key stream.  This one can handle a thousand characters. If you’re curious, I used Mathematica’s pseudorandom number function RandomInteger[ ] to generate this list.

keystream ={41,71,99,35,111,178,198,137,201,242,209,26,142,216,197,87,241,69,61,231,1,39,244,187,58,47,16,156,30,34,23,206,134,222,242,7,184,55,255,72,106,21,60,167,81,94,170,164,33,191,71,5,174,213,82,114,246,60,224,188,174,223,247,119,111,46,171,122,94,5,233,87,35,233,245,120,165,155,220,233,36,46,119,1,64,183,10,59,157,167,108,135,225,23,151,64,223,10,187,248,95,237,29,31,239,174,53,178,151,253,132,106,98,216,82,81,122,187,88,150,169,88,159,186,253,122,23,26,194,242,139,1,150,101,117,122,145,130,224,72,238,140,60,19,125,111,99,71,90,151,14,248,36,196,111,233,204,125,197,233,72,176,225,170,91,178,246,193,193,220,218,92,182,120,107,118,11,77,171,85,217,202,32,126,239,42,224,73,44,137,187,251,253,146,240,43,231,179,1,139,4,13,96,134,40,82,20,95,155,137,241,38,194,247,110,71,231,13,70,61,46,112,139,189,86,56,142,250,125,250,238,104,164,215,194,182,73,37,125,56,147,131,104,208,136,226,216,243,137,226,227,189,140,41,96,88,119,189,87,59,144,159,220,14,230,53,36,56,249,155,184,18,159,47,174,245,85,20,86,190,128,26,189,82,172,192,102,168,67,10,83,4,154,116,154,153,35,144,150,86,235,149,223,45,164,91,17,116,176,153,252,24,225,154,166,254,161,186,134,206,214,220,48,39,40,49,133,170,136,88,84,179,134,225,19,232,111,165,178,217,8,24,233,52,29,220,16,95,165,68,230,186,37,29,99,254,135,32,34,171,130,164,94,198,83,253,119,67,111,106,109,12,79,217,90,192,217,153,149,145,233,179,139,34,127,6,213,231,120,186,154,73,122,167,32,122,128,175,234,83,75,6,225,21,137,245,28,92,82,11,219,236,20,105,206,206,206,49,111,180,84,254,133,194,142,135,71,107,33,90,88,207,65,93,86,10,186,74,237,202,126,100,50,54,197,225,82,123,20,35,148,15,111,141,49,96,83,166,155,149,236,214,103,160,189,133,86,244,115,50,46,91,105,192,78,231,10,4,125,235,215,224,196,219,197,70,203,29,147,245,89,190,170,195,68,176,243,54,177,27,144,79,4,24,253,65,33,32,85,47,70,231,200,105,153,163,21,43,164,250,109,206,151,47,157,74,221,145,81,30,50,161,226,38,55,165,168,182,242,213,37,133,202,74,89,220,8,40,46,107,112,44,46,59,36,86,43,48,103,30,113,232,102,165,134,100,46,247,230,163,183,136,83,100,187,219,92,93,42,248,139,187,253,196,231,63,49,169,197,31,177,202,9,185,169,18,17,61,203,150,28,62,101,225,233,122,100,61,31,225,59,203,213,3,36,120,254,89,210,31,251,104,130,208,235,108,125,251,194,78,84,61,158,239,68,104,152,114,120,70,157,65,60,33,42,33,4,160,82,235,167,158,210,154,166,145,130,197,79,115,149,82,189,94,238,173,113,66,1,147,247,38,223,254,13,93,156,114,204,1,152,169,70,236,48,23,120,162,100,255,233,204,153,124,18,203,247,57,96,81,1,68,237,171,217,126,67,4,54,98,23,213,227,25,35,189,82,238,21,217,126,176,250,66,194,144,55,25,101,2,100,217,38,243,160,43,108,114,67,128,178,46,103,40,11,224,240,32,137,128,248,44,95,156,68,68,236,112,81,248,247,38,243,45,148,102,59,202,254,51,40,128,195,238,54,54,148,198,4,60,33,156,28,253,36,44,67,233,48,226,75,206,160,152,164,222,64,193,252,206,207,179,212,16,15,145,45,2,76,170,251,18,8,230,137,238,57,245,218,89,31,28,34,132,123,130,55,109,253,76,96,246,59,60,21,111,120,255,150,156,49,152,116,43,41,151,80,78,197,1,247,178,81,197,29,177,78,93,67,185,150,139,162,215,31,161,162,207,142,125,57,199,193,225,178,79,139,167,38,228,50,110,83,214,107,38,86,124,244,117,133,37,181,222,218,162,251,71,142,117,80,57,76,29,144,67,152,33,141,57,133,5,34,7,64,55,112,42,161,37,23,191,176,41,95,141,82,14,189,173,185,211,39,86,15,27,191,163,143,124,171,125,208,39,185,141,248,191,253,145,68,205,181,231,144,132,126,55,71,124,77,104,184,139,62,93,43,188,49,186,36,99,152,179,113,67,230,146,124,68,85,120,164,215,149,150,109,182,43,170,159,43,182,6,111,191,228,230,94,55};

Let’s encrypt our favorite message, but we need to adjust the key stream to be the same length as our message.

x=ToCharacterCode["If every porkchop were perfect, we wouldn't have hotdogs.", "UTF-8"]
s=Part[keystream, 1;;Length[x]]

Now we can encrypt

y=BitXor[x,s]

And we can view the binary version.

BaseForm[y,2]

If we were to actually send this, we would need to pad each value to be an 8-bit binary number by adding leading 0’s and then flattening to one list.

Flatten[IntegerDigits[y,2,8]]

In-Class Work

Decipher the following message that was encoded using the keystream defined above. 
Remember that you’ll need to adjust the keystream to be the same length as the ciphertext as we did above when encrypting.

y={111,34,6,79,79,198,174,236,233,144,163,127,235,162,160,119,158,43,29,158,110,82,134,155,92,74,117,232,48,2,67,166,231,170,8427,116,152,64,151,49,74,118,78,200,50,45,138,204,64,201,34,37,198,186,62,23,133,28,137,210,142,171,159,18,2,0}

Now encrypt your own G-rated message in a format similar to y, and post it on the Jamboard frame #8.
Decrypt the messages that others posted.