Skip to content

Commit 50ca3f2

Browse files
committed
style: apply black lint
1 parent 6d0f49d commit 50ca3f2

File tree

5 files changed

+103
-91
lines changed

5 files changed

+103
-91
lines changed

binding/python/py/synlink/crypto/ed25519.py

Lines changed: 83 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@
77

88
from nacl.signing import SigningKey, VerifyKey
99
from nacl.encoding import HexEncoder
10-
from synlink.crypto.exception import CryptoException
10+
from synlink.crypto.exception import (
11+
CryptoBaseException,
12+
SignatureVerificationError,
13+
)
1114
from synlink.crypto.kind import Kind
1215
from synlink.crypto.typing import PrivateKey as IPrivateKey
1316
from synlink.crypto.typing import PublicKey as IPublicKey
@@ -21,16 +24,20 @@
2124
Message = bytes
2225
Signiture = bytes
2326

24-
__all__ = ["PublicKey", "PrivateKey", "KeyPair", "create_new_ed25519_key_pair",
25-
"create_new_ed25519_key_pair_from_seed"]
26-
27-
27+
__all__ = [
28+
"PublicKey",
29+
"PrivateKey",
30+
"KeyPair",
31+
"create_new_ed25519_key_pair",
32+
"create_new_ed25519_key_pair_from_seed",
33+
]
2834

2935
class PublicKey(IPublicKey):
3036
"""
3137
Represents an ED25519 public key, providing methods for verification
3238
and various conversions. This class wraps nacl.signing.VerifyKey.
3339
"""
40+
3441
def __init__(self, impl: VerifyKey):
3542
"""
3643
Initializes a PublicKey object.
@@ -41,25 +48,21 @@ def __init__(self, impl: VerifyKey):
4148
super().__init__()
4249
self._impl: VerifyKey = impl
4350
self._kind = Kind.ED25519
44-
4551
def get_kind(self) -> Kind:
4652
"""
4753
Returns the kind of this cryptographic key.
4854
"""
4955
return self._kind
50-
5156
def to_bytes(self) -> bytes:
5257
"""
5358
Converts the public key to its raw byte representation.
5459
"""
5560
return bytes(self._impl)
56-
5761
def __bytes__(self) -> bytes:
5862
"""
5963
Allows the PublicKey object to be converted to bytes using bytes().
6064
"""
6165
return self.to_bytes()
62-
6366
@classmethod
6467
def from_bytes(cls, data: bytes) -> Self:
6568
"""
@@ -72,7 +75,28 @@ def from_bytes(cls, data: bytes) -> Self:
7275
A new PublicKey instance.
7376
"""
7477
return cls(VerifyKey(data))
78+
def try_verify(self, data: bytes, signature: bytes) -> bool:
79+
"""
80+
Attempts to verify the signature against the signed message.
81+
82+
Args:
83+
data: The original message bytes that were signed.
84+
signature: The raw signature bytes.
85+
86+
Returns:
87+
True if the signature is valid.
7588
89+
Raises:
90+
SignatureVerificationError: If the signature is forged or corrupt.
91+
CryptoBaseException: For other unexpected verification errors.
92+
"""
93+
try:
94+
self._impl.verify(data, signature)
95+
return True
96+
except BadSignatureError as e:
97+
raise SignatureVerificationError(f"{e}") from e
98+
except Exception as e:
99+
raise CryptoBaseException(f"{e}") from e
76100
def verify(self, data: bytes, signature: bytes) -> bool:
77101
"""
78102
Verifies the signature against the signed message.
@@ -94,31 +118,28 @@ def verify(self, data: bytes, signature: bytes) -> bool:
94118
# Catch other potential exceptions during verification
95119
# print(f"An unexpected error occurred during verification: {e}") # For debugging
96120
return False
97-
98-
99121
def __str__(self) -> str:
100122
"""
101123
Returns a human-readable string representation of the public key.
102124
"""
103-
output = self._impl \
104-
.encode(encoder=HexEncoder()) \
105-
.decode('utf-8')
125+
output = self._impl.encode(encoder=HexEncoder()).decode("utf-8")
106126
return f"PublicKey({output})"
107-
108127
def __repr__(self) -> str:
109128
"""
110129
Returns a detailed string representation for debugging.
111130
"""
112-
output = self._impl.encode(encoder=HexEncoder()).decode('utf-8')
131+
output = self._impl.encode(encoder=HexEncoder()).decode("utf-8")
113132
# Show a truncated hex representation for brevity in repr
114-
return f"<synlink.crypto.ed25519.PublicKey {output[:8]}...{output[-8:]}>"
115-
133+
return (
134+
f"<synlink.crypto.ed25519.PublicKey {output[:8]}...{output[-8:]}>"
135+
)
116136

