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