Skip to content

Instantly share code, notes, and snippets.

@nlitsme
Last active July 29, 2022 17:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nlitsme/95bf1ec19f5d4c391bd08d53a168885b to your computer and use it in GitHub Desktop.
Save nlitsme/95bf1ec19f5d4c391bd08d53a168885b to your computer and use it in GitHub Desktop.
spellmaster decryptor
"""
PT/CT pairs
Key expanded Plaintext Ciphertext
AAAAAAAA AAAAAAAA AAAAAAAAAA VTPL?DL?HV
AAAAAAAA AAAAAAAA ABCDEFGHIJKLMNOPQRSTUVWXY VMHTL?QFPCBKSZCJGRZM-EEEZ
AAAA AAAAAAAA BBBB OTBZ
AAAAAAAA AAAAAAAA BBBBBBBBBB OTBZNRZNVA
AAAAAAAA AAAAAAAA BBBBBBBBBBBBBBBB OTBZNRZNVAJRJFVR
AAA AAAAAAAA BBBBBBBBBBBBBBBBBBBBBBBBB OTBZNRZNVAJRJFVRVVOTVBBJB
AAAAAAAA AAAAAAAA BCDEFGHIJKLMNOPQRSTUVWXYZ OLXXXIRHMTOWV-JWBPCGQEIFY
AAAAAAAA AAAAAAAA CDEFGHIJKLMNOPQRSTUVWXYZA GN?HEJTIUVSJOV-ZLVFSUYZEH
AAAAAAAA AAAAAAAA DEFGHIJKLMNOPQRSTUVWXYZAB ABHIRHMYSZVONCRTFEJSUZAHA
AAAAAAAA AAAAAAAA IS-SPELLMASTER-ALIVE? PRQGBETNKDV?EHYE-RELK
BBBBBBBB BBBBBBBB IS-SPELLMASTER-ALIVE? XERHCFUOLZWAFIZF?SM-L
CAT CATCATCA DOGSDOGSDOGSDOGS QLGAGVHPOCWEXCID
CATS CATSCATS DOGSDOGSDOGSDOGS WXCQ-DSUCEKQD-WU
SECRECY SECRECYS CRYPTOMUSEUM-FOREVER LRCHZHE-GQBBSJROQ--R
SECRECY SECRECYS LONG-LIVE-CRYPTOMUSEUM ?HIJVVI-XLXOKRKI?SKIQX
see https://www.reddit.com/r/codes/comments/wa8g4i/cryptomuseum_is_looking_for_help_in_figuring_out/
Code by itsme@xs4all.nl.
https://github.com/nlitsme
"""
def umod28(c):
c %= 28
if c<0: c += 28
return c
def umod26(c):
c %= 26
if c<0: c += 26
return c
def to28(x):
return x.replace('-', '[').replace('?', '\\')
def from28(x):
return x.replace('[', '-').replace('\\', '?')
def smod256(c):
c %= 256
if c<-128: c += 256
if c>127: c -= 256
return c
class SpellMasterCipher:
def __init__(self, key = None):
if key is None:
key = "FRANKLIN"
while len(key) < 8:
key = key + key
self.key = key[:8]
self.DecodeXlate = [ 3, 12, 16, 10, 9, 22, 11, 0, 20, 6, 14, 24, 5, 8, 1, 18, 17, 7, 4, 15, 19, 25, 2, 13, 21, 23, 26, 27 ]
self.EncodeXlate = [ 7, 14, 22, 0, 18, 12, 9, 17, 13, 4, 3, 6, 1, 23, 10, 19, 2, 16, 15, 20, 8, 24, 5, 25, 11, 21, 26, 27 ]
def encode(self, text):
# Convert input text to 0-27 range
word_buf = [ self.EncodeXlate[ord(c)-ord('A')] for c in text ]
# Take copy of the key
tempcode = [ ord(c) for c in self.key ]
# Encrypt the text
result = []
for c in word_buf:
# Calculate key
key = umod26(smod256((sum(tempcode) - 8 * ord('A'))))
# Apply key
result.append( umod26(key - c) )
# Modify key
key = umod26(key + c)
tempcode = tempcode[1:] + [ key ]
return "".join(chr(c+ord('A')) for c in result)
def decode(self, text):
# Convert input text to 0-27 range
word_buf = [ ord(c)-ord('A') for c in text ]
# Take copy of the key
tempcode = [ ord(c) for c in self.key ]
# decrypt the text
result = []
for c in word_buf:
# Calculate key
key = umod26(smod256((sum(tempcode) - 8 * ord('A'))))
# Apply key
result.append( umod26(key - c) )
# Modify key
key = umod26(key + result[-1])
tempcode = tempcode[1:] + [ key ]
# Convert result back to ASCII range
return "".join(chr(self.DecodeXlate[c]+ord('A')) for c in result)
def main():
import argparse
parser = argparse.ArgumentParser(description='spellmaster decrypt')
parser.add_argument('--key', '-k', type=str)
parser.add_argument('--decrypt', '-d', action='store_true')
parser.add_argument('--encrypt', '-e', action='store_true')
parser.add_argument('--sm26', action='store_true', help='code from the patent')
parser.add_argument('textdata', nargs='*', type=str)
args = parser.parse_args()
if not args.sm26:
global umod26
umod26 = umod28 # ... not the prettiest solution here....
sm = SpellMasterCipher(args.key)
for txt in args.textdata:
if not args.sm26:
txt = to28(txt)
if args.decrypt:
res = sm.decode(txt)
else:
res = sm.encode(txt)
if not args.sm26:
res = from28(res)
print(res)
if __name__ == '__main__':
main()
python3 spellmaster.py -e -k AAAAAAAA AAAAAAAAAA
python3 spellmaster.py -e -k AAAAAAAA ABCDEFGHIJKLMNOPQRSTUVWXY
python3 spellmaster.py -e -k AAAA BBBB
python3 spellmaster.py -e -k AAAAAAAA BBBBBBBBBB
python3 spellmaster.py -e -k AAAAAAAA BBBBBBBBBBBBBBBB
python3 spellmaster.py -e -k AAA BBBBBBBBBBBBBBBBBBBBBBBBB
python3 spellmaster.py -e -k AAAAAAAA BCDEFGHIJKLMNOPQRSTUVWXYZ
python3 spellmaster.py -e -k AAAAAAAA CDEFGHIJKLMNOPQRSTUVWXYZA
python3 spellmaster.py -e -k AAAAAAAA DEFGHIJKLMNOPQRSTUVWXYZAB
python3 spellmaster.py -e -k AAAAAAAA IS-SPELLMASTER-ALIVE?
python3 spellmaster.py -e -k BBBBBBBB IS-SPELLMASTER-ALIVE?
python3 spellmaster.py -e -k CAT DOGSDOGSDOGSDOGS
python3 spellmaster.py -e -k CATS DOGSDOGSDOGSDOGS
python3 spellmaster.py -e -k SECRECY CRYPTOMUSEUM-FOREVER
python3 spellmaster.py -e -k SECRECY LONG-LIVE-CRYPTOMUSEUM
python3 spellmaster.py -d -k AAAAAAAA VTPL?DL?HV
python3 spellmaster.py -d -k AAAAAAAA VMHTL?QFPCBKSZCJGRZM-EEEZ
python3 spellmaster.py -d -k AAAA OTBZ
python3 spellmaster.py -d -k AAAAAAAA OTBZNRZNVA
python3 spellmaster.py -d -k AAAAAAAA OTBZNRZNVAJRJFVR
python3 spellmaster.py -d -k AAA OTBZNRZNVAJRJFVRVVOTVBBJB
python3 spellmaster.py -d -k AAAAAAAA OLXXXIRHMTOWV-JWBPCGQEIFY
python3 spellmaster.py -d -k AAAAAAAA GN?HEJTIUVSJOV-ZLVFSUYZEH
python3 spellmaster.py -d -k AAAAAAAA ABHIRHMYSZVONCRTFEJSUZAHA
python3 spellmaster.py -d -k AAAAAAAA PRQGBETNKDV?EHYE-RELK
python3 spellmaster.py -d -k BBBBBBBB XERHCFUOLZWAFIZF?SM-L
python3 spellmaster.py -d -k CAT QLGAGVHPOCWEXCID
python3 spellmaster.py -d -k CATS WXCQ-DSUCEKQD-WU
python3 spellmaster.py -d -k SECRECY LRCHZHE-GQBBSJROQ--R
python3 spellmaster.py -d -k SECRECY ?HIJVVI-XLXOKRKI?SKIQX
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment