Skip to content

FEAT: Add VigenereConverter - #2333

Merged
Roman Lutz (romanlutz) merged 16 commits into
microsoft:mainfrom
diamond8658:feature/vigenere-converter
Aug 11, 2026
Merged

FEAT: Add VigenereConverter#2333
Roman Lutz (romanlutz) merged 16 commits into
microsoft:mainfrom
diamond8658:feature/vigenere-converter

Conversation

@diamond8658

Copy link
Copy Markdown
Contributor

Description

Adds VigenereConverter, a classical polyalphabetic cipher converter that generalizes CaesarConverter using a repeating keyword instead of a fixed shift. Closes #2304.

Follows the existing CaesarConverter/AtbashConverter structure:

  • __init__(self, *, key: str, append_description: bool = False), validates the key is non-empty and ASCII alphabetic
  • _build_identifier() returns a ComponentIdentifier with key as a param
  • convert_async encodes the prompt, with the same append_description behavior rendering vigenere_description.yaml
  • Non-alphabetic characters pass through unchanged and don't consume a position in the key, matching Caesar's handling of digits and punctuation

vigenere_description.yaml cites Handa et al. (arXiv:2402.10601), the paper specifically covering word substitution cipher jailbreaking, rather than the CipherChat paper cited by Caesar/Atbash, since that paper doesn't cover Vigenère.

Per the discussion on #2304, this does not touch pyrit/scenario/scenarios/garak/encoding.py (garak has no corresponding probe) or FoundryTechnique (will be picked up when Foundry's converter set is refreshed separately).

Tests and Documentation

New tests/unit/converter/test_vigenere_converter.py, 13 tests covering basic encoding, case preservation, key case insensitivity, non-alphabetic passthrough (including non-ASCII alphabetic characters, which was a real bug caught during development, see note below), wraparound, append_description, and invalid key handling.

Added VigenereConverter to the existing parametrized fixtures in tests/unit/converter/test_converter.py alongside Caesar/Atbash.

Verified against tests/unit/registry/test_converter_registry.py, confirms the converter is discovered, correctly classified as non-LLM-based, and buildable through the registry.

pyrit/converter/__init__.py updated with the import and __all__ export.

doc/code/converters/1_text_to_text_converters.py updated with a demo line. Ran with jupytext --execute --to notebook doc/code/converters/1_text_to_text_converters.py, all cells including the new one execute cleanly.

Implementation note: the initial version used str.isalpha() to detect letters, which returns True for non-ASCII characters (accented letters, etc.) not present in the cipher alphabet, causing a crash. Fixed by checking ASCII letter membership explicitly. Caesar and Atbash avoid this because they use str.translate(), which passes through unmapped characters silently.

@diamond8658

Copy link
Copy Markdown
Contributor Author

diamond8658 please read the following Contributor License Agreement(CLA). If you agree with the CLA, please reply with the following information.

@microsoft-github-policy-service agree [company="{your company}"]

Options:

  • (default - no company specified) I have sole ownership of intellectual property rights to my Submissions and I am not making Submissions in the course of work for my employer.
@microsoft-github-policy-service agree
  • (when company given) I am making Submissions in the course of work for my employer (or my employer has intellectual property rights in my Submissions by contract or applicable law). I have permission from my employer to make Submissions and enter into this Agreement on behalf of my employer. By signing below, the defined term “You” includes me and my employer.
@microsoft-github-policy-service agree company="Microsoft"

Contributor License Agreement

@microsoft-github-policy-service agree

Copilot AI and others added 2 commits August 6, 2026 11:00
The .py side of 1_text_to_text_converters was updated but the paired
.ipynb was not; jupytext keeps these in lockstep. Adds the import, the
conversion call, its output, and the markdown mention.

Also refreshes the generated modality reference table in
0_converters.ipynb, which now picks up VigenereConverter (and
AcrosticConverter, which was already missing on main).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 4e67eb0e-8f79-4d4f-8023-e3f0da61cab7
@diamond8658

Copy link
Copy Markdown
Contributor Author

Roman Lutz (@romanlutz)

Comment thread pyrit/datasets/converters/vigenere_description.yaml Outdated
Comment thread pyrit/datasets/converters/vigenere_description.yaml Outdated
@romanlutz Roman Lutz (romanlutz) self-assigned this Aug 7, 2026
Roman Lutz (romanlutz) and others added 4 commits August 7, 2026 13:35
…iation test

_try_instantiate_converter fills required str params with a generic placeholder, which VigenereConverter rejects because its key must be alphabetic. Add an override like the other converters with validated required params.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 4e67eb0e-8f79-4d4f-8023-e3f0da61cab7
@romanlutz

Copy link
Copy Markdown
Contributor

diamond8658 can you respond on the comments? It's otherwise ready to merge.

@diamond8658

Copy link
Copy Markdown
Contributor Author

Just addressed the author stuff, and pinned it to v1 as well Roman Lutz (@romanlutz)

@romanlutz

Copy link
Copy Markdown
Contributor

diamond8658 rereading my comment I think I expressed myself badly. If there is a connection to v1 we should cite it but if not then let omit the source link. I guess it really depends on how you got the idea.

@diamond8658

Copy link
Copy Markdown
Contributor Author

Good question but there really isn't that much of a connection to the paper. I wrote this based on general knowledge on how the vigenere cipher works so I'm just going to drop the source entirely. Should be ready to merge now. Roman Lutz (@romanlutz)

@romanlutz
Roman Lutz (romanlutz) added this pull request to the merge queue Aug 11, 2026
Merged via the queue into microsoft:main with commit 5a6aa3c Aug 11, 2026
54 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

FEAT: Add VigenereConverter

3 participants