Пример #1
0
    def test_rotor_conv(self, letter, rotor, position, key):
        rotor_list = []
        if position == "left":
            rotor_list.append(rotor)
            rotor_list.append(4)
            rotor_list.append(3)
        elif position == "middle":
            rotor_list.append(4)
            rotor_list.append(rotor)
            rotor_list.append(3)
        else:
            rotor_list.append(4)
            rotor_list.append(3)
            rotor_list.append(rotor)

        machine = enigma.Enigma(rotor_list=rotor_list, user_reflector="B")
        machine.set_key(key)
        out = machine._get_rotor_conv("left", letter)
        back = machine._get_rotor_conv_inv("left", out)
        logger.debug(
            "Key '%s' - Running Rotor Setting: %s        %s  ----->  %s  ------> %s",
            key,
            rotor_list,
            letter,
            out,
            back,
        )
        assert back == letter, CIPHER_FAILED
Пример #2
0
    def test_creaEnigmaOk(self):
        rotor = enigma.Rotor(abecedario, rotor_types['I'][0], rotor_types['I'][1])
        rotor.ini = 'K'
        reflector = enigma.Reflector(conf=UKW)
        maquina = enigma.Enigma(rotores=[rotor], reflector=reflector)

        self.assertEqual(maquina.ini, "A")
        self.assertEqual(rotor.pos_ini, "A")
Пример #3
0
 def test_reflector_conv(self, letter, reflector, key):
     machine = enigma.Enigma(user_reflector=reflector)
     machine.set_key(key)
     out = machine._get_reflector_conv(letter)
     back = machine._get_reflector_conv(out)
     logger.debug(
         "Key '%s' - Running Reflector Setting: %s        %s  ----->  %s  ------> %s",
         key, reflector, letter, out, back)
     assert back == letter, "Cipher->Decipher Failed to Return Initial Letter"
Пример #4
0
 def test_inter_rotor_conv(self, letter, rotor_list, key):
     machine = enigma.Enigma(rotor_list=rotor_list, user_reflector='B')
     machine.set_key(key)
     out = machine._get_inter_rotor_conv('left', 'middle', letter)
     back = machine._get_inter_rotor_conv_inv('middle', 'left', out)
     logger.debug(
         "Key '%s' - Running InterRotor Setting: %s        %s  ----->  %s  ------> %s",
         key, rotor_list, letter, out, back)
     assert back == letter, "Cipher->Decipher Failed to Return Initial Letter"
Пример #5
0
def decrypt_with_key(key):
    engine = enigma.Enigma(rotor.ROTOR_Reflector_A,
                           rotor.ROTOR_I,
                           rotor.ROTOR_II,
                           rotor.ROTOR_III,
                           key=key,
                           plugs="AA BB CC DD EE")

    return engine.encipher(ShakesHorribleMessage)
 def test_letrasiciales(self):
     pos = enigma.Enigma()
     a = "A"
     b = "A"
     c = "B"
     rotora = ["ABC", "BCA"]
     rotorb = ["BCA", "ABC"]
     rotorc = ["CAB", "BAC"]
     self.assertEqual(pos.posicion_inicial(rotora, rotorb, rotorc, a, b, c),
                      ["ABC", "BCA"], ["ACB", "BAC"], ["BAC", "CAB"])
Пример #7
0
    def test_codifica_frase(self):
        rotor1 = enigma.Rotor(abecedario, rotor_types['I'][0], rotor_types['I'][1])
        rotor2 = enigma.Rotor(abecedario, rotor_types['I'][0], rotor_types['I'][1])
        rotor3 = enigma.Rotor(abecedario, rotor_types['I'][0], rotor_types['I'][1])
        reflector = enigma.Reflector(UKW)

        maquina = enigma.Enigma([rotor1, rotor2, rotor3], reflector=reflector, ini='ZAA')
        
        self.assertEqual(maquina.codifica("HOLA"), "LCHD")
        self.assertEqual(maquina.ini, "DAA")
Пример #8
0
    def test_creaEnigmaErrores(self):
        with self.assertRaises(AttributeError) as e:
            rotor = enigma.Rotor(abecedario, rotor_types['I'][0]+'Ñ', rotor_types['I'][1])

        rotor = enigma.Rotor(abecedario, rotor_types['I'][0], rotor_types['I'][1])
        rotor.ini = 'K'
        reflector = enigma.Reflector(conf=['ABC', 'CBA'])

        with self.assertRaises(AttributeError):
            maquina = enigma.Enigma(rotores=[rotor], reflector=reflector)
