Skip to content

Commit bbed4ff

Browse files
committed
NISTTV_BASE62
1 parent c474144 commit bbed4ff

File tree

2 files changed

+18
-11
lines changed

2 files changed

+18
-11
lines changed

ff3/ff3.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,18 +76,16 @@ class FF3Cipher:
7676
from the base 62 alphabet (digits + lowercase + uppercase latin) are used.
7777
"""
7878
DOMAIN_MIN = 1_000_000 # 1M required in FF3-1
79-
BASE62 = string.digits + string.ascii_lowercase + string.ascii_uppercase
79+
BASE62 = string.digits + string.ascii_uppercase + string.ascii_lowercase
80+
NISTTV_BASE62 = string.digits + string.ascii_lowercase + string.ascii_uppercase
8081
BASE62_LEN = len(BASE62)
8182
RADIX_MAX = 256 # Support 8-bit alphabets for now
8283

83-
def __init__(self, key, tweak, radix=10, ):
84+
def __init__(self, key : str, tweak : str, alphabet : str ):
8485
keybytes = bytes.fromhex(key)
8586
self.tweak = tweak
86-
self.radix = radix
87-
if radix <= FF3Cipher.BASE62_LEN:
88-
self.alphabet = FF3Cipher.BASE62[0:radix]
89-
else:
90-
self.alphabet = None
87+
self.alphabet = alphabet
88+
self.radix = len(alphabet)
9189

9290
# Calculate range of supported message lengths [minLen..maxLen]
9391
# per revised spec, radix^minLength >= 1,000,000.
@@ -120,6 +118,13 @@ def __init__(self, key, tweak, radix=10, ):
120118
# factory method to create a FF3Cipher object with a custom alphabet
121119
@staticmethod
122120
def withCustomAlphabet(key, tweak, alphabet):
121+
c = FF3Cipher(key, tweak, alphabet)
122+
return c
123+
124+
# factory method to create a FF3Cipher object with a radix
125+
@staticmethod
126+
def withRadix(key, tweak, radix):
127+
alphabet = FF3Cipher.BASE62[0:radix]
123128
c = FF3Cipher(key, tweak, len(alphabet))
124129
c.alphabet = alphabet
125130
return c

ff3/ff3_test.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -373,14 +373,16 @@ def test_encrypt_boundaries(self):
373373
def test_encrypt_all(self):
374374
for test in testVectors:
375375
with self.subTest(testVector=test):
376-
c = FF3Cipher(test['key'], test['tweak'], test['radix'])
376+
alphabet = FF3Cipher.NISTTV_BASE62[0:test['radix']]
377+
c = FF3Cipher(test['key'], test['tweak'], alphabet)
377378
s = c.encrypt(test['plaintext'])
378379
self.assertEqual(s, test['ciphertext'])
379380

380381
def test_decrypt_all(self):
381382
for test in testVectors:
382383
with self.subTest(testVector=test):
383-
c = FF3Cipher(test['key'], test['tweak'], test['radix'])
384+
alphabet = FF3Cipher.NISTTV_BASE62[0:test['radix']]
385+
c = FF3Cipher(test['key'], test['tweak'], alphabet)
384386
s = c.decrypt(test['ciphertext'])
385387
self.assertEqual(s, test['plaintext'])
386388

@@ -419,7 +421,7 @@ def test_custom_alphabet(self):
419421
tweak = "D8E7920AFA330A73"
420422
plaintext = "⁸⁹⁰¹²¹²³⁴⁵⁶⁷⁸⁹⁰⁰⁰⁰"
421423
ciphertext = "⁷⁵⁰⁹¹⁸⁸¹⁴⁰⁵⁸⁶⁵⁴⁶⁰⁷"
422-
c = FF3Cipher.withCustomAlphabet(key, tweak, alphabet)
424+
c = FF3Cipher(key, tweak, alphabet)
423425
s = c.encrypt(plaintext)
424426
self.assertEqual(s, ciphertext)
425427
x = c.decrypt(s)
@@ -466,7 +468,7 @@ def test_whole_domain(self):
466468
tweak = "D8E7920AFA330A73"
467469
for radix, plaintext_len, alphabet in test_cases:
468470
if alphabet is None:
469-
c = FF3Cipher(key, tweak, radix=radix)
471+
c = FF3Cipher.withRadix(key, tweak, radix=radix)
470472
else:
471473
c = FF3Cipher.withCustomAlphabet(key, tweak, alphabet=alphabet)
472474
self.subTest(radix=radix, plaintext_len=plaintext_len)

0 commit comments

Comments
 (0)