3.2.3, 3.2.4IAS Networks and CryptographyCore

Monoalphabetic Substitution and Vernam

Apply a complete reversible substitution and a bitwise XOR cipher without confusing their key requirements. The original small examples demonstrate mechanisms, not deployed secure encryption.

35 min Video by Craig'n'Dave Encryption Foundations
100. AQA A Level (7516-7517) SLR13 - 4.5.6 Encryption - Vernam cipherCurated by Kepler, not produced by us. Watch it before the notes below.
Open on YouTube

Before you start

  • Apply a supplied permutation in plaintext-alphabet order and invert it.
  • Align equal-length bit strings and evaluate XOR position by position.

Watch, pause, try

Video by Craig'n'Dave. The shared AQA main video develops Vernam XOR; the companion’s Caesar shift is one special substitution. Pearson requires a general one-to-one monoalphabetic mapping, so use the supplied full alphabet key rather than assume a constant shift. The fixed teaching pads make arithmetic reproducible and do not satisfy one-time-pad secrecy assumptions automatically.

Viewing focus: Encrypt/decrypt a general monoalphabetic substitution

After watching, attempt these questions before opening the answers. You can also use the written lesson below.

After watching 1: Use plaintext alphabet A–Z and the reversed key ZYXWVUTSRQPONMLKJIHGFEDCBA. Encrypt FACE and FEE, then decrypt the first result. Is this key necessarily a Caesar shift, and what visible relationship remains when the same plaintext letter repeats?

Show answer and reasoning

FACE becomes UZXV and FEE becomes UVV. Applying the inverse mapping recovers FACE. The reversed alphabet is a valid one-to-one mapping but not one constant Caesar displacement for all letters. Repeated plaintext letters still produce repeated ciphertext letters under a monoalphabetic key, exposing structure; reversibility does not establish modern cryptographic security.

After watching 2: XOR plaintext 10110 with key 01101. Encrypt a second plaintext 00111 using that same key and compare the XOR of the two ciphertexts with the XOR of the two plaintexts. Why is recovering both messages with the key insufficient evidence of perfect secrecy or authentication?

Show answer and reasoning

The ciphertexts are 11011 and 01010. Their XOR is 10001, equal to 10110 XOR 00111 because the reused key cancels. Recovery demonstrates the arithmetic identity, while key reuse leaks a relation between messages. One-time-pad reasoning also needs an independent uniform secret pad of sufficient length used once; XOR alone supplies no authentication against changes.

What you'll be able to do

  • Encrypt/decrypt a general monoalphabetic substitution
  • Trace Vernam XOR in both directions
  • Explain substitution patterns and one-time-pad assumptions
1

Use a one-to-one alphabet mapping

A monoalphabetic substitution replaces each plaintext symbol with a fixed corresponding ciphertext symbol. To decrypt unambiguously over the chosen alphabet, use a one-to-one permutation: every symbol has exactly one inverse. A Caesar shift is one special case, but a general permutation need not move every letter by the same distance.

The example uses uppercase ASCII A–Z only and key QWERTYUIOPASDFGHJKLZXCVBNM in plaintext-alphabet order. B maps to W, A to Q and D to R, so BAD encrypts as WQR. Repeated plaintext letters still produce repeated ciphertext letters, revealing patterns. A large number of possible substitution keys does not erase the statistical structure of an ordinary language message.

2

Validate the inverse rather than guessing it

The code rejects a key that omits or duplicates an alphabet symbol and rejects input outside its stated alphabet. Decryption reverses the mapping, not the ciphertext string. Spaces, punctuation and lowercase text would need an explicitly extended input policy; silently dropping them would lose information. The example’s restrictions make the reversible domain visible.

Test all twenty-six individual symbols and a whole alphabet round trip. A valid permutation should recover every permitted message exactly. A wrong but reversible mapping can still pass a self-consistent round trip, so also check independent known substitutions such as BAD→WQR. Neither the code nor this key is offered as modern secure storage or communication.

Python 3
ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

def substitute(text, key, decrypt=False):
    if len(key) != 26 or set(key) != set(ALPHABET):
        raise ValueError('Key must be a permutation of uppercase A-Z')
    if any(character not in ALPHABET for character in text):
        raise ValueError('Use uppercase A-Z input only')
    source, target = (key, ALPHABET) if decrypt else (ALPHABET, key)
    mapping = dict(zip(source, target))
    return ''.join(mapping[character] for character in text)

key = 'QWERTYUIOPASDFGHJKLZXCVBNM'
ciphertext = substitute('BAD', key)
print(ciphertext)
print(substitute(ciphertext, key, decrypt=True))
Scroll horizontally to see the full code or table.
An original general substitution over a deliberately restricted alphabet.
3

Apply XOR and state the secrecy conditions

A Vernam XOR mechanism combines matching plaintext/key bits. Repeating XOR with the same key recovers the original because x XOR k XOR k=x. For bits 1001 and key 0110, ciphertext is 1111; applying 0110 again gives 1001. The byte example uses two fixed teaching key bytes to make the arithmetic reproducible.

Perfect-secrecy one-time-pad reasoning needs an independently uniformly random secret key at least as long as the message and no reuse, with the scheme used correctly. XOR alone does not create those properties. Reusing the same pad across two messages leaks a relationship between their plaintexts, and XOR encryption alone does not provide message authentication. Keep text encoding, byte values and the key assumptions separate.

Python 3
def xor_bytes(data, key):
    if len(data) != len(key):
        raise ValueError('Data and key must have equal length')
    return bytes(value ^ mask for value, mask in zip(data, key))

plaintext = b'HI'
key = bytes([42, 7])
ciphertext = xor_bytes(plaintext, key)
print(list(ciphertext))
print(xor_bytes(ciphertext, key).decode('ascii'))
Scroll horizontally to see the full code or table.
A two-byte arithmetic demonstration; these fixed key bytes are not a one-time-pad key-generation scheme.
4

Work through the problem

Attempt the task before opening its worked response. Record each change of state, explain the rule used, and check the result against the original requirements. Code examples labelled Python 3 use that language’s conventions; pseudocode states its own assumptions.

Example 1Encrypt BAD using the stated substitution key.
1Use the fixed alphabet-position mapping.
2B→W, A→Q and D→R.
Answer
WQR; decryption uses the inverse mapping.
Example 2Encrypt 1001 with XOR key 0110, then decrypt.
1Compare corresponding bits: 1⊕0,0⊕1,0⊕1,1⊕0 gives 1111.
21111 XOR 0110 gives 1001.
Answer
Ciphertext 1111; the original 1001 is recovered.

Common mistakes to avoid

Treating a general substitution as necessarily one constant shift.
Use the supplied full permutation and its inverse.
Calling every XOR example an unbreakable one-time pad.
State and check the key-generation and non-reuse assumptions.

Key takeaways

  • A general substitution needs a reversible alphabet permutation.
  • XOR reverses when the same key is applied again.
  • Mechanism demonstrations do not establish modern security.

Explore further

Return to this tomorrow

Close the notes and answer from memory. Revisit any explanation you cannot yet reconstruct.

  • XORing a value twice with the same mask gives:
  • Any fixed repeated XOR key automatically provides perfect secrecy:

Test yourself

Answer a few questions, then review anything you missed.

Next step

Keep practising

Start with the quiz above to check the key ideas. You can also choose another topic from the practice library.

Browse practice topics

Related lessons

All 2 lessons