Skip to content

Instantly share code, notes, and snippets.

@nlitsme
Last active July 29, 2022 17:22
Show Gist options
  • Select an option

  • Save nlitsme/95bf1ec19f5d4c391bd08d53a168885b to your computer and use it in GitHub Desktop.

Select an option

Save nlitsme/95bf1ec19f5d4c391bd08d53a168885b to your computer and use it in GitHub Desktop.

Revisions

  1. nlitsme revised this gist Jul 29, 2022. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion spellmaster.py
    Original file line number Diff line number Diff line change
    @@ -122,7 +122,7 @@ def main():

    if not args.sm26:
    global umod26
    umod26 = umod28
    umod26 = umod28 # ... not the prettiest solution here....

    sm = SpellMasterCipher(args.key)
    for txt in args.textdata:
  2. nlitsme created this gist Jul 29, 2022.
    142 changes: 142 additions & 0 deletions spellmaster.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,142 @@
    """
    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

    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()

    33 changes: 33 additions & 0 deletions testvectors.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,33 @@

    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