Skip to content

Commit

Permalink
python: Overhaul exceptions
Browse files Browse the repository at this point in the history
  • Loading branch information
real-or-random committed Oct 18, 2024
1 parent f0b7d96 commit 3e7631b
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 27 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,7 @@ have obtained authentic public host keys.

*Raises*:

- `InvalidContributionError` - If `hostpubkeys[i]` is not a valid public key
- `FaultyParticipantError` - If `hostpubkeys[i]` is not a valid public key
for some `i`, which is indicated as part of the exception.
- `DuplicateHostpubkeyError` - If `hostpubkeys` contains duplicates.
- `ThresholdError` - If `1 <= t <= len(hostpubkeys)` does not hold.
Expand Down Expand Up @@ -745,7 +745,7 @@ Perform a participant's first step of a ChillDKG session.
- `ValueError` - If the participant's host public key is not in argument
`hostpubkeys`.
- `SecretKeyError` - If the length of `hostseckey` is not 32 bytes.
- `InvalidContributionError` - If `hostpubkeys[i]` is not a valid public key
- `FaultyParticipantError` - If `hostpubkeys[i]` is not a valid public key
for some `i`, which is indicated as part of the exception.
- `DuplicateHostpubkeyError` - If `hostpubkeys` contains duplicates.
- `ThresholdError` - If `1 <= t <= len(hostpubkeys)` does not hold.
Expand Down Expand Up @@ -779,7 +779,7 @@ Perform a participant's second step of a ChillDKG session.
*Raises*:

- `SecKeyError` - If the length of `hostseckey` is not 32 bytes.
- `InvalidContributionError` - If `cmsg1` is invalid. This can happen if
- `FaultyParticipantError` - If `cmsg1` is invalid. This can happen if
another participant has sent an invalid message to the coordinator,
or if the coordinator has sent an invalid `cmsg1`.

Expand Down Expand Up @@ -858,7 +858,7 @@ Perform the coordinator's first step of a ChillDKG session.

*Raises*:

- `InvalidContributionError` - If `hostpubkeys[i]` is not a valid public key
- `FaultyParticipantError` - If `hostpubkeys[i]` is not a valid public key
for some `i`, which is indicated as part of the exception.
- `DuplicateHostpubkeyError` - If `hostpubkeys` contains duplicates.
- `ThresholdError` - If `1 <= t <= len(hostpubkeys)` does not hold.
Expand Down
23 changes: 13 additions & 10 deletions python/chilldkg_ref/chilldkg.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@
from .util import (
BIP_TAG,
tagged_hash_bip_dkg,
ProtocolError,
SecretKeyError,
ThresholdError,
InvalidContributionError,
FaultyParticipantError,
FaultyCoordinatorError,
)

