66
77from codex32 .bech32 import (
88 CHARSET ,
9- _chars_to_u5 ,
10- _u5_to_chars ,
119 bech32_decode ,
1210 bech32_encode ,
1311 bech32_verify_checksum ,
12+ chars_to_u5 ,
13+ u5_to_chars ,
1414)
15- from codex32 .checksums import _CODEX32 , _CODEX32_LONG , _Checksum
15+ from codex32 .checksums import CODEX32 , CODEX32_LONG , Checksum
1616from codex32 .errors import (
1717 DuplicateShareIndex ,
1818 ExistingTargetIndex ,
@@ -68,7 +68,7 @@ def __post_init__(self) -> None:
6868 def _from_symbols (cls , symbols : tuple [int , ...]) -> "Header" :
6969 if len (symbols ) != 6 :
7070 raise InvalidLength ("codex32 header must contain six symbols" )
71- text = _u5_to_chars (symbols )
71+ text = u5_to_chars (symbols )
7272 if text [0 ] not in "023456789" :
7373 raise InvalidThreshold (
7474 f"The threshold must be 0 or a number from 2 through 9; found { text [0 ]!r} ."
@@ -77,25 +77,36 @@ def _from_symbols(cls, symbols: tuple[int, ...]) -> "Header":
7777
7878 @property
7979 def _symbols (self ) -> tuple [int , ...]:
80- return tuple (_chars_to_u5 (f"{ self .threshold } { self .identifier } { self .index } " ))
80+ return tuple (chars_to_u5 (f"{ self .threshold } { self .identifier } { self .index } " ))
8181
8282
83- def _checksum_for_encoded_length (hrp : str , encoded_length : int ) -> _Checksum :
83+ def checksum_for_encoded_length (hrp : str , encoded_length : int ) -> Checksum :
84+ """Return the codex32 checksum required by an encoded HRP/data length."""
85+
8486 expanded_length = 2 * len (hrp ) + 1 + encoded_length
8587 if expanded_length <= 93 :
86- return _CODEX32
88+ return CODEX32
8789 if expanded_length < 96 :
8890 raise InvalidLength ("expanded codex32 lengths 94 and 95 are invalid" )
8991 if expanded_length <= 1023 :
90- return _CODEX32_LONG
92+ return CODEX32_LONG
9193 raise InvalidLength ("expanded codex32 codeword exceeds 1023 symbols" )
9294
9395
94- def _decode_codex32 (text : str ) -> tuple [str , _ProfileRules | None , tuple [int , ...], _Checksum ]:
96+ def checksum_for_body_length (hrp : str , body_length : int ) -> Checksum :
97+ """Return the checksum required when constructing a codex32 body."""
98+
99+ expanded_body_length = 2 * len (hrp ) + 1 + body_length
100+ checksum = CODEX32 if expanded_body_length <= 80 else CODEX32_LONG
101+ checksum_for_encoded_length (hrp , body_length + checksum .length )
102+ return checksum
103+
104+
105+ def _decode_codex32 (text : str ) -> tuple [str , _ProfileRules | None , tuple [int , ...], Checksum ]:
95106 hrp , encoded = bech32_decode (text )
96107 if len (hrp ) + 1 + len (encoded ) < 21 :
97108 raise InvalidLength ("codex32 string must contain at least 21 characters" )
98- checksum = _checksum_for_encoded_length (hrp , len (encoded ))
109+ checksum = checksum_for_encoded_length (hrp , len (encoded ))
99110 body = tuple (encoded [: - checksum .length ])
100111 Header ._from_symbols (body [:6 ])
101112 if not bech32_verify_checksum (hrp , encoded , checksum ):
@@ -205,10 +216,7 @@ def _from_parts(
205216 if rules is not None :
206217 _validate_payload (rules .profile , header , payload )
207218 body = [* header ._symbols , * payload ]
208- expanded_body_length = 2 * len (normalized_hrp ) + 1 + len (body )
209- checksum = _CODEX32 if expanded_body_length <= 80 else _CODEX32_LONG
210- # Validate the completed generic codeword, including the 94/95 gap.
211- _checksum_for_encoded_length (normalized_hrp , len (body ) + checksum .length )
219+ checksum = checksum_for_body_length (normalized_hrp , len (body ))
212220 text = bech32_encode (normalized_hrp , body , checksum )
213221 return parse_codex32 (text .upper () if uppercase else text )
214222
@@ -330,7 +338,7 @@ def _interpolate_tail(share_set: _ShareSet, target: str) -> Share | Secret:
330338 value ^= _gf32_multiply (weight , row [column ])
331339 result .append (value )
332340 header = Header (share_set .threshold , share_set .identifier , target )
333- text = f"{ share_set .hrp } 1{ _u5_to_chars ((* header ._symbols , * result ))} "
341+ text = f"{ share_set .hrp } 1{ u5_to_chars ((* header ._symbols , * result ))} "
334342 return parse_codex32 (text .upper () if share_set .uppercase else text )
335343
336344
0 commit comments