Skip to content

Commit

Permalink
Implement #158 - rot47 support
Browse files Browse the repository at this point in the history
The file handler code also has been tweaked so new Substitution ciphers
will auto register.
  • Loading branch information
clach04 committed Sep 7, 2024
1 parent 483ccdd commit 62b0ca6
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 18 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Some countries have also have restrictions on import, export, and usage see http
+ [ptpyvim](#ptpyvim)
+ [ptcipher](#ptcipher)
- [rot-13](#rot-13)
- [rot-47](#rot-47)
- [Tombo Blowfish CHI](#tombo-blowfish-chi)
- [ccrypt CPT](#ccrypt-cpt)
- [OpenPGP - gpg / pgp](#openpgp---gpg---pgp)
Expand Down Expand Up @@ -353,6 +354,17 @@ https://en.wikipedia.org/wiki/ROT13
ptcipher -v -p test README.rot13
py -3 -m puren_tonbo.tools.ptcipher puren_tonbo/tests/data/aesop.rot13 -p password_ignored

echo Why did the chicken cross the road?|ptcipher -p ignored_password --encrypt --cipher=rot13
echo Jul qvq gur puvpxra pebff gur ebnq?|ptcipher -p ignored_password --encrypt --cipher=rot13

#### rot-47

Symmetric Substitution cipher with no passphrase/password/key support.
Do not use, this is implemented as a demo and for testing code paths when encryption libraries are not available.

https://en.wikipedia.org/wiki/ROT13#Variants

py -3 -m puren_tonbo.tools.ptcipher puren_tonbo/tests/data/aesop.rot47 -p password_ignored

#### Tombo Blowfish CHI

Expand Down
39 changes: 21 additions & 18 deletions puren_tonbo/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import bisect
import datetime
import errno
import inspect
from io import BytesIO as FakeFile
import json
import locale
Expand Down Expand Up @@ -256,20 +257,30 @@ class Rot13(SubstitutionCipher):
description = 'rot-13 UNSECURE!'
extensions = ['.rot13']

__substitution_table = maketrans(b'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', b'NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm')
substitution_table = maketrans(b'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', b'NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm')

def read_from(self, file_object):
# NOTE no password/key usage!
data = file_object.read()
try:
return data.translate(self.__substitution_table)
return data.translate(self.substitution_table)
except Exception as info:
#raise # debug
# chain exception...
raise PurenTonboException(info)

def write_to(self, file_object, byte_data):
file_object.write(byte_data.translate(self.__substitution_table))
file_object.write(byte_data.translate(self.substitution_table))


class Rot47(Rot13):
description = 'rot-47 UNSECURE!'
extensions = ['.rot47']

substitution_table = maketrans(
b'!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~',
b'PQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNO'
)


class VimDecryptArgs():
Expand Down Expand Up @@ -647,24 +658,16 @@ class ZipBzip2AES(ZipAES):

# note uses file extension - could also sniff file header and use file magic
file_type_handlers = {}
"""
'.txt': RawFile, # these are not needed, filename2handler() defaults
'.md': RawFile,
}
"""
for file_extension in RawFile.extensions:
file_type_handlers[file_extension] = RawFile

for file_extension in Rot13.extensions:
file_type_handlers[file_extension] = Rot13

"""
# TODO introspect and add to list based on class isinstance check
for enc_class in (RawFile, Rot13):
# Dumb introspect code for RawFile and SubstitutionCipher (rot13 and rot47)
for enc_class_name in dir(): #(RawFile, Rot13):
enc_class = globals()[enc_class_name]
if not inspect.isclass(enc_class):
continue
if not issubclass(enc_class, RawFile) and not issubclass(enc_class, SubstitutionCipher):
continue
for file_extension in enc_class.extensions:
file_type_handlers[file_extension] = enc_class
"""


if chi_io:
for file_extension in TomboBlowfish.extensions:
Expand Down
7 changes: 7 additions & 0 deletions puren_tonbo/tests/data/aesop.rot13
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
nrfbc

Gur Sebtf Qrfvevat n Xvat

Gur Sebtf jrer yvivat nf unccl nf pbhyq or va n zneful fjnzc gung whfg fhvgrq gurz; gurl jrag fcynfuvat nobhg pnevat sbe abobql naq abobql gebhoyvat jvgu gurz. Ohg fbzr bs gurz gubhtug gung guvf jnf abg evtug, gung gurl fubhyq unir n xvat naq n cebcre pbafgvghgvba, fb gurl qrgrezvarq gb fraq hc n crgvgvba gb Wbir gb tvir gurz jung gurl jnagrq. "Zvtugl Wbir," gurl pevrq, "fraq hagb hf n xvat gung jvyy ehyr bire hf naq xrrc hf va beqre." Wbir ynhturq ng gurve pebnxvat, naq guerj qbja vagb gur fjnzc n uhtr Ybt, juvpu pnzr qbja fcynfuvat vagb gur fjnzc. Gur Sebtf jrer sevtugrarq bhg bs gurve yvirf ol gur pbzzbgvba znqr va gurve zvqfg, naq nyy ehfurq gb gur onax gb ybbx ng gur ubeevoyr zbafgre; ohg nsgre n gvzr, frrvat gung vg qvq abg zbir, bar be gjb bs gur obyqrfg bs gurz iragherq bhg gbjneqf gur Ybt, naq rira qnerq gb gbhpu vg; fgvyy vg qvq abg zbir. Gura gur terngrfg ureb bs gur Sebtf whzcrq hcba gur Ybt naq pbzzraprq qnapvat hc naq qbja hcba vg, gurerhcba nyy gur Sebtf pnzr naq qvq gur fnzr; naq sbe fbzr gvzr gur Sebtf jrag nobhg gurve ohfvarff rirel qnl jvgubhg gnxvat gur fyvtugrfg abgvpr bs gurve arj Xvat Ybt ylvat va gurve zvqfg. Ohg guvf qvq abg fhvg gurz, fb gurl frag nabgure crgvgvba gb Wbir, naq fnvq gb uvz, "Jr jnag n erny xvat; bar gung jvyy ernyyl ehyr bire hf." Abj guvf znqr Wbir natel, fb ur frag nzbat gurz n ovt Fgbex gung fbba frg gb jbex tbooyvat gurz nyy hc. Gura gur Sebtf ercragrq jura gbb yngr.

Orggre ab ehyr guna pehry ehyr.
7 changes: 7 additions & 0 deletions puren_tonbo/tests/data/aesop.rot47
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
26D@A

%96 uC@8D s6D:C:?8 2 z:?8

%96 uC@8D H6C6 =:G:?8 2D 92AAJ 2D 4@F=5 36 :? 2 >2CD9J DH2>A E92E ;FDE DF:E65 E96>j E96J H6?E DA=2D9:?8 23@FE 42C:?8 7@C ?@3@5J 2?5 ?@3@5J EC@F3=:?8 H:E9 E96>] qFE D@>6 @7 E96> E9@F89E E92E E9:D H2D ?@E C:89E[ E92E E96J D9@F=5 92G6 2 <:?8 2?5 2 AC@A6C 4@?DE:EFE:@?[ D@ E96J 56E6C>:?65 E@ D6?5 FA 2 A6E:E:@? E@ y@G6 E@ 8:G6 E96> H92E E96J H2?E65] Q|:89EJ y@G6[Q E96J 4C:65[ QD6?5 F?E@ FD 2 <:?8 E92E H:== CF=6 @G6C FD 2?5 <66A FD :? @C56C]Q y@G6 =2F8965 2E E96:C 4C@2<:?8[ 2?5 E9C6H 5@H? :?E@ E96 DH2>A 2 9F86 {@8[ H9:49 42>6 5@H? DA=2D9:?8 :?E@ E96 DH2>A] %96 uC@8D H6C6 7C:89E6?65 @FE @7 E96:C =:G6D 3J E96 4@>>@E:@? >256 :? E96:C >:5DE[ 2?5 2== CFD965 E@ E96 32?< E@ =@@< 2E E96 9@CC:3=6 >@?DE6Cj 3FE 27E6C 2 E:>6[ D66:?8 E92E :E 5:5 ?@E >@G6[ @?6 @C EH@ @7 E96 3@=56DE @7 E96> G6?EFC65 @FE E@H2C5D E96 {@8[ 2?5 6G6? 52C65 E@ E@F49 :Ej DE:== :E 5:5 ?@E >@G6] %96? E96 8C62E6DE 96C@ @7 E96 uC@8D ;F>A65 FA@? E96 {@8 2?5 4@>>6?465 52?4:?8 FA 2?5 5@H? FA@? :E[ E96C6FA@? 2== E96 uC@8D 42>6 2?5 5:5 E96 D2>6j 2?5 7@C D@>6 E:>6 E96 uC@8D H6?E 23@FE E96:C 3FD:?6DD 6G6CJ 52J H:E9@FE E2<:?8 E96 D=:89E6DE ?@E:46 @7 E96:C ?6H z:?8 {@8 =J:?8 :? E96:C >:5DE] qFE E9:D 5:5 ?@E DF:E E96>[ D@ E96J D6?E 2?@E96C A6E:E:@? E@ y@G6[ 2?5 D2:5 E@ 9:>[ Q(6 H2?E 2 C62= <:?8j @?6 E92E H:== C62==J CF=6 @G6C FD]Q }@H E9:D >256 y@G6 2?8CJ[ D@ 96 D6?E 2>@?8 E96> 2 3:8 $E@C< E92E D@@? D6E E@ H@C< 8@33=:?8 E96> 2== FA] %96? E96 uC@8D C6A6?E65 H96? E@@ =2E6]

q6EE6C ?@ CF=6 E92? 4CF6= CF=6]
17 changes: 17 additions & 0 deletions puren_tonbo/tests/testsuite.py
Original file line number Diff line number Diff line change
Expand Up @@ -899,6 +899,23 @@ class TestFileSystemNotesWriteFunctionSaveEncryptedRot13(TestFileSystemNotesWrit
handler_class = puren_tonbo.Rot13 # rot-13


# rot-47
class TestBaseEncryptedRot47(TestBaseEncryptedFile, TestBaseEncryptedFileCompat, TestBaseEncryptedFileUtil):
test_data_bytes = b"this is just a small piece of text."
test_password_bytes = b'mypassword'
pt_handler_class = puren_tonbo.Rot47
encrypt_pt_handler_class = decrypt_pt_handler_class = puren_tonbo.Rot47 # TODO review this

def test_same_input_different_crypted_text(self):
self.skip('rot-47 always has same output')

class TestFileSystemNotesWriteClassSaveEncryptedRot47(TestFileSystemNotesWriteClassSaveRawPlainText):
handler_class = puren_tonbo.Rot47 # rot-47

class TestFileSystemNotesWriteFunctionSaveEncryptedRot47(TestFileSystemNotesWriteFunctionSaveRawPlainText):
handler_class = puren_tonbo.Rot47 # rot-47



""" TODO implement TestFileSystemNotesWriteClassSaveRawPlainText and TestFileSystemNotesWriteFunctionSaveRawPlainText for:
grep '(EncryptedFile):' puren_tonbo/__init__.py
Expand Down

0 comments on commit 62b0ca6

Please sign in to comment.