Playing around with XOR (my fav operation) during the holidays

# cipher design notes:
## purpose?
### cheap single byte keyed stream cipher
### cheaply obfuscate data based on a simple password
### use a simple language with as few lines & dependencies as possible
## internal key setup:
### produce a random byte for every pw byte (KEY IV)
### generate a secret internal state byte for every pw byte (KEY HASH):
#### loop through the each pw byte & mix together its random byte & a counter value
#### set the final looped result as the state byte for that key byte
#### order the operations used to try & reduce getting a null byte output
#### end the internal state byte with the current counter value mixed in (CBC MODE)
## message cipher steps:
### use the looped key counter above as an index to get a key list item
### XOR the message byte with each byte in key item: random byte, pwd byte, state byte
### mix the cipher byte in with the internal state byte (new secret internal state)
### XOR the prior internal state byte with the cipher byte (cipher output)
## notes:
### this does not prevent or detect bit-flipping (integrity with a hash function)
import sys, random
def h(n):
  sys.stdout.write(hex(n).replace("x","")[-2:])
i=0xff; j=0x00; l=len(sys.argv[1]); s=sys.stdin.read()
if (s[:2]=="ff"):
  r=s[2:2+(l*2)]; t=s[2+(l*2):].strip()
  s="".join([chr(int(t[x:x+2],16)) for x in range(0,len(t),2)])
  k=[[int(r[x*2:(x*2)+2],16), ord(sys.argv[1][x])] for x in range(0,l)]
else:
  k=[[random.randint(0x00, 0xff), ord(d)] for d in sys.argv[1]]
  h(i); z=[h(d[0]) for d in k]; r=""
for e in k:
  for d in k:
    i=(((i+j)*(d[0]^d[1]))%256); j=((j+1)%256)
  e.append(i); i=((i+j)%256); j=((j+1)%256)
j=0
for c in s:
  p=ord(c); m=k[j%l]; o=(((p^m[0])^m[1])^m[2]); j=(j+1); n=(j%256)
  if (r==""):
    t=i; i=((k[o%l][0]+o+n)%256); o=(o^t); h(o)
  else:
    d=(p^i); t=i; i=((k[d%l][0]+d+n)%256); o=(o^t); sys.stdout.write(chr(o))

Cipher testing output (Message: 000000, Key: 000000):

a=$(echo '000000' | python ~/tmp/en.py "000000") ; echo "Cipher-Out: [$a]" ; \
k="000000" ; echo -n "Decrypt-Test[$k]: " ; echo "$a" | tr -d '|' | python ~/tmp/en.py "$k" ; \
for x in 1 2 3 ; do
k="00000$x" ; echo -n "Bad-Key-Test[$k]: "
echo "$a" | tr -d '|' | python ~/tmp/en.py "$k" | xxd | sed -e 's/^[^ ]* //' | sed -e 's/  [ ]*/|/g' | sed -e 's/\(..[ |]\)/ \1/g' | tr -s ' '
done
Cipher-Out: [ff372f4ca01971de08925718521c]
Decrypt-Test[000000]: 000000
Bad-Key-Test[000001]: 70 b0 bf f0 cc 98 0e|p......
Bad-Key-Test[000002]: 6c e0 ac c5 9d 59 54|l....YT
Bad-Key-Test[000003]: 5c 50 e0 c3 da a8 1f|\P.....

Leave a comment