66from getpass import getpass
77from secrets import token_bytes
88
9- from .difficulty import SCryptParameters , oldDefaultScryptParams , determineScryptParameters , sysrand
9+ from .difficulty import (
10+ SCryptParameters ,
11+ oldDefaultScryptParams ,
12+ determineScryptParameters ,
13+ sysrand ,
14+ )
1015from .txtui import show , promptUser
1116
1217
13- class TokenType (Enum ):
18+ @dataclass
19+ class TokenInfo :
1420 tokens : Callable [[], Sequence [str ]]
1521 separator : str
1622 retokenize : Callable [[str ], Sequence [str ]]
1723
18- numbers = "numbers"
19- words = "words"
20-
21-
22- TokenType .numbers .tokens = lambda : "0123456789"
23- TokenType .numbers .separator = ""
24- TokenType .numbers .retokenize = lambda x : list (x )
25-
2624
2725def horsephrase_tokens () -> Sequence [str ]:
2826 from horsephrase .__main__ import words
2927
3028 return words
3129
3230
33- TokenType . words . tokens = horsephrase_tokens
34- TokenType . words . separator = " "
35- TokenType . words . retokenize = lambda x : x .split (" " )
31+ class TokenType ( Enum ):
32+ numbers = TokenInfo ( lambda : "0123456789" , ", " , lambda x : list ( x ))
33+ words = TokenInfo ( horsephrase_tokens , " " , lambda x : x .split (" " ) )
3634
3735
3836@dataclass
@@ -146,7 +144,7 @@ def tojson(self) -> dict[str, object]:
146144 "generatedCount" : str (self .generatedCount ),
147145 "salt" : self .salt .hex (),
148146 "key" : self .key .hex (),
149- "tokenType" : self .tokenType .value ,
147+ "tokenType" : self .tokenType .name ,
150148 "guesses" : [each .tojson () for each in self .guesses ],
151149 "maxKnown" : str (self .maxKnown ),
152150 "kdf" : self .kdf .tojson (),
@@ -164,7 +162,7 @@ def fromjson(cls, data: dict[str, Any]) -> Memorization2:
164162 generatedCount = int (data ["generatedCount" ]),
165163 salt = bytes .fromhex (data ["salt" ]),
166164 key = bytes .fromhex (data ["key" ]),
167- tokenType = TokenType ( data ["tokenType" ]) ,
165+ tokenType = TokenType [ data ["tokenType" ]] ,
168166 guesses = [UserGuess .fromjson (each ) for each in data ["guesses" ]],
169167 maxKnown = int (data ["maxKnown" ]),
170168 kdf = SCryptParameters .fromjson (data .get ("kdf" , oldDefaultScryptParams )),
@@ -191,7 +189,9 @@ def new(cls, label: str) -> Memorization2:
191189 return self
192190
193191 def string (self ) -> str :
194- return show (self .tokenType .separator , self .knownTokens , self .generatedCount )
192+ return show (
193+ self .tokenType .value .separator , self .knownTokens , self .generatedCount
194+ )
195195
196196 def nextPromptTime (self ) -> float :
197197 """
@@ -225,33 +225,37 @@ def generateOne(self) -> None:
225225 """
226226 Generate one additional token.
227227 """
228- chosen = sysrand .choice (self .tokenType .tokens ())
228+ chosen = sysrand .choice (self .tokenType .value . tokens ())
229229 if self .generatedCount > self .maxKnown :
230230 # we no longer remember the entire passphrase, but the key has to
231231 # represent the entire passphrase.
232232 wholePassphrase = getpass (
233233 "enter correctly to confirm: "
234234 + show (
235- self .tokenType .separator ,
235+ self .tokenType .value . separator ,
236236 self .knownTokens + [chosen ],
237237 self .generatedCount + 1 ,
238238 )
239239 + ": "
240240 )
241- tokens = self .tokenType .retokenize (wholePassphrase )
241+ tokens = self .tokenType .value . retokenize (wholePassphrase )
242242 newTokenMismatch = tokens [- 1 ] != chosen
243243 oldTokenMismatch = (
244244 self .kdf .kdf (
245245 salt = self .salt ,
246- password = self .tokenType .separator .join (tokens [:- 1 ]).encode ("utf-8" ),
246+ password = self .tokenType .value .separator .join (tokens [:- 1 ]).encode (
247+ "utf-8"
248+ ),
247249 )
248250 != self .key
249251 )
250252 if newTokenMismatch or oldTokenMismatch :
251253 print ("passphrase incorrect" )
252254 return
253255 else :
254- wholePassphrase = self .tokenType .separator .join ([* self .knownTokens , chosen ])
256+ wholePassphrase = self .tokenType .value .separator .join (
257+ [* self .knownTokens , chosen ]
258+ )
255259 # commit!
256260 self .generatedCount += 1
257261 self .knownTokens .append (chosen )
0 commit comments