FEAT: Add VigenereConverter - #2333
Conversation
@microsoft-github-policy-service agree |
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
…onverter' into feature/vigenere-converter
…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
|
diamond8658 can you respond on the comments? It's otherwise ready to merge. |
|
Just addressed the author stuff, and pinned it to v1 as well Roman Lutz (@romanlutz) |
|
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. |
…yRIT into feature/vigenere-converter
|
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) |
Description
Adds
VigenereConverter, a classical polyalphabetic cipher converter that generalizesCaesarConverterusing a repeating keyword instead of a fixed shift. Closes #2304.Follows the existing
CaesarConverter/AtbashConverterstructure:__init__(self, *, key: str, append_description: bool = False), validates the key is non-empty and ASCII alphabetic_build_identifier()returns aComponentIdentifierwithkeyas a paramconvert_asyncencodes the prompt, with the sameappend_descriptionbehavior renderingvigenere_description.yamlvigenere_description.yamlcites 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) orFoundryTechnique(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
VigenereConverterto the existing parametrized fixtures intests/unit/converter/test_converter.pyalongside 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__.pyupdated with the import and__all__export.doc/code/converters/1_text_to_text_converters.pyupdated with a demo line. Ran withjupytext --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 returnsTruefor 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 usestr.translate(), which passes through unmapped characters silently.