ERIKO-CHAN cipher Nov 14, 2010
ERIKO-CHAN is an obscure and weak symmetric stream cipher. The only reason I know of its existence is first through novalis's writeup in this node, and then a handful of messages about it on a cryptography mailing list. Was it created by a paranoid or mathematically-inclined Japanophile fangirl or boy? Did e intend to erode the foundations of our dichotic gender paradigm through eir transgression, following in the tradition of the great Alan Turing? How many vampires still live in Transylvania? This is becoming a digression.
Key: a twenty digit (or more) random number (whose square root is irrational)
Calculate the square root of the key and, beginning at the first digit after the decimal place, copy each digit which is within the range 0-5 until you have the same number of digits as in your message.
Layer on a transposition cipher to make it more secure.
Don't use the same key more than once. Subtracting two ciphertexts encrypted with the same key yields two plaintexts mashed together, which is not difficult to crack.
I don't know why keys of the form A^n/B^m might be bad, as novalis suggests. As long as their square roots are irrational, they should work fine, right?
It may be possible to recover the key by knowing a short stretch of the square root stream and then using continued fractions. I have no idea if that's true.
This is probably kid sister encryption.
ERIKO-CHAN in Python
import decimal, re def encrypt(message, key): return erikochan(message, key, True) def decrypt(message, key): return erikochan(message, key, False) def erikochan(input, key, encrypt): # normalize the input input = re.sub(r'[^0-9a-z]+', '', input.lower()) # get the key stream k = 1 keystream =  while len(keystream) < len(input) * 2: k += 1 decimal.getcontext().prec = len(input) * 2 * k keystream = str(decimal.Decimal(key).sqrt()).split('.') keystream = map(int, re.sub(r'[6-9]+', '', keystream)) # encrypt k = 0 output = '' for c in input: if c in '0123456789': c = ord(c) - ord('0') + 26 else: c = ord(c) - ord('a') a = c / 6 b = c % 6 if encrypt: a = (a + keystream[k]) % 6 b = (b + keystream[k+1]) % 6 else: a = (a - keystream[k]) % 6 b = (b - keystream[k+1]) % 6 k += 2 c = a * 6 + b if c < 26: c = chr(c + ord('a')) else: c = chr(c - 26 + ord('0')) output += c return output
Taking the Square Root to Arbitrary Precision in Python (the hard way)
import re def sqrt(n): 'yields the number before the decimal place,\ followed by one yield for each digit afterward' n = str(n) assert re.match(r'[0-9]*(\.[0-9]*)?$', n), 'number too funky---pass it as a string without scientific notation, like "123456789.0123456789"' if '.' in n: a, b = n.split('.') else: a, b = n, '' if len(a) % 2: a = '0' + a if len(b) % 2: b += '0' lst = map(int, re.findall('..', a) + re.findall('..', b)) dec = len(a) / 2 # decimal pt is before this element in lst i = 0 r = 0 p = 0 while 1: if i >= len(lst): c = r * 100 else: c = r * 100 + lst[i] i += 1 y = [(x, (20 * p + x) * x) for x in range(10)] # get largest y not exceeding c x, y = [(x, y) for x, y in y if y <= c][-1] p = 10 * p + x r = c - y if i == dec: yield p elif i > dec: yield x if r == 0 and i >= len(lst): return def example(): import math n = 12345678901234567890 g = sqrt(n) print n print math.sqrt(n) for i in range(20): print g.next(), print
- Cryptography-Digest Digest #954---Description of the cipher and some possible weaknesses.
- Cryptography-Digest Digest #973---Discussion of possible weaknesses of ERIKO-CHAN and general cipher-creation habits.
- A Study of the Digits of pi, e and Certain Other Irrational Numbers
links to: Polybius square