117137
class PrivateKey(IPrivateKey):
118138
"""
119139
Represents an ED25519 private key, providing methods for signing
120140
and various conversions. This class wraps nacl.signing.SigningKey.
121141
"""
142+
122143
def __init__(self, impl: SigningKey):
123144
"""
124145
Initializes a PrivateKey object.
@@ -129,13 +150,11 @@ def __init__(self, impl: SigningKey):
129150
super().__init__()
130151
self._kind = Kind.ED25519
131152
self._impl: SigningKey = impl
132-
133153
def get_kind(self) -> Kind:
134154
"""
135155
Returns the kind of this cryptographic key.
136156
"""
137157
return self._kind
138-
139158
@classmethod
140159
def generate(cls) -> Self:
141160
"""
@@ -146,7 +165,6 @@ def generate(cls) -> Self:
146165
"""
147166
impl = SigningKey.generate()
148167
return cls(impl)
149-
150168
@classmethod
151169
def from_seed(cls, seed: Optional[bytes] = None) -> Self:
152170
"""
@@ -171,7 +189,6 @@ def from_seed(cls, seed: Optional[bytes] = None) -> Self:
171189
), "PrivateKey seed must be a 32 bytes long binary sequence"
172190
impl = ImplPrivateKey.from_seed(seed)
173191
return cls(SigningKey(bytes(impl)))
174-
175192
@classmethod
176193
def from_bytes(cls, data: bytes) -> Self:
177194
"""
@@ -185,16 +202,14 @@ def from_bytes(cls, data: bytes) -> Self:
185202
"""
186203
impl = SigningKey(data)
187204
return cls(impl)
188-
189205
def get_public_key(self) -> IPublicKey:
190206
"""
191207
Returns the public key corresponding to this private key.
192208
"""
193209
if not isinstance(self._impl, SigningKey):
194-
raise CryptoException("Invalid private key implementation.")
210+
raise CryptoBaseException("Invalid private key implementation.")
195211
# Return a PublicKey wrapping the VerifyKey derived from this SigningKey
196212
return PublicKey(self._impl.verify_key)
197-
198213
def sign(self, data: bytes) -> Tuple[Message, Signiture]:
199214
"""
200215
Signs data with the private key and returns the raw signature.
@@ -206,76 +221,95 @@ def sign(self, data: bytes) -> Tuple[Message, Signiture]:
206221
The raw signature bytes.
207222
"""
208223
if not isinstance(self._impl, SigningKey):
209-
raise CryptoException("Invalid private key implementation.")
224+
raise CryptoBaseException("Invalid private key implementation.")
210225
# Direct signing using the wrapped SigningKey
211226
signed_message = self._impl.sign(data)
212227
return signed_message.message, signed_message.signature
213-
214228
def to_bytes(self) -> bytes:
215229
"""
216230
Converts the private key to its raw byte representation.
217231
"""
218232
return bytes(self._impl)
219-
220233
def __bytes__(self) -> bytes:
221234
"""
222235
Allows the PrivateKey object to be converted to bytes using bytes().
223236
"""
224237
return self.to_bytes()
225-
226238
def __str__(self) -> str:
227239
"""
228240
Returns a human-readable string representation of the private key.
229241
"""
230242
# For security, avoid showing private key material in str.
231243
return "PrivateKey(ED25519)"
232-
233244
def __repr__(self) -> str:
234245
"""
235246
Returns a detailed string representation for debugging.
236247
"""
237248
# For security, avoid showing private key material in repr.
238249
return "<synlink.crypto.ed25519.PrivateKey>"
239250

240-
241251
@dataclass(frozen=True, repr=False)
242252
class KeyPair(object):
243253
"""
244254
Represents an ED25519 key pair, containing both a private and public key.
245255
"""
246-
secret : PrivateKey
247-
public : PublicKey
248256

249-
def try_verify(self, message : bytes, signature : bytes) -> bool:
250-
try:
251-
return self.public.verify(data=message, signature=signature)
252-
except BadSignatureError as e:
253-
raise e
257+
secret: PrivateKey
258+
public: PublicKey
259+
260+
def try_verify(self, message: bytes, signature: bytes) -> bool:
261+
"""
262+
Try to verifies the signature against the signed message.
263+
264+
Args:
265+
data: The original message bytes that were signed.
266+
signature: The raw signature bytes.
254267
255-
def verify(self, message : bytes, signature : bytes) -> bool:
268+
Returns:
269+
Always True if the signature is valid.
270+
271+
Rasies:
272+
BadSignatureError: Signature was forged or otherwise corrupt.
273+
Exception: base class for all non-exit exceptions.
274+
"""
275+
return self.public.try_verify(data=message, signature=signature)
276+
def verify(self, message: bytes, signature: bytes) -> bool:
277+
"""
278+
Verifies the signature against the signed message.
279+
280+
Args:
281+
data: The original message bytes that were signed.
282+
signature: The raw signature bytes.
283+
284+
Returns:
285+
True if the signature is valid, False otherwise.
286+
"""
256287
try:
257288
return self.public.verify(data=message, signature=signature)
258289
except BadSignatureError:
259290
return False
291+
def sign(self, message: bytes) -> Tuple[Message, Signiture]:
292+
"""
293+
Signs data with the private key and returns the raw signature.
260294
261-
def sign(self, message : bytes) -> Tuple[Message, Signiture]:
262-
return self.secret.sign(
263-
data=message
264-
)
295+
Args:
296+
data: The message bytes to sign.
265297
298+
Returns:
299+
The raw signature bytes.
300+
"""
301+
return self.secret.sign(data=message)
266302
def __bytes__(self) -> bytes:
267303
"""
268304
Returns the raw bytes of the secret (private) key.
269305
"""
270306
return bytes(self.secret)
271-
272307
def __repr__(self) -> str:
273308
"""
274309
Returns a detailed string representation for debugging.
275310
"""
276311
# Include the public key's repr for better context
277-
return f"<synlink.crypto.ed25519.KeyPair public={self.public!r}>"
278-
312+
return f"<synlink.crypto.ed25519.KeyPair public={self.public!s}>"
279313

280314
def create_new_ed25519_key_pair() -> KeyPair:
281315
"""
@@ -288,8 +322,9 @@ def create_new_ed25519_key_pair() -> KeyPair:
288322
public = secret.get_public_key()
289323
return KeyPair(secret, public)
290324

291-
292-
def create_new_ed25519_key_pair_from_seed(seed: Optional[bytes] = None) -> KeyPair:
325+
def create_new_ed25519_key_pair_from_seed(
326+
seed: Optional[bytes] = None,
327+
) -> KeyPair:
293328
"""
294329
Creates a new ED25519 key pair from an optional 32-byte seed.
295330
Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
from synlink.error import SynlinkBaseException
22

3+
class CryptoBaseException(SynlinkBaseException):
4+
"""Base exception for all cryptographic errors."""
5+
6+
pass
7+
8+
class SignatureVerificationError(CryptoBaseException):
9+
"""Raised when signature verification fails."""
310

4-
class CryptoException(SynlinkBaseException):
511
pass

binding/python/py/synlink/crypto/io.py

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,35 @@
1-
21
import os
32
import pathlib
43

54
from typing import Union, Optional
65

76
from cryptography.hazmat.primitives import serialization
87
from cryptography.hazmat.primitives.asymmetric import (
9-
ed25519 as ED25519,
8+
ed25519 as ED25519,
109
)
1110

1211
import synlink.crypto.ed25519 as ed25519
1312
from synlink.crypto.typing import KeyPair
1413

15-
HOME_DIR : str = pathlib.Path.home().__str__()
14+
HOME_DIR: str = pathlib.Path.home().__str__()
1615
SSH_DEFAULT_DIRECTORY = os.path.join(HOME_DIR, ".ssh")
1716

1817
__all__ = ["load_open_ssh_private_key"]
1918

2019
def load_ssh_private_key(
21-
file : Union[str, os.PathLike] = SSH_DEFAULT_DIRECTORY,
22-
password : Optional[Union[str, bytes]] = None,
23-
) -> KeyPair:
20+
file: Union[str, os.PathLike] = SSH_DEFAULT_DIRECTORY,
21+
password: Optional[Union[str, bytes]] = None,
22+
) -> KeyPair:
2423
"""Load private key from OpenSSL custom encoding, and reconstruct
2524
key pair.
26-
25+
2726
Args:
2827
ssh_dir: Path to SSH directory (default: ~/.ssh)
2928
key_name: Base name of key files (default: id_rsa)
30-
29+
3130
Returns:
3231
KeyPair containing the loaded public and private keys
33-
32+
3433
Raises:
3534
FileNotFoundError: If key files don't exist
3635
ValueError: If keys are malformed or incompatible
@@ -51,9 +50,7 @@ def load_ssh_private_key(
5150
)
5251

5352
if isinstance(buffer, ED25519.Ed25519PrivateKey):
54-
secret = ed25519.PrivateKey.from_bytes(
55-
buffer.private_bytes_raw()
56-
)
53+
secret = ed25519.PrivateKey.from_bytes(buffer.private_bytes_raw())
5754
public = secret.get_public_key()
5855
return ed25519.KeyPair(secret=secret, public=public)
5956
else:

0 commit comments

Comments
 (0)