__all__ = [
Expand All @@ -39,7 +41,8 @@
# Exceptions
"SecretKeyError",
"ThresholdError",
"InvalidContributionError",
"FaultyParticipantError",
"FaultyCoordinatorError",
"InvalidRecoveryDataError",
"DuplicateHostpubkeyError",
"SessionNotFinalizedError",
Expand All @@ -62,15 +65,15 @@
###


class DuplicateHostpubkeyError(ValueError):
class DuplicateHostpubkeyError(ProtocolError):
pass


class SessionNotFinalizedError(Exception):
class SessionNotFinalizedError(ProtocolError):
pass


class InvalidRecoveryDataError(Exception):
class InvalidRecoveryDataError(ValueError):
pass


Expand Down Expand Up @@ -219,7 +222,7 @@ def params_validate(params: SessionParams) -> None:
try:
_ = GE.from_bytes_compressed(hostpubkey)
except ValueError as e:
raise InvalidContributionError(
raise FaultyParticipantError(
i, "Participant has provided an invalid host public key"
) from e

Expand All @@ -246,7 +249,7 @@ def params_id(params: SessionParams) -> bytes:
bytes: The parameters ID, a 32-byte string.
Raises:
InvalidContributionError: If `hostpubkeys[i]` is not a valid public key
FaultyParticipantError: If `hostpubkeys[i]` is not a valid public key
for some `i`, which is indicated as part of the exception.
DuplicateHostpubkeyError: If `hostpubkeys` contains duplicates.
ThresholdError: If `1 <= t <= len(hostpubkeys)` does not hold.
Expand Down Expand Up @@ -395,7 +398,7 @@ def participant_step1(
ValueError: If the participant's host public key is not in argument
`hostpubkeys`.
SecretKeyError: If the length of `hostseckey` is not 32 bytes.
InvalidContributionError: If `hostpubkeys[i]` is not a valid public key
FaultyParticipantError: If `hostpubkeys[i]` is not a valid public key
for some `i`, which is indicated as part of the exception.
DuplicateHostpubkeyError: If `hostpubkeys` contains duplicates.
ThresholdError: If `1 <= t <= len(hostpubkeys)` does not hold.
Expand Down Expand Up @@ -445,7 +448,7 @@ def participant_step2(
Raises:
SecKeyError: If the length of `hostseckey` is not 32 bytes.
InvalidContributionError: If `cmsg1` is invalid. This can happen if
FaultyParticipantError: If `cmsg1` is invalid. This can happen if
another participant has sent an invalid message to the coordinator,
or if the coordinator has sent an invalid `cmsg1`.
Expand Down Expand Up @@ -543,7 +546,7 @@ def coordinator_step1(
`coordinator_finalize` call).
Raises:
InvalidContributionError: If `hostpubkeys[i]` is not a valid public key
FaultyParticipantError: If `hostpubkeys[i]` is not a valid public key
for some `i`, which is indicated as part of the exception.
DuplicateHostpubkeyError: If `hostpubkeys` contains duplicates.
ThresholdError: If `1 <= t <= len(hostpubkeys)` does not hold.
Expand Down
11 changes: 8 additions & 3 deletions python/chilldkg_ref/encpedpop.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@
from secp256k1proto.util import int_from_bytes

from . import simplpedpop
from .util import tagged_hash_bip_dkg, prf, InvalidContributionError
from .util import (
tagged_hash_bip_dkg,
prf,
FaultyParticipantError,
FaultyCoordinatorError,
)


###
Expand Down Expand Up @@ -208,7 +213,7 @@ def participant_step2(

reported_pubnonce = pubnonces[idx]
if reported_pubnonce != pubnonce:
raise InvalidContributionError(None, "Coordinator replied with wrong pubnonce")
raise FaultyCoordinatorError("Coordinator replied with wrong pubnonce")

enc_context = serialize_enc_context(simpl_state.t, enckeys)
secshare = decrypt_sum(
Expand Down Expand Up @@ -240,7 +245,7 @@ def coordinator_step(
pubnonces = [pmsg.pubnonce for pmsg in pmsgs]
for i in range(n):
if len(pmsgs[i].enc_shares) != n:
raise InvalidContributionError(
raise FaultyParticipantError(
i, "Participant sent enc_shares with invalid length"
)
enc_secshares = [
Expand Down
21 changes: 13 additions & 8 deletions python/chilldkg_ref/simplpedpop.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@

from secp256k1proto.bip340 import schnorr_sign, schnorr_verify
from secp256k1proto.secp256k1 import GE, Scalar
from .util import BIP_TAG, SecretKeyError, InvalidContributionError, ThresholdError
from .util import (
BIP_TAG,
SecretKeyError,
ThresholdError,
FaultyParticipantError,
FaultyCoordinatorError,
)
from .vss import VSS, VSSCommitment


Expand Down Expand Up @@ -122,35 +128,34 @@ def participant_step2(
t, n, idx, com_to_secret = state
coms_to_secrets, sum_coms_to_nonconst_terms, pops = cmsg

# TODO Raise InvalidContributionError when deserizaltion yields wrong lengths
# TODO Raise FaultyCoordinatorError when deserizaltion yields wrong lengths
assert len(coms_to_secrets) == n
assert len(sum_coms_to_nonconst_terms) == t - 1
assert len(pops) == n

if coms_to_secrets[idx] != com_to_secret:
raise InvalidContributionError(
None, "Coordinator sent unexpected first group element for local index"
raise FaultyCoordinatorError(
"Coordinator sent unexpected first group element for local index"
)

for i in range(n):
if i == idx:
# No need to check our own pop.
continue
if coms_to_secrets[i].infinity:
raise InvalidContributionError(i, "Participant sent invalid commitment")
raise FaultyParticipantError(i, "Participant sent invalid commitment")
# This can be optimized: We serialize the coms_to_secrets[i] here, but
# schnorr_verify (inside pop_verify) will need to deserialize it again, which
# involves computing a square root to obtain the y coordinate.
if not pop_verify(pops[i], coms_to_secrets[i].to_bytes_xonly(), i):
raise InvalidContributionError(
raise FaultyParticipantError(
i, "Participant sent invalid proof-of-knowledge"
)
sum_coms = assemble_sum_coms(coms_to_secrets, sum_coms_to_nonconst_terms, n)
threshold_pubkey = sum_coms.commitment_to_secret()
pubshares = [sum_coms.pubshare(i) for i in range(n)]
if not VSSCommitment.verify_secshare(secshare, pubshares[idx]):
# TODO What to raise here? We don't know who was wrong.
raise InvalidContributionError(None, "Received invalid secshare.")
raise FaultyParticipantError(None, "Received invalid secshare")

dkg_output = DKGOutput(
secshare.to_bytes(),
Expand Down
12 changes: 10 additions & 2 deletions python/chilldkg_ref/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,15 @@ class ThresholdError(ValueError):
pass


class InvalidContributionError(Exception):
class ProtocolError(Exception):
pass


class FaultyParticipantError(ProtocolError):
def __init__(self, participant: Optional[int], error: str) -> None:
self.participant = participant
self.participant = participant # None means we don't know
self.contrib = error


class FaultyCoordinatorError(ProtocolError):
pass

0 comments on commit 3e7631b

Please sign in to comment.