eddsa-threshold 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- eddsa_threshold/__init__.py +1 -0
- eddsa_threshold/eddsa/__init__.py +1 -0
- eddsa_threshold/eddsa/algorithms/__init__.py +1 -0
- eddsa_threshold/eddsa/algorithms/ed25519.py +84 -0
- eddsa_threshold/eddsa/algorithms/ed25519ctx.py +23 -0
- eddsa_threshold/eddsa/algorithms/ed25519ph.py +23 -0
- eddsa_threshold/eddsa/algorithms/ed448.py +84 -0
- eddsa_threshold/eddsa/algorithms/ed448ph.py +23 -0
- eddsa_threshold/eddsa/curves/__init__.py +1 -0
- eddsa_threshold/eddsa/curves/base/__init__.py +1 -0
- eddsa_threshold/eddsa/curves/base/edwards_curve.py +91 -0
- eddsa_threshold/eddsa/curves/base/encoding.py +54 -0
- eddsa_threshold/eddsa/curves/base/field_ops.py +48 -0
- eddsa_threshold/eddsa/curves/base/scalar_ops.py +34 -0
- eddsa_threshold/eddsa/curves/ed25519/__init__.py +1 -0
- eddsa_threshold/eddsa/curves/ed25519/constants.py +37 -0
- eddsa_threshold/eddsa/curves/ed25519/ed25519_curve.py +79 -0
- eddsa_threshold/eddsa/curves/ed25519/encoding.py +80 -0
- eddsa_threshold/eddsa/curves/ed25519/field_ops.py +12 -0
- eddsa_threshold/eddsa/curves/ed25519/scalar_ops.py +12 -0
- eddsa_threshold/eddsa/curves/ed448/__init__.py +1 -0
- eddsa_threshold/eddsa/curves/ed448/constants.py +37 -0
- eddsa_threshold/eddsa/curves/ed448/ed448_curve.py +76 -0
- eddsa_threshold/eddsa/curves/ed448/encoding.py +77 -0
- eddsa_threshold/eddsa/curves/ed448/field_ops.py +12 -0
- eddsa_threshold/eddsa/curves/ed448/scalar_ops.py +12 -0
- eddsa_threshold/eddsa/keys/__init__.py +1 -0
- eddsa_threshold/eddsa/keys/ed25519_keypair.py +46 -0
- eddsa_threshold/eddsa/keys/ed448_keypair.py +45 -0
- eddsa_threshold/eddsa/keys/keypair.py +50 -0
- eddsa_threshold/eddsa/util/__init__.py +1 -0
- eddsa_threshold/eddsa/util/dom.py +17 -0
- eddsa_threshold/eddsa/util/hash_bindings.py +12 -0
- eddsa_threshold/frost/__init__.py +1 -0
- eddsa_threshold/frost/coordinator.py +185 -0
- eddsa_threshold/frost/core/__init__.py +1 -0
- eddsa_threshold/frost/core/base/__init__.py +1 -0
- eddsa_threshold/frost/core/base/frost_hashing.py +27 -0
- eddsa_threshold/frost/core/ed25519/__init__.py +1 -0
- eddsa_threshold/frost/core/ed25519/frost_hashing.py +26 -0
- eddsa_threshold/frost/core/ed448/__init__.py +1 -0
- eddsa_threshold/frost/core/ed448/frost_hashing.py +27 -0
- eddsa_threshold/frost/core/frost_types.py +53 -0
- eddsa_threshold/frost/core/polynomial.py +39 -0
- eddsa_threshold/frost/core/secrets/__init__.py +1 -0
- eddsa_threshold/frost/core/secrets/secret_sharing.py +26 -0
- eddsa_threshold/frost/core/secrets/shamir_secret_sharing.py +41 -0
- eddsa_threshold/frost/core/util.py +109 -0
- eddsa_threshold/frost/participant.py +140 -0
- eddsa_threshold/frost/trusted_dealer.py +72 -0
- eddsa_threshold-0.2.0.dist-info/METADATA +39 -0
- eddsa_threshold-0.2.0.dist-info/RECORD +55 -0
- eddsa_threshold-0.2.0.dist-info/WHEEL +5 -0
- eddsa_threshold-0.2.0.dist-info/licenses/LICENSE +14 -0
- eddsa_threshold-0.2.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from typing import Final, Tuple
|
|
3
|
+
|
|
4
|
+
from eddsa_threshold.eddsa.curves.base.edwards_curve import EdwardsCurve
|
|
5
|
+
from eddsa_threshold.frost.core.base.frost_hashing import FrostHashing
|
|
6
|
+
from eddsa_threshold.frost.core.frost_types import GroupInfo, NonceCommitment, ParticipantId, SecretShare, SecretValue, SessionId, SigningPackage, VSSCommitment
|
|
7
|
+
from eddsa_threshold.frost.core.polynomial import derive_interpolating_value
|
|
8
|
+
from eddsa_threshold.frost.core.util import binding_factor_for_participant, compute_binding_factors, compute_group_commitment, derive_group_info
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class FrostParticipant:
|
|
12
|
+
"""
|
|
13
|
+
Participant-side implementation for a 2-round FROST signing flow.
|
|
14
|
+
|
|
15
|
+
The participant owns one long-term secret key share and ephemeral nonces.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
# EdwardsCurve for now, because this project only implements FROST for EdDSA, but this can be made more generic if needed.
|
|
19
|
+
def __init__(self, participant_id: ParticipantId, threshold: int, max_participants: int, hashing: FrostHashing, curve: EdwardsCurve):
|
|
20
|
+
self.PARTICIPANT_ID: Final[ParticipantId] = participant_id
|
|
21
|
+
self.THRESHOLD: Final[int] = threshold
|
|
22
|
+
self.MAX_PARTICIPANTS: Final[int] = max_participants
|
|
23
|
+
|
|
24
|
+
self._HASHING: Final[FrostHashing] = hashing
|
|
25
|
+
self._CURVE: Final[EdwardsCurve] = curve
|
|
26
|
+
|
|
27
|
+
self._dealer_info_set: bool = False
|
|
28
|
+
|
|
29
|
+
self._nonce_pair: dict[SessionId, Tuple[int, int]] = dict() # store nonce pairs for active signing sessions, cleared after signing is complete
|
|
30
|
+
|
|
31
|
+
def set_and_verify_dealer_info(self, secret_share: SecretShare, vss_commitment: list[VSSCommitment]) -> None:
|
|
32
|
+
"""
|
|
33
|
+
Set the participant's secret share and group info after receiving and verifying them from the trusted dealer.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
if not self._vss_verify(secret_share, vss_commitment):
|
|
37
|
+
raise ValueError(f"VSS verification failed for the received secret share and VSS commitment for participant {self.PARTICIPANT_ID}")
|
|
38
|
+
|
|
39
|
+
if self._dealer_info_set:
|
|
40
|
+
raise ValueError(f"Participant {self.PARTICIPANT_ID} has already set their dealer info")
|
|
41
|
+
|
|
42
|
+
self._SECRET_SHARE = secret_share
|
|
43
|
+
self._GROUP_INFO = derive_group_info(self.THRESHOLD, self.MAX_PARTICIPANTS, vss_commitment, self._CURVE)
|
|
44
|
+
self._dealer_info_set = True
|
|
45
|
+
|
|
46
|
+
def round_one_commit(self, session_id: SessionId) -> NonceCommitment:
|
|
47
|
+
"""
|
|
48
|
+
Round 1 of FROST signing: generates a nonce pair and returns the corresponding commitment.
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
if not self._dealer_info_set:
|
|
52
|
+
raise ValueError(f"Participant {self.PARTICIPANT_ID} has not set their dealer info")
|
|
53
|
+
|
|
54
|
+
if session_id in self._nonce_pair:
|
|
55
|
+
raise ValueError(f"participant {self.PARTICIPANT_ID} has already committed to this signing session")
|
|
56
|
+
|
|
57
|
+
nonce_pair, commitment = self._commit()
|
|
58
|
+
self._nonce_pair[session_id] = nonce_pair
|
|
59
|
+
|
|
60
|
+
return commitment
|
|
61
|
+
|
|
62
|
+
def round_two_sign(self, signing_package: SigningPackage) -> SecretValue:
|
|
63
|
+
"""
|
|
64
|
+
Round 2 of FROST signing: takes the signing package from the coordinator and returns the signature share.
|
|
65
|
+
"""
|
|
66
|
+
|
|
67
|
+
if signing_package.session_id not in self._nonce_pair:
|
|
68
|
+
raise ValueError(f"participant {self.PARTICIPANT_ID} must commit to this signing session before signing")
|
|
69
|
+
|
|
70
|
+
nonce_pair = self._nonce_pair[signing_package.session_id]
|
|
71
|
+
signature_share = self._sign(signing_package.session_id, signing_package.message, list(signing_package.commitments.values()))
|
|
72
|
+
|
|
73
|
+
self._nonce_pair.pop(signing_package.session_id) # clear nonce pair for this session since signing is complete
|
|
74
|
+
|
|
75
|
+
return signature_share
|
|
76
|
+
|
|
77
|
+
def _commit(self) -> Tuple[Tuple[int, int], NonceCommitment]:
|
|
78
|
+
"""
|
|
79
|
+
Generates a nonce pair and the corresponding commitment for round 1 of FROST signing.
|
|
80
|
+
"""
|
|
81
|
+
|
|
82
|
+
encoded_secret_share = self._CURVE.encoding.encode_scalar(self._SECRET_SHARE.value)
|
|
83
|
+
hiding_nonce = self._generate_nonce(encoded_secret_share)
|
|
84
|
+
binding_nonce = self._generate_nonce(encoded_secret_share)
|
|
85
|
+
|
|
86
|
+
hiding_nonce_commitment = self._CURVE.extended_to_affine(self._CURVE.scalar_mult(hiding_nonce, None)) # None means base point
|
|
87
|
+
binding_nonce_commitment = self._CURVE.extended_to_affine(self._CURVE.scalar_mult(binding_nonce, None))
|
|
88
|
+
|
|
89
|
+
return (hiding_nonce, binding_nonce), NonceCommitment(self._SECRET_SHARE.index, hiding_nonce_commitment, binding_nonce_commitment)
|
|
90
|
+
|
|
91
|
+
def _sign(self, session_id: SessionId, message: bytes, commitments: list[NonceCommitment]) -> SecretValue:
|
|
92
|
+
"""
|
|
93
|
+
Generates a signature share for round 2 of FROST signing given the signing package from the coordinator.
|
|
94
|
+
"""
|
|
95
|
+
|
|
96
|
+
nonce_pair = self._nonce_pair[session_id]
|
|
97
|
+
|
|
98
|
+
binding_factors = compute_binding_factors(self._GROUP_INFO.group_public_key, commitments, message, self._HASHING, self._CURVE.encoding)
|
|
99
|
+
binding_factor = binding_factor_for_participant(self._SECRET_SHARE.index, binding_factors)
|
|
100
|
+
|
|
101
|
+
group_commitment = compute_group_commitment(commitments, binding_factors, self._CURVE)
|
|
102
|
+
|
|
103
|
+
participants = list(commitment.participant_id for commitment in commitments)
|
|
104
|
+
# Potentially implemenet reuse logic
|
|
105
|
+
lambda_i = derive_interpolating_value(participants, self._SECRET_SHARE.index, 0, self._CURVE.scalar_ops)
|
|
106
|
+
|
|
107
|
+
challenge = self._compute_challenge(group_commitment, message)
|
|
108
|
+
|
|
109
|
+
hiding_nonce, binding_nonce = nonce_pair
|
|
110
|
+
signature_share = hiding_nonce + (binding_nonce * binding_factor) + (lambda_i * self._SECRET_SHARE.value * challenge)
|
|
111
|
+
|
|
112
|
+
return self._CURVE.scalar_ops.reduce(signature_share)
|
|
113
|
+
|
|
114
|
+
def _vss_verify(self, secret_share: SecretShare, vss_commitment: list[VSSCommitment]) -> bool:
|
|
115
|
+
"""
|
|
116
|
+
Verify a participant's secret share against the VSS commitment.
|
|
117
|
+
"""
|
|
118
|
+
|
|
119
|
+
S = self._CURVE.scalar_mult(secret_share.value, None)
|
|
120
|
+
S_ = (0, 1, 1, 0) # identity point in extended coordinates
|
|
121
|
+
for i in range(0, self.THRESHOLD):
|
|
122
|
+
S_ = self._CURVE.add(S_, self._CURVE.scalar_mult(pow(secret_share.index, i), vss_commitment[i]))
|
|
123
|
+
|
|
124
|
+
return self._CURVE.extended_to_affine(S) == self._CURVE.extended_to_affine(S_)
|
|
125
|
+
|
|
126
|
+
def _generate_nonce(self, secret: bytes) -> int:
|
|
127
|
+
"""
|
|
128
|
+
Generates a nonce using the participant's secret share and a random value.
|
|
129
|
+
"""
|
|
130
|
+
|
|
131
|
+
random = os.urandom(32)
|
|
132
|
+
return self._HASHING.h3(random + secret)
|
|
133
|
+
|
|
134
|
+
def _compute_challenge(self, group_commitment: Tuple, message: bytes) -> int:
|
|
135
|
+
"""
|
|
136
|
+
Computes the signing challenge c = H(R || A || m) where R is the group commitment, A is the group public key, and m is the message.
|
|
137
|
+
"""
|
|
138
|
+
|
|
139
|
+
challenge_input = self._CURVE.encoding.encode_point(group_commitment) + self._GROUP_INFO.group_public_key + message
|
|
140
|
+
return self._HASHING.h2(challenge_input)
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
from typing import Callable, Final
|
|
2
|
+
|
|
3
|
+
from eddsa_threshold.eddsa.curves.base.edwards_curve import EdwardsCurve
|
|
4
|
+
from eddsa_threshold.frost.core.base.frost_hashing import FrostHashing
|
|
5
|
+
from eddsa_threshold.frost.core.secrets.shamir_secret_sharing import ShamirSecretSharing
|
|
6
|
+
from eddsa_threshold.frost.core.frost_types import ParticipantId, SecretShare, VSSCommitment
|
|
7
|
+
from eddsa_threshold.frost.core.util import check_participant_bounds
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class FrostTrustedDealer:
|
|
11
|
+
|
|
12
|
+
def __init__(self, seed: int, threshold: int, participant_ids: list[ParticipantId], participant_connections: dict[ParticipantId, Callable[[SecretShare, list[VSSCommitment]], None]], coordinator_connection: Callable[[list[VSSCommitment]], None], curve: EdwardsCurve) -> None:
|
|
13
|
+
if seed < 0 or seed >= curve.scalar_ops.order:
|
|
14
|
+
raise ValueError("seed must be a valid scalar value for the curve")
|
|
15
|
+
|
|
16
|
+
check_participant_bounds(threshold, participant_ids, curve.scalar_ops)
|
|
17
|
+
|
|
18
|
+
self._seed = seed
|
|
19
|
+
self.PARTICIPANT_IDS: Final[list[ParticipantId]] = participant_ids
|
|
20
|
+
self._PARTICIPANT_CONNECTIONS: Final[dict[ParticipantId, Callable[[SecretShare, list[VSSCommitment]], None]]] = participant_connections
|
|
21
|
+
self._COORDINATOR_CONNECTION: Final[Callable[[list[VSSCommitment]], None]] = coordinator_connection
|
|
22
|
+
self._CURVE: Final[EdwardsCurve] = curve
|
|
23
|
+
|
|
24
|
+
# In the future, we may want to support other secret sharing schemes
|
|
25
|
+
self._SECRET_SHARING: Final[ShamirSecretSharing] = ShamirSecretSharing(threshold, len(self.PARTICIPANT_IDS), self._CURVE.scalar_ops)
|
|
26
|
+
|
|
27
|
+
def keygen(self):
|
|
28
|
+
"""
|
|
29
|
+
Trusted dealer key generation.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
shares, coeffs = self._SECRET_SHARING.split(self._seed)
|
|
33
|
+
|
|
34
|
+
vss_commitment = self._vss_commit(coeffs)
|
|
35
|
+
|
|
36
|
+
for participant_id, share in zip(self.PARTICIPANT_IDS, shares):
|
|
37
|
+
if participant_id in self._PARTICIPANT_CONNECTIONS:
|
|
38
|
+
self._PARTICIPANT_CONNECTIONS[participant_id](share, vss_commitment)
|
|
39
|
+
else:
|
|
40
|
+
raise ValueError(f"No connection provided for participant {participant_id}")
|
|
41
|
+
|
|
42
|
+
if self._COORDINATOR_CONNECTION:
|
|
43
|
+
self._COORDINATOR_CONNECTION(vss_commitment)
|
|
44
|
+
|
|
45
|
+
# clear seed, shares, coeffs from memory after key generation, MUST not be reused for another keygen session
|
|
46
|
+
self._seed = -1
|
|
47
|
+
shares.clear()
|
|
48
|
+
coeffs.clear()
|
|
49
|
+
|
|
50
|
+
@classmethod
|
|
51
|
+
def from_private_bytes(cls, seed: int, threshold: int, participant_ids: list[ParticipantId], participant_connections: dict[ParticipantId, Callable[[SecretShare, list[VSSCommitment]], None]], coordinator_connection: Callable[[list[VSSCommitment]], None], curve: EdwardsCurve) -> FrostTrustedDealer:
|
|
52
|
+
"""Create a dealer instance from the given private seed bytes."""
|
|
53
|
+
return cls(seed, threshold, participant_ids, participant_connections, coordinator_connection, curve)
|
|
54
|
+
|
|
55
|
+
@classmethod
|
|
56
|
+
def generate(cls, threshold: int, participant_ids: list[ParticipantId], participant_connections: dict[ParticipantId, Callable[[SecretShare, list[VSSCommitment]], None]], coordinator_connection: Callable[[list[VSSCommitment]], None], curve: EdwardsCurve) -> FrostTrustedDealer:
|
|
57
|
+
"""Generate a new dealer instance with a fresh secret."""
|
|
58
|
+
seed = curve.scalar_ops.random_scalar()
|
|
59
|
+
return cls(seed, threshold, participant_ids, participant_connections, coordinator_connection, curve)
|
|
60
|
+
|
|
61
|
+
def _vss_commit(self, coeffs: list[int]) -> list[VSSCommitment]:
|
|
62
|
+
"""
|
|
63
|
+
Generates a VSS commitment from the given polynomial coefficients.
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
vss_commitment = []
|
|
67
|
+
|
|
68
|
+
for coeff in coeffs:
|
|
69
|
+
vss_i = self._CURVE.scalar_mult(coeff, None)
|
|
70
|
+
vss_commitment.append(vss_i)
|
|
71
|
+
|
|
72
|
+
return vss_commitment
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: eddsa-threshold
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Educational EdDSA and FROST implementations
|
|
5
|
+
Author-email: Maximilian <23641084+xfallme@users.noreply.github.com>
|
|
6
|
+
License-Expression: 0BSD
|
|
7
|
+
Project-URL: Homepage, https://github.com/xfallme/EdDSA-Threshold
|
|
8
|
+
Project-URL: Repository, https://github.com/xfallme/EdDSA-Threshold
|
|
9
|
+
Project-URL: Issues, https://github.com/xfallme/EdDSA-Threshold/issues
|
|
10
|
+
Keywords: cryptography,threshold,eddsa,frost
|
|
11
|
+
Requires-Python: >=3.14
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Provides-Extra: dev
|
|
15
|
+
Requires-Dist: black>=26.5; extra == "dev"
|
|
16
|
+
Requires-Dist: mypy>=2.1; extra == "dev"
|
|
17
|
+
Requires-Dist: pytest==9.0.3; extra == "dev"
|
|
18
|
+
Requires-Dist: pytest-cases==3.10.1; extra == "dev"
|
|
19
|
+
Requires-Dist: pytest-mock==3.15.1; extra == "dev"
|
|
20
|
+
Requires-Dist: ruff>=0.15; extra == "dev"
|
|
21
|
+
Requires-Dist: pynacl>=1.6.2; extra == "dev"
|
|
22
|
+
Dynamic: license-file
|
|
23
|
+
|
|
24
|
+
# EdDSA (Threshold)
|
|
25
|
+
|
|
26
|
+
> [!CAUTION]
|
|
27
|
+
> This project is a strictly educational implementation of the EdDSA standard and FROST algorithm. This means it is NOT PRODUCTION READY at the moment.
|
|
28
|
+
> And will likely never be.
|
|
29
|
+
|
|
30
|
+
This repository contains two different but linked implementations. The first is a "normal" single- party DSA, in this case EdDSA. The second is a multi-party threshold signature scheme, namely FROST.
|
|
31
|
+
|
|
32
|
+
## EdDSA
|
|
33
|
+
|
|
34
|
+
Although this implementation is strictly educational, it follows the standard for EdDSA as specified in [RFC 8032](https://datatracker.ietf.org/doc/html/rfc8032).
|
|
35
|
+
|
|
36
|
+
## FROST
|
|
37
|
+
|
|
38
|
+
FROST is a bit different, there is no standard (yet) and the [RFC 9591](https://datatracker.ietf.org/doc/html/rfc9591) is strictly informational.
|
|
39
|
+
Also, the RFC defines multiple instantiations for FROST, however this package only implements the version compatible with [Ed25519](https://datatracker.ietf.org/doc/html/rfc9591#name-frosted25519-sha-512) and [Ed448](https://datatracker.ietf.org/doc/html/rfc9591#name-frosted448-shake256) since the focus of the corresponding Master Thesis is on backwards compatibility in regards to the verification.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
eddsa_threshold/__init__.py,sha256=lfKASrNz00_628laptQbdv7sb118Ltk-7n9xu3xsVHk,30
|
|
2
|
+
eddsa_threshold/eddsa/__init__.py,sha256=8n4W6uj_mIwQyz4TXVbvDVtuOEE07EP_Xu6hWaJeYsk,23
|
|
3
|
+
eddsa_threshold/eddsa/algorithms/__init__.py,sha256=OgSLr3-cQJ1findSBT_K0XjwQp7vc448RZwEGtQKqeA,31
|
|
4
|
+
eddsa_threshold/eddsa/algorithms/ed25519.py,sha256=FjG6ADGPlRD_VO51F9k5uAJcHRhcLPwHsqgaWqnODmI,3179
|
|
5
|
+
eddsa_threshold/eddsa/algorithms/ed25519ctx.py,sha256=psIu67FKXCuyLMt4Ww58UIQTn9-gJgTKwyBDwp5vjUs,1034
|
|
6
|
+
eddsa_threshold/eddsa/algorithms/ed25519ph.py,sha256=kB8dnedMRvn2AZP7cPDyFrHsi9Kp6ORf-Gjx8lUfpdk,1065
|
|
7
|
+
eddsa_threshold/eddsa/algorithms/ed448.py,sha256=eussmwjgoGWYRbJdIABOJNQHJBgNA28FSRsqhUQkG-E,3232
|
|
8
|
+
eddsa_threshold/eddsa/algorithms/ed448ph.py,sha256=0VgopcxQ3af98I1tzPZHwO6cRWgnnPfOmgsZccwm8-c,957
|
|
9
|
+
eddsa_threshold/eddsa/curves/__init__.py,sha256=IK7ljKkfDzfkCDEP4EFJtMT1-gInReCqjUG01pPgFRk,28
|
|
10
|
+
eddsa_threshold/eddsa/curves/base/__init__.py,sha256=n9Lvy8LC7DEFjp1fMlF6GkJRKx-TNR0sa7Hqz2vfvw8,30
|
|
11
|
+
eddsa_threshold/eddsa/curves/base/edwards_curve.py,sha256=RUqMF7Vc5Qriovq733FqIMoswwzFj0zw0FpT92zCrgw,2927
|
|
12
|
+
eddsa_threshold/eddsa/curves/base/encoding.py,sha256=TXogRKFEGHItftu-H2Wx3UyyvF7L23osTWzBY2ZpxS8,1635
|
|
13
|
+
eddsa_threshold/eddsa/curves/base/field_ops.py,sha256=EJAA6iY7rw0ZUjh2-_--5fqWIY8qz3_jiDUB3uAHLvo,1350
|
|
14
|
+
eddsa_threshold/eddsa/curves/base/scalar_ops.py,sha256=4tgrqPs4zDSyyIkZXabNJ1bvBWBspXCxE5XewKi8m2c,956
|
|
15
|
+
eddsa_threshold/eddsa/curves/ed25519/__init__.py,sha256=EMBoAt4lBb-KykLhy1UZ8zXCEO5O8iCVQbMwW26loTc,35
|
|
16
|
+
eddsa_threshold/eddsa/curves/ed25519/constants.py,sha256=LvXshRDSA3FE4O4qbw8yQap8WnEkUHxxBlUrSxgeapU,923
|
|
17
|
+
eddsa_threshold/eddsa/curves/ed25519/ed25519_curve.py,sha256=UrvAF85zumOiBFr7JJCEPr7iIWylUA6zK2SUd5G3TOg,2029
|
|
18
|
+
eddsa_threshold/eddsa/curves/ed25519/encoding.py,sha256=TLJJVi7C7-aqyd-JJFJ1r0ty7q6l61d4e8mTz9WiOeQ,2484
|
|
19
|
+
eddsa_threshold/eddsa/curves/ed25519/field_ops.py,sha256=LcQQEHPutCP6xGf95_u005Nj8F70BgxA20Ins56Q9i4,270
|
|
20
|
+
eddsa_threshold/eddsa/curves/ed25519/scalar_ops.py,sha256=9Ormd6XeCDuEMoluz6XZBtnr5Ff-RC_hAVa8UDiWbBI,268
|
|
21
|
+
eddsa_threshold/eddsa/curves/ed448/__init__.py,sha256=9FnwT1eOBgcskwR0H9GES_wNofjt2YTlm6qTxcw00dI,33
|
|
22
|
+
eddsa_threshold/eddsa/curves/ed448/constants.py,sha256=KuG2fwz4Vo6l_lrZ8CpS243H5KyXXIrVdJ5IyLMb-zU,1006
|
|
23
|
+
eddsa_threshold/eddsa/curves/ed448/ed448_curve.py,sha256=vE_UmOnK7nt0yTKaGKXWBq-zaNtZAJrFcXyWDJ73xks,1912
|
|
24
|
+
eddsa_threshold/eddsa/curves/ed448/encoding.py,sha256=oaTE56rgxQr96AJTlhY0dEwvsqbpqBKu935FW6aEs7s,2325
|
|
25
|
+
eddsa_threshold/eddsa/curves/ed448/field_ops.py,sha256=8MhjocTHJifeMJaTqRgYIRXeu6AyxTh29nWJOv80_Tg,273
|
|
26
|
+
eddsa_threshold/eddsa/curves/ed448/scalar_ops.py,sha256=AH2vUnaeyt1v22Ui18sG_ty327p0oTVJx2FOgB8Na0M,261
|
|
27
|
+
eddsa_threshold/eddsa/keys/__init__.py,sha256=OVoWR2WgDoEkOW2IpRRTWemWd4d3CVyrQVv4adGefSg,22
|
|
28
|
+
eddsa_threshold/eddsa/keys/ed25519_keypair.py,sha256=fTbCB1t6wcQ4gonFNiLQVXPpSTAuP8UwwfSCW4Rq8p4,1561
|
|
29
|
+
eddsa_threshold/eddsa/keys/ed448_keypair.py,sha256=gJm6CWhOA7ShqSm-PrJgYFN63mQHzv-wSctxr10VGmg,1554
|
|
30
|
+
eddsa_threshold/eddsa/keys/keypair.py,sha256=myvBx7qNMFVVhi30EVwtejhZwA83swvN4U2Rrqg0nEQ,1623
|
|
31
|
+
eddsa_threshold/eddsa/util/__init__.py,sha256=wFHlAEsRLfuekGImWHqi-_1OzvPYfDcbiRbSANgDuIM,22
|
|
32
|
+
eddsa_threshold/eddsa/util/dom.py,sha256=kqU7e0axroO2AZ2deh0qcuUPgltMfDJ6VqZdsloQ688,663
|
|
33
|
+
eddsa_threshold/eddsa/util/hash_bindings.py,sha256=KcKkMENtCLSMx118BBsFuMvZgPefOLEnic0wKivrZ60,349
|
|
34
|
+
eddsa_threshold/frost/__init__.py,sha256=iK_XjyEK_4ApFFNN6MRTYpH0Cpxqyy7axinGj3Q_aWs,36
|
|
35
|
+
eddsa_threshold/frost/coordinator.py,sha256=74JLPw7MntKmvjpiOGAcLEM-ceqsJJ_FC5fjKZOv0dI,7744
|
|
36
|
+
eddsa_threshold/frost/participant.py,sha256=jiS_XeVWV3to6UQsqKnzQgt-68OFO1JTyjxOh4RBgI4,6943
|
|
37
|
+
eddsa_threshold/frost/trusted_dealer.py,sha256=ndfwPyAiHE1D33z_4GUqwPEB0xagLNlUGTkFsWFJQfI,3878
|
|
38
|
+
eddsa_threshold/frost/core/__init__.py,sha256=1KX1Z_tlMEkLpDH6skCl_tb3rGjvhJ6VQOLBI8Oq5qo,28
|
|
39
|
+
eddsa_threshold/frost/core/frost_types.py,sha256=LYiowaolZn6yw-T3VJ-ho35vvuXvlkhkxWqBHah06yg,1253
|
|
40
|
+
eddsa_threshold/frost/core/polynomial.py,sha256=Hi4D7p4VBIYNcZe7nos-fgKy3eCQeKf6IZLKikweqZM,1132
|
|
41
|
+
eddsa_threshold/frost/core/util.py,sha256=o4O1x0lLGlgqprH52i_EdO1pRVKg_uV0haW-Fd9hQ5w,4924
|
|
42
|
+
eddsa_threshold/frost/core/base/__init__.py,sha256=0eFoCkRPKQ-l6UhQbp1y9w57QlemTj6XKfDXcDDdbtg,28
|
|
43
|
+
eddsa_threshold/frost/core/base/frost_hashing.py,sha256=qboXjQr36J0BVUg2SGpkLFzAl7Th2Dsw2peX0zRXgog,658
|
|
44
|
+
eddsa_threshold/frost/core/ed25519/__init__.py,sha256=A6MxasKrHxcl-dv1pu-YH8FhrjZI2Pvs7FgOm6cVJlU,37
|
|
45
|
+
eddsa_threshold/frost/core/ed25519/frost_hashing.py,sha256=zvvdrhyvAxQipkvOs5dUJcz3cNwE7iH2HmCCI8hQxbw,919
|
|
46
|
+
eddsa_threshold/frost/core/ed448/__init__.py,sha256=LePiRkQccNcBfHY8vve7jwZHNSyUbh65H7QJOhc2jDk,35
|
|
47
|
+
eddsa_threshold/frost/core/ed448/frost_hashing.py,sha256=sQpan2t6RI70lfkhT2NK8CZMY4O5M2cbj2J3lP07E6I,1078
|
|
48
|
+
eddsa_threshold/frost/core/secrets/__init__.py,sha256=QI-UHdD9Pyhhbd6mRwa2UX-8qBPlBtRTQ42seqc8wWw,29
|
|
49
|
+
eddsa_threshold/frost/core/secrets/secret_sharing.py,sha256=8YbTWSbO76DaBHymRvT8Ej3CVIVrTvxC8vtndF91BfE,854
|
|
50
|
+
eddsa_threshold/frost/core/secrets/shamir_secret_sharing.py,sha256=ntx1iPjPamTE_bWvWfEc2juVYHsTc4o9zrAgPdYgTJI,1767
|
|
51
|
+
eddsa_threshold-0.2.0.dist-info/licenses/LICENSE,sha256=GnTcxvPvk1nKBdI6c2txhYiKrz6d12VBluN9qN59_1w,660
|
|
52
|
+
eddsa_threshold-0.2.0.dist-info/METADATA,sha256=UrqBi1bH36ZGF1cl1nNnqcHNGRM8D9fqRmrqKiXFJJo,2054
|
|
53
|
+
eddsa_threshold-0.2.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
54
|
+
eddsa_threshold-0.2.0.dist-info/top_level.txt,sha256=iLKoOwo1o3ZOWfN1iZSY_M-Gr8kzE_Yc4v8K6wB9j0w,16
|
|
55
|
+
eddsa_threshold-0.2.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
BSD Zero Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 xfallme
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
purpose with or without fee is hereby granted.
|
|
7
|
+
|
|
8
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
9
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
10
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
11
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
12
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
13
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
14
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
eddsa_threshold
|