Repository navigation
errors: Move friendly recovery messages into library #158
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -103,7 +103,7 @@ def _decode_codex32(text: str) -> tuple[str, _ProfileRules | None, tuple[int, .. | |
| body = tuple(encoded[: -checksum.length]) | ||
| Header._from_symbols(body[:6]) | ||
| if not bech32_verify_checksum(hrp, encoded, checksum): | ||
| raise InvalidChecksum(f"invalid {checksum.kind} checksum") | ||
| raise InvalidChecksum("The checksum does not match.") | ||
| profile_rules = _optional_profile_rules(hrp) | ||
| if profile_rules is not None: | ||
| profile_rules.validate_text_length(len(text)) | ||
|
|
@@ -278,31 +278,31 @@ def _validate_share_set(artifacts: Sequence[Share | Secret], *, require_exact: b | |
| first = copied[0] | ||
| threshold = first.header.threshold | ||
| if threshold not in range(2, 10): | ||
| raise MismatchedThreshold("linear sharing requires threshold 2 through 9") | ||
| raise MismatchedThreshold("Only strings with a threshold of 2 through 9 can be combined.") | ||
| if len(copied) > threshold or (require_exact and len(copied) != threshold): | ||
| raise WrongShareCount(f"threshold is {threshold}, but {len(copied)} artifacts were supplied") | ||
| first_tail, checksum_length, encoded_length = _artifact_tail(first) | ||
| tails = [first_tail] | ||
| indices = [first.header.index] | ||
| for item in copied[1:]: | ||
| if item.hrp != first.hrp: | ||
| raise MismatchedHrp(f"{first.hrp} and {item.hrp} cannot be combined") | ||
| raise MismatchedHrp("These strings are for different applications.") | ||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. did you like showing the mismatch or is the new string best?
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this diff uses strings repeatedly but sometimes a more user friendly message may say shares when the provided data was all non-S
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Showing the mismatch is better. #161 keeps the library's "ms and bip39_12w cannot be combined", which you said seemed fine earlier today. On shares versus strings: #161 (10c8f9b) now says "shares" when every input is an ordinary share and "strings" when a secret is among them. Generated by Claude Code |
||
| if item.header.threshold != threshold: | ||
| raise MismatchedThreshold("share thresholds do not match") | ||
| raise MismatchedThreshold("These strings require different numbers of shares.") | ||
| if item.header.identifier != first.header.identifier: | ||
| raise MismatchedIdentifier("share identifiers do not match") | ||
| raise MismatchedIdentifier("These strings have different identifiers.") | ||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is a situation where strings or shares could be correct. i nit slightly prefer to use the one our set is.
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in #161 (10c8f9b). The threshold, identifier and length mismatches all pick the noun from the set itself. "These strings require different numbers of shares" also became "These shares have different thresholds" (or "These strings have…") so that it reads well with either noun. Generated by Claude Code |
||
| tail, item_checksum_length, item_encoded_length = _artifact_tail(item) | ||
| item_shape = ( | ||
| len(item.payload_symbols), | ||
| item_checksum_length, | ||
| item_encoded_length, | ||
| ) | ||
| if item_shape != (len(first.payload_symbols), checksum_length, encoded_length): | ||
| raise MismatchedPayloadLength("share payload/checksum lengths do not match") | ||
| raise MismatchedPayloadLength("These strings have different lengths.") | ||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same shares sometimes, strings other times.
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| tails.append(tail) | ||
| indices.append(item.header.index) | ||
| if len(set(indices)) != len(indices): | ||
| raise DuplicateShareIndex("share indices must be distinct") | ||
| raise DuplicateShareIndex("That share index was already entered.") | ||
| return _ShareSet( | ||
| copied, | ||
| first.hrp, | ||
|
|
@@ -317,7 +317,7 @@ def _validate_share_set(artifacts: Sequence[Share | Secret], *, require_exact: b | |
| def _validate_recovery_prefix(shares: Sequence[Share | Secret]) -> None: | ||
| share_set = _validate_share_set(shares, require_exact=False) | ||
| if any(isinstance(item, Secret) for item in share_set.artifacts): | ||
| raise SecretInRecoverySet("recovery accepts ordinary shares only") | ||
| raise SecretInRecoverySet("Enter ordinary shares rather than the shared secret.") | ||
|
|
||
|
|
||
| def _validate_basis_prefix(basis: Sequence[Share | Secret]) -> None: | ||
|
|
@@ -342,7 +342,7 @@ def recover_secret(shares: Sequence[Share]) -> Secret: | |
| """Recover S from exactly k compatible, distinct ordinary shares.""" | ||
| share_set = _validate_share_set(shares) | ||
| if any(isinstance(item, Secret) for item in share_set.artifacts): | ||
| raise SecretInRecoverySet("recovery accepts ordinary shares only") | ||
| raise SecretInRecoverySet("Enter ordinary shares rather than the shared secret.") | ||
|
Comment on lines
319
to
+345
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why are we duplicating this logic?
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We shouldn't. In #161 (10c8f9b), Generated by Claude Code |
||
| recovered = _interpolate_tail(share_set, "s") | ||
| if not isinstance(recovered, Secret): | ||
| raise InvalidShareSet("interpolation did not produce a secret") | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we keep {checksum.kind} or not?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Drop it. Which checksum applies follows from the string's length, and naming it ("invalid Long codex32 checksum") gives the user nothing to act on. #161 drops it too, so both codex32 and bech32 checksum failures read "The checksum does not match." The
kindfield stays becausetests/test_crc.pyreads it.Generated by Claude Code