Пример #9
0
    def test_cambia_ini(self):
        rotor = enigma.Rotor(abecedario, rotor_types['I'][0], rotor_types['I'][1])
        rotor.ini = 'K'
        reflector = enigma.Reflector(conf=UKW)
        maquina = enigma.Enigma(rotores=[rotor], reflector=reflector, ini="C")

        self.assertEqual(maquina.ini, "C")
        self.assertEqual(maquina.rotores[0].pos_ini, "C")

        maquina.ini = "T"
        self.assertEqual(maquina.ini, "T")
        self.assertEqual(maquina.rotores[0].pos_ini, "T")
Пример #10
0
 def test_inter_rotor_conv(self, letter, rotor_list, key):
     machine = enigma.Enigma(rotor_list=rotor_list, user_reflector="B")
     machine.set_key(key)
     out = machine._get_inter_rotor_conv("left", "middle", letter)
     back = machine._get_inter_rotor_conv_inv("middle", "left", out)
     logger.debug(
         "Key '%s' - Running InterRotor Setting: %s        %s  ----->  %s  ------> %s",
         key,
         rotor_list,
         letter,
         out,
         back,
     )
     assert back == letter, CIPHER_FAILED
Пример #11
0
 def test_reflector_conv(self, letter, reflector, key):
     machine = enigma.Enigma(user_reflector=reflector)
     machine.set_key(key)
     out = machine._get_reflector_conv(letter)
     back = machine._get_reflector_conv(out)
     logger.debug(
         "Key '%s' - Running Reflector Setting: %s        %s  ----->  %s  ------> %s",
         key,
         reflector,
         letter,
         out,
         back,
     )
     assert back == letter, CIPHER_FAILED
Пример #12
0
    def run(self) -> None:
        """Run terminal application"""
        self._enigma_type = "M3" if len(self._key) == 3 else "M4"

        _enigma = enigma.Enigma(rotor_list=self._rotors,
                                enigma_type=self._enigma_type,
                                debug="DEBUG")

        self._key = self.key_set_option()

        self._rotors = self.rotor_set_option()

        _ringstellung = self.ringstellung_option()

        self.fetch_phrases(_enigma, _ringstellung)
Пример #13
0
    def fetch_phrases(self, machine: enigma.Enigma,
                      ringstellung: List[int]) -> None:
        """Request user inputs for phrases to encode."""
        self.apply_rsg(ringstellung, machine)

        _input_phrase = ""
        while _input_phrase not in ["quit", "q", "exit"]:
            _input_phrase = input("INPUT: ")
            if _input_phrase not in ["quit", "q", "exit"]:
                if _input_phrase == "reset":
                    enigma_ = enigma.Enigma(
                        rotor_list=self._rotors,
                        enigma_type=self._enigma_type,
                        debug="DEBUG",
                    )
                    enigma_.set_key(self._key)
                    self.apply_rsg(ringstellung, machine)
                print("OUTPUT: {}".format(machine.type_phrase(_input_phrase)))
    def setup_enigma_and_msg(self, len_msg, n_rotors, n_plugs):
        self.charset = string.ascii_lowercase
        self.n_chars = len(self.charset)

        self.reflector = enigma.Swapper(n_positions=self.n_chars)
        self.reflector.assign_random_swaps(n_swaps=self.n_chars // 2, seed=3)

        rotor_seeds = list(range(n_rotors))
        self.rotors = [
            enigma.Rotor(n_positions=self.n_chars, seed=seed) for seed in rotor_seeds
        ]
        self.rotor_positions = n_rotors * [15]

        self.plugboard = enigma.Swapper(n_positions=self.n_chars)
        self.plugboard.assign_random_swaps(n_swaps=n_plugs, seed=41)

        message = (
            "The Enigma machine is a cipher device developed and used in the early- to mid-20th century to protect"
            " commercial, diplomatic, and military communication. It was employed extensively by Nazi Germany during "
            "World War II, in all branches of the German military. The Germans believed, erroneously, that use of the"
            " Enigma machine enabled them to communicate securely and thus enjoy a huge advantage in World War II. "
            "The Enigma machine was considered to be so secure that even the most top-secret messages were enciphered"
            " on its electrical circuits. Enigma has an electromechanical rotor mechanism that scrambles the 26 letters "
            "of the alphabet. In typical use, one person enters text on the Enigma's keyboard and another person writes"
            " down which of 26 lights above the keyboard lights up at each key press. If plain text is entered, the "
            "lit-up letters are the encoded ciphertext. Entering ciphertext transforms it back into readable plaintext. "
            "The rotor mechanism changes the electrical connections between the keys and the lights with each keypress. "
            "The security of the system depends on a set of machine settings that were generally changed daily during the "
            "war, based on secret key lists distributed in advance, and on other settings that were changed for "
            "each message. The receiving station has to know and use the exact settings employed by the transmitting "
            "station to successfully decrypt a message."
        )
        message = message.lower()
        self.message_full = "".join(c for c in message if c.islower())

        encoder = enigma.Enigma(
            self.rotors, self.plugboard, self.reflector, charset=self.charset
        )
        encoder.set_rotor_positions(self.rotor_positions)
        self.message = self.message_full[:len_msg]
        self.encrypted_message = encoder.encode_message(self.message)

        # reset all rotors so MC does not start with a good value
        encoder.set_rotor_positions(n_rotors * [0])
    def test_encrypt_decrypt(self):
        plugboard = enigma.Swapper(n_positions=self.n_chars)
        plugboard.assign_random_swaps(n_swaps=10, seed=41)
        rotor_seeds = [21, 32, 34]
        rotors = [
            enigma.Rotor(n_positions=self.n_chars, seed=seed) for seed in rotor_seeds
        ]
        reflector = enigma.Swapper(n_positions=self.n_chars)
        reflector.assign_random_swaps(n_swaps=self.n_chars // 2, seed=3)

        encoder = enigma.Enigma(rotors, plugboard, reflector, charset=self.charset)
        rotor_positions = [3, 4, 7]

        encoder.set_rotor_positions(rotor_positions)
        encoded_message = encoder.encode_message(self.test_message)
        self.assertNotEqual(encoded_message, self.test_message)

        encoder.set_rotor_positions(rotor_positions)
        decoded_message = encoder.encode_message(encoded_message)
        self.assertEqual(decoded_message, self.test_message)
Пример #16
0
    def test_rotor_conv(self, letter, rotor, position, key):
        rotor_list = []
        if position == 'left':
            rotor_list.append(rotor)
            rotor_list.append(4)
            rotor_list.append(3)
        elif position == 'middle':
            rotor_list.append(4)
            rotor_list.append(rotor)
            rotor_list.append(3)
        else:
            rotor_list.append(4)
            rotor_list.append(3)
            rotor_list.append(rotor)

        machine = enigma.Enigma(rotor_list=rotor_list, user_reflector='B')
        machine.set_key(key)
        out = machine._get_rotor_conv('left', letter)
        back = machine._get_rotor_conv_inv('left', out)
        logger.debug(
            "Key '%s' - Running Rotor Setting: %s        %s  ----->  %s  ------> %s",
            key, rotor_list, letter, out, back)
        assert back == letter, "Cipher->Decipher Failed to Return Initial Letter"
Пример #17
0
    def __init__(self) -> None:
        """Initialise a new instance of the Enigma Terminal Application"""
        _enigma_m3_intro = enigma.Enigma(debug="DEBUG")
        _version = _enigma_m3_intro.version
        self._key: str = ""
        self._rotors: List[int] = []

        if _enigma_m3_intro.is_beta:
            _version += " (BETA)"

        _intro = """
        ===========================================

           WELCOME TO THE PYTHON ENIGMA ENCODER
                        {}

                   Kristian Zarebski

        ===========================================
        Type 'q' or 'quit' to exit.

        """.format(_version)

        print(_intro)
Пример #18
0
def globalSearch(start, end):
    plug = enigma.Plugboard({})
    myenigmas = []
    for i in range(15):
        myenigmas.append(
            enigma.Enigma(rotors=[2, 1, 3], reflector="A", plugboard=plug))
        myenigmas[i].initialization2('AAA', 'AAA')
    offsets = [72, 15, 38, 33, 11, 40, 6, 17, 14, 11, 38, 40, 23, 49, 4]
    found = False
    for a in range(start, end):
        if found:
            break
        for b in range(len(ALPHABET)):
            if found:
                break
            for c in range(len(ALPHABET)):
                if found:
                    break
                for d in range(len(ALPHABET)):
                    for i in range(15):
                        myenigmas[i].set_rotors_step(
                            ALPHABET[a] + ALPHABET[b] + ALPHABET[c],
                            'AA' + ALPHABET[d], [2, 1, 3], offsets[i])

                    for i in range(len(ALPHABET)):
                        #test cycle
                        text1 = myenigmas[0].encryption(ALPHABET[i], False)
                        text1 = myenigmas[1].encryption(text1, False)
                        text1 = myenigmas[2].encryption(text1, False)

                        # and another one
                        text2 = myenigmas[3].encryption(ALPHABET[i], False)
                        text2 = myenigmas[4].encryption(text2, False)

                        #and another
                        text3 = myenigmas[5].encryption(ALPHABET[i], False)
                        text3 = myenigmas[6].encryption(text3, False)
                        text3 = myenigmas[7].encryption(text3, False)
                        text3 = myenigmas[8].encryption(text3, False)

                        #one more cycle
                        text4 = myenigmas[9].encryption(ALPHABET[i], False)
                        text4 = myenigmas[10].encryption(text4, False)

                        #last one
                        text5 = myenigmas[11].encryption(ALPHABET[i], False)
                        text5 = myenigmas[12].encryption(text5, False)
                        text5 = myenigmas[13].encryption(text5, False)
                        text5 = myenigmas[14].encryption(text5, False)
                        if ALPHABET[i] == text1 and ALPHABET[
                                i] == text2 and ALPHABET[
                                    i] == text3 and ALPHABET[
                                        i] == text4 and ALPHABET[i] == text5:
                            found = True
                            print('N connected to ' + ALPHABET[i] +
                                  ' on plugboard')
                            print('Rotors positions: %s%s%s' %
                                  (ALPHABET[a], ALPHABET[b], ALPHABET[c]))
                            print('Rings positions: AA%s' % ALPHABET[d])
                            print(datetime.datetime.now())

    print("End: " + str(datetime.datetime.now()))
Пример #19
0
import enigma

enigma_m3 = enigma.Enigma(debug="DEBUG")
version = enigma_m3.version

if enigma_m3.is_beta:
    version += " (BETA)"

intro = """
===========================================

  WELCOME TO THE PYTHON ENIGMA M3 ENCODER
                  {}
          
           Kristian Zarebski

===========================================
Type 'q' or 'quit' to exit.
              
""".format(
    version
)

inp = ""

print(intro)
while inp not in ["quit", "q"]:
    enigma_m3 = enigma.Enigma(debug="DEBUG")
    enigma_m3.set_key("ARE")
    inp = input("INPUT: ")
    if inp not in ["quit", "q"]:
Пример #20
0
 def setUp(self) -> None:
     self.encryptor = enigma.Enigma(['a', 'e', 'i', 'o', 'y'],
                                    ['y', 'i', 'o', 'a', 'e'])
     self.decryptor = enigma.Enigma(['y', 'i', 'o', 'a', 'e'],
                                    ['a', 'e', 'i', 'o', 'y'])
Пример #21
0
import enigma

enigma_m3 = enigma.Enigma(debug='DEBUG')
version = enigma_m3.version

if enigma_m3.isBeta:
    version += ' (BETA)'

intro = '''
===========================================

  WELCOME TO THE PYTHON ENIGMA M3 ENCODER
                  {}
          
           Kristian Zarebski

===========================================
Type 'q' or 'quit' to exit.
              
'''.format(version)

inp = ''

print(intro)
while inp not in ['quit', 'q']:
    enigma_m3 = enigma.Enigma(debug='DEBUG')
    enigma_m3.set_key('ARE')
    inp = input("INPUT: ")
    if inp not in ['quit', 'q']:
        print("OUTPUT: {}".format(enigma_m3.type_phrase(inp)))
Create and test an Enigma machine encryption and decoding machine

This code is based on the implementation of the Enigma machine in Python 
called pyEnigma by Christophe Goessen (initial author) and Cédric Bonhomme
https://github.com/cedricbonhomme/pyEnigma

Created on Tue Feb  5 12:17:02 2019

@author: uqscha22
"""
import enigma
import rotor

engine = enigma.Enigma(rotor.ROTOR_Reflector_A,
                       rotor.ROTOR_I,
                       rotor.ROTOR_II,
                       rotor.ROTOR_III,
                       key="ABC",
                       plugs="AA BB CC DD EE")

#print(engine)

# Part a)
message = "Hello World"
print("Message:", message)
secret = engine.encipher(message)
print("Encoded Message:", secret)

#Write code to decrypt message below
#HINT: Reuse the code above to do it. You do not need to write a decrypt function.
engine = enigma.Enigma(rotor.ROTOR_Reflector_A,
                       rotor.ROTOR_I,
Пример #23
0
import enigma

machine = enigma.Enigma(enigma.Plugboard.STATIC_WIRING,
                        enigma.Rotor(1, 'A', 'A'), enigma.Rotor(2, 'A', 'A'),
                        enigma.Rotor(3, 'A', 'A'),
                        enigma.Reflector('REFLECTOR_B'))


def test_RotorWiring(rotor_n, rings, pos, fwd_in, rev_in, fwd_out, rev_out):
    rotor = enigma.Rotor(rotor_n, rings, pos)
    if rotor.produceLetterOutput(
            fwd_in) == fwd_out and rotor.produceReverseOutput(
                rev_in) == rev_out:
        print('Test for rotor PASS')
    else:
        print('Test for rotor FAIL')
        print('## CORRECT OUTPUT\n' + fwd_out + '\n' + rev_out +
              '\n## ACTUAL OUTPUT')
        print(rotor.produceLetterOutput(fwd_in))
        print(rotor.produceReverseOutput(fwd_out))


def test_letterToPosition(rotor, letter, good_out):
    t = machine.letterToPosition(rotor, letter)
    if t == good_out:
        print('Test for letterToPosition PASS')
    else:
        print('Test for letterToPosition FAIL')
        print('## CORRECT OUTPUT\n' + str(good_out) + '\n## ACTUAL OUTPUT')
        print(t)
Пример #24
0
import enigma

enigma_m4 = enigma.Enigma(debug="DEBUG",
                          enigma_type="M4",
                          rotor_list=[1, 3, 5, 8])
version = enigma_m4.version

if enigma_m4.is_beta:
    version += " (BETA)"

intro = """
===========================================

  WELCOME TO THE PYTHON ENIGMA M4 ENCODER
                  {}
          
           Kristian Zarebski

===========================================
Type 'q' or 'quit' to exit.
              
""".format(version)

inp = ""

print(intro)
while inp not in ["quit", "q"]:
    enigma_m4 = enigma.Enigma(debug="DEBUG",
                              enigma_type="M4",
                              rotor_list=[1, 3, 5, 8])
    enigma_m4.set_key("LEAR")
Пример #25
0
import enigma
welcome_message = "Witaj w maszynie szyfrującej i deszyfrującej!"
choosing_options = "Wybierz jedną z opcji: \n" \
                   "1 - Szyfrowanie \n" \
                   "2 - Deszyfrowanie \n" \
                   "3 - Wyjscie \n"
print(welcome_message)
user_input = ''

cypher = enigma.Enigma(['a', 'e', 'i', 'o', 'y'], ['y', 'i', 'o', 'a', 'e'])
decypher = enigma.Enigma(['y', 'i', 'o', 'a', 'e'], ['a', 'e', 'i', 'o', 'y'])

while user_input.lower() not in ["wyjscie", "wyjście", "3"]:
    user_input = input(choosing_options)

    if user_input.lower() in ["szyfrowanie", "1"]:
        user_sentence = input("Podaj zdanie do szyfrowania: \n")
        print("Oto twoje zaszyfrowane zdanie: " + cypher.enigmator(user_sentence))
    elif user_input.lower() in ["deszyfrowanie", "2"]:
        user_sentence = input("Podaj zdanie do deszyfrowania: \n")
        print("Oto twoje odszyfrowane zdanie: " + decypher.enigmator(user_sentence))
    elif user_input.lower() in ["wyjscie", "wyjście", "3"]:
        print("Dziękuję za użycie maszyny szyfrującej.\nDo zobaczenia następnym razem!")
    else:
        print("Bledna operacja!")





import random
import tqdm

import enigma

n_messages = 3000
chars_per_message = 256
charset = string.ascii_uppercase
n_chars = len(charset)

plugboard = enigma.Swapper(n_positions=n_chars, n_swaps=10, seed=41)
rotor_seeds = [21, 32, 34]
rotors = [enigma.Rotor(n_positions=n_chars, seed=seed) for seed in rotor_seeds]
reflector = enigma.Swapper(n_positions=n_chars, n_swaps=n_chars // 2, seed=3)

encoder = enigma.Enigma(rotors, plugboard, reflector, charset=charset)
rotor_positions = [3, 4, 7]

messages = [
    "".join(random.choices(charset, k=chars_per_message))
    for _ in range(n_messages)
]
tick = time.time()
for message in tqdm.tqdm(messages):
    encoder.set_rotor_positions(rotor_positions)
    encoded_message = encoder.encode_message(message)
tock = time.time()

avg_time = (tock - tick) / n_messages

print(
Пример #27
0
#!/bin/env python3
"""Crypt text file
usage:
	$ python enigma-file cipher "filename"
	$ python enigma-file decipher "filename" """

import enigma
from sys import argv
(script, todo, filename) = argv
e = enigma.Enigma((0, 0), enigma.w_rotor1, enigma.w_rotor2, enigma.w_reflector,
                  enigma.w_plugboard)
key = enigma.Keyboard()
with open(filename, 'r') as plaintxt:
    lines = plaintxt.readlines()
    lines = [line.strip() for line in lines]  # striping newline character
    for l in lines:
        if todo in ("cipher", 'c'):
            print(key.out_text_cipher(e.cipher(key.input_text(l))))
        if todo in ("decipher", 'd'):
            print(key.out_text_decipher(e.cipher(key.input_text(l))))
Пример #28
0
import enigma

enigma_m3 = enigma.Enigma(debug='DEBUG')
version = enigma_m3.version

if enigma_m3.isBeta:
   version += ' (BETA)'

intro='''
===========================================

  WELCOME TO THE PYTHON ENIGMA 3 ENCODER
                  {}
          
           Kristian Zarebski

===========================================
Type 'q' or 'quit' to exit.
              
'''.format(version)

inp = ''

print(intro)
choice = ''
rotors = [2,3,4]
key  = 'YES'
while choice not in ['y','Y','n','N']:
   choice = input('Set 3 letter key? [y/N] ')
if choice.upper() == 'Y':
    key = input('Enter 3 letter key: ')
Пример #29
0
import enigma

enigma_m4 = enigma.Enigma(debug='DEBUG',
                          enigma_type='M4',
                          rotor_list=[1, 3, 5, 8])
version = enigma_m4.version

if enigma_m4.isBeta:
    version += ' (BETA)'

intro = '''
===========================================

  WELCOME TO THE PYTHON ENIGMA M4 ENCODER
                  {}
          
           Kristian Zarebski

===========================================
Type 'q' or 'quit' to exit.
              
'''.format(version)

inp = ''

print(intro)
while inp not in ['quit', 'q']:
    enigma_m4 = enigma.Enigma(debug='DEBUG',
                              enigma_type='M4',
                              rotor_list=[1, 3, 5, 8])
    enigma_m4.set_key('LEAR')
Пример #30
0
crib = "Hail Shakes!"
crib_substring = "Gdwm Qopjmw!"
print(crib_substring)

##Break the code via brute force search
from itertools import product
all_keys = (''.join(x)
            for x in product(capitalLetters, capitalLetters, capitalLetters))

attempt_key = ''
attempt = crib_substring
N = 0  # number of attempts
for key in all_keys:
    engine = enigma.Enigma(rotor.ROTOR_Reflector_A,
                           rotor.ROTOR_I,
                           rotor.ROTOR_II,
                           rotor.ROTOR_III,
                           key=key,
                           plugs="AA BB CC DD EE")
    attempt = engine.encipher(ShakesHorribleMessage)
    if crib == attempt[-len(crib_substring):]:
        attempt_key = key
        break
    N += 1

#Print the Decoded message
engine = enigma.Enigma(rotor.ROTOR_Reflector_A,
                       rotor.ROTOR_I,
                       rotor.ROTOR_II,
                       rotor.ROTOR_III,
                       key=attempt_key,
                       plugs="AA BB CC DD EE")