Skip to content

Commit d0a5eca

Browse files
committed
fix: python typing issues
1 parent 7acac5e commit d0a5eca

File tree

5 files changed

+107
-46
lines changed

5 files changed

+107
-46
lines changed

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

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from __future__ import annotations
12
from dataclasses import dataclass
23
from typing import Optional, Tuple
34

@@ -6,20 +7,15 @@
67
from nacl.public import PrivateKey as ImplPrivateKey
78

89
from nacl.signing import SigningKey, VerifyKey
9-
from nacl.encoding import HexEncoder
10+
from nacl.encoding import HexEncoder, Encoder
1011
from synlink.crypto.exception import (
1112
CryptoBaseException,
1213
SignatureVerificationError,
1314
)
1415
from synlink.crypto.kind import Kind
1516
from synlink.crypto.typing import PrivateKey as IPrivateKey
1617
from synlink.crypto.typing import PublicKey as IPublicKey
17-
from synlink.utils import _check_minimum_version
18-
19-
if _check_minimum_version(3, 11, 0):
20-
from typing import Self
21-
else:
22-
from typing_extensions import Self
18+
from synlink.crypto.typing import KeyPair as IKeyPair
2319

2420
Message = bytes
2521
Signiture = bytes
@@ -32,6 +28,7 @@
3228
"create_new_ed25519_key_pair_from_seed",
3329
]
3430

31+
3532
class PublicKey(IPublicKey):
3633
"""
3734
Represents an ED25519 public key, providing methods for verification
@@ -45,26 +42,29 @@ def __init__(self, impl: VerifyKey):
4542
Args:
4643
impl: An instance of nacl.signing.VerifyKey.
4744
"""
48-
super().__init__()
4945
self._impl: VerifyKey = impl
5046
self._kind = Kind.ED25519
47+
5148
def get_kind(self) -> Kind:
5249
"""
5350
Returns the kind of this cryptographic key.
5451
"""
5552
return self._kind
53+
5654
def to_bytes(self) -> bytes:
5755
"""
5856
Converts the public key to its raw byte representation.
5957
"""
6058
return bytes(self._impl)
59+
6160
def __bytes__(self) -> bytes:
6261
"""
6362
Allows the PublicKey object to be converted to bytes using bytes().
6463
"""
6564
return self.to_bytes()
65+
6666
@classmethod
67-
def from_bytes(cls, data: bytes) -> Self:
67+
def from_bytes(cls, data: bytes) -> "PublicKey":
6868
"""
6969
Creates a PublicKey object from its raw byte representation.
7070
@@ -75,6 +75,7 @@ def from_bytes(cls, data: bytes) -> Self:
7575
A new PublicKey instance.
7676
"""
7777
return cls(VerifyKey(data))
78+
7879
def try_verify(self, data: bytes, signature: bytes) -> bool:
7980
"""
8081
Attempts to verify the signature against the signed message.
@@ -97,6 +98,7 @@ def try_verify(self, data: bytes, signature: bytes) -> bool:
9798
raise SignatureVerificationError(f"{e}") from e
9899
except Exception as e:
99100
raise CryptoBaseException(f"{e}") from e
101+
100102
def verify(self, data: bytes, signature: bytes) -> bool:
101103
"""
102104
Verifies the signature against the signed message.
@@ -114,26 +116,31 @@ def verify(self, data: bytes, signature: bytes) -> bool:
114116
return True
115117
except BadSignatureError:
116118
return False
117-
except Exception as e:
119+
except Exception:
118120
# Catch other potential exceptions during verification
119121
# print(f"An unexpected error occurred during verification: {e}") # For debugging
120122
return False
123+
121124
def __str__(self) -> str:
122125
"""
123126
Returns a human-readable string representation of the public key.
124127
"""
125-
output = self._impl.encode(encoder=HexEncoder()).decode("utf-8")
128+
encoder: Encoder = HexEncoder
129+
output = self._impl.encode(encoder).decode("utf-8")
126130
return f"PublicKey({output})"
131+
127132
def __repr__(self) -> str:
128133
"""
129134
Returns a detailed string representation for debugging.
130135
"""
131-
output = self._impl.encode(encoder=HexEncoder()).decode("utf-8")
136+
encoder: Encoder = HexEncoder
137+
output = self._impl.encode(encoder).decode("utf-8")
132138
# Show a truncated hex representation for brevity in repr
133139
return (
134140
f"<synlink.crypto.ed25519.PublicKey {output[:8]}...{output[-8:]}>"
135141
)
136142

143+
137144
class PrivateKey(IPrivateKey):
138145
"""
139146
Represents an ED25519 private key, providing methods for signing
@@ -147,16 +154,17 @@ def __init__(self, impl: SigningKey):
147154
Args:
148155
impl: An instance of nacl.signing.SigningKey.
149156
"""
150-
super().__init__()
151157
self._kind = Kind.ED25519
152158
self._impl: SigningKey = impl
159+
153160
def get_kind(self) -> Kind:
154161
"""
155162
Returns the kind of this cryptographic key.
156163
"""
157164
return self._kind
165+
158166
@classmethod
159-
def generate(cls) -> Self:
167+
def generate(cls) -> "PrivateKey":
160168
"""
161169
Generates a new random ED25519 private key.
162170
@@ -165,8 +173,9 @@ def generate(cls) -> Self:
165173
"""
166174
impl = SigningKey.generate()
167175
return cls(impl)
176+
168177
@classmethod
169-
def from_seed(cls, seed: Optional[bytes] = None) -> Self:
178+
def from_seed(cls, seed: Optional[bytes] = None) -> "PrivateKey":
170179
"""
171180
Generates an ED25519 private key from a 32-byte seed.
172181
@@ -189,8 +198,9 @@ def from_seed(cls, seed: Optional[bytes] = None) -> Self:
189198
), "PrivateKey seed must be a 32 bytes long binary sequence"
190199
impl = ImplPrivateKey.from_seed(seed)
191200
return cls(SigningKey(bytes(impl)))
201+
192202
@classmethod
193-
def from_bytes(cls, data: bytes) -> Self:
203+
def from_bytes(cls, data: bytes) -> "PrivateKey":
194204
"""
195205
Creates an ED25519 private key from its raw byte representation.
196206
@@ -202,6 +212,7 @@ def from_bytes(cls, data: bytes) -> Self:
202212
"""
203213
impl = SigningKey(data)
204214
return cls(impl)
215+
205216
def get_public_key(self) -> IPublicKey:
206217
"""
207218
Returns the public key corresponding to this private key.
@@ -210,6 +221,7 @@ def get_public_key(self) -> IPublicKey:
210221
raise CryptoBaseException("Invalid private key implementation.")
211222
# Return a PublicKey wrapping the VerifyKey derived from this SigningKey
212223
return PublicKey(self._impl.verify_key)
224+
213225
def sign(self, data: bytes) -> Tuple[Message, Signiture]:
214226
"""
215227
Signs data with the private key and returns the raw signature.
@@ -225,37 +237,42 @@ def sign(self, data: bytes) -> Tuple[Message, Signiture]:
225237
# Direct signing using the wrapped SigningKey
226238
signed_message = self._impl.sign(data)
227239
return signed_message.message, signed_message.signature
240+
228241
def to_bytes(self) -> bytes:
229242
"""
230243
Converts the private key to its raw byte representation.
231244
"""
232245
return bytes(self._impl)
246+
233247
def __bytes__(self) -> bytes:
234248
"""
235249
Allows the PrivateKey object to be converted to bytes using bytes().
236250
"""
237251
return self.to_bytes()
252+
238253
def __str__(self) -> str:
239254
"""
240255
Returns a human-readable string representation of the private key.
241256
"""
242257
# For security, avoid showing private key material in str.
243258
return "PrivateKey(ED25519)"
259+
244260
def __repr__(self) -> str:
245261
"""
246262
Returns a detailed string representation for debugging.
247263
"""
248264
# For security, avoid showing private key material in repr.
249265
return "<synlink.crypto.ed25519.PrivateKey>"
250266

267+
251268
@dataclass(frozen=True, repr=False)
252-
class KeyPair(object):
269+
class KeyPair(IKeyPair):
253270
"""
254271
Represents an ED25519 key pair, containing both a private and public key.
255272
"""
256273

257274
secret: PrivateKey
258-
public: PublicKey
275+
public: IPublicKey
259276

260277
def try_verify(self, message: bytes, signature: bytes) -> bool:
261278
"""
@@ -273,6 +290,7 @@ def try_verify(self, message: bytes, signature: bytes) -> bool:
273290
Exception: base class for all non-exit exceptions.
274291
"""
275292
return self.public.try_verify(data=message, signature=signature)
293+
276294
def verify(self, message: bytes, signature: bytes) -> bool:
277295
"""
278296
Verifies the signature against the signed message.
@@ -288,6 +306,7 @@ def verify(self, message: bytes, signature: bytes) -> bool:
288306
return self.public.verify(data=message, signature=signature)
289307
except BadSignatureError:
290308
return False
309+
291310
def sign(self, message: bytes) -> Tuple[Message, Signiture]:
292311
"""
293312
Signs data with the private key and returns the raw signature.
@@ -299,18 +318,21 @@ def sign(self, message: bytes) -> Tuple[Message, Signiture]:
299318
The raw signature bytes.
300319
"""
301320
return self.secret.sign(data=message)
321+
302322
def __bytes__(self) -> bytes:
303323
"""
304324
Returns the raw bytes of the secret (private) key.
305325
"""
306326
return bytes(self.secret)
327+
307328
def __repr__(self) -> str:
308329
"""
309330
Returns a detailed string representation for debugging.
310331
"""
311332
# Include the public key's repr for better context
312333
return f"<synlink.crypto.ed25519.KeyPair public={self.public!s}>"
313334

335+
314336
def create_new_ed25519_key_pair() -> KeyPair:
315337
"""
316338
Creates a new ED25519 key pair with randomly generated keys.
@@ -320,7 +342,8 @@ def create_new_ed25519_key_pair() -> KeyPair:
320342
"""
321343
secret = PrivateKey.generate()
322344
public = secret.get_public_key()
323-
return KeyPair(secret, public)
345+
return KeyPair(secret=secret, public=public)
346+
324347

325348
def create_new_ed25519_key_pair_from_seed(
326349
seed: Optional[bytes] = None,
@@ -338,4 +361,4 @@ def create_new_ed25519_key_pair_from_seed(
338361
"""
339362
secret: PrivateKey = PrivateKey.from_seed(seed)
340363
public = secret.get_public_key()
341-
return KeyPair(secret, public)
364+
return KeyPair(secret=secret, public=public)

binding/python/py/synlink/crypto/exception.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
from synlink.error import SynlinkBaseException
22

3+
34
class CryptoBaseException(SynlinkBaseException):
45
"""Base exception for all cryptographic errors."""
56

67
pass
78

9+
810
class SignatureVerificationError(CryptoBaseException):
911
"""Raised when signature verification fails."""
1012

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

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import os
2-
import pathlib
32

4-
from typing import Union, Optional
3+
from typing import Union, Optional, Final
54

65
from cryptography.hazmat.primitives import serialization
76
from cryptography.hazmat.primitives.asymmetric import (
@@ -10,11 +9,10 @@
109

1110
import synlink.crypto.ed25519 as ed25519
1211
from synlink.crypto.typing import KeyPair
12+
from synlink.utils import HOME_DIR
1313

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

17-
__all__ = ["load_open_ssh_private_key"]
1816

1917
def load_ssh_private_key(
2018
file: Union[str, os.PathLike] = SSH_DEFAULT_DIRECTORY,
@@ -54,4 +52,4 @@ def load_ssh_private_key(
5452
public = secret.get_public_key()
5553
return ed25519.KeyPair(secret=secret, public=public)
5654
else:
57-
raise NotImplemented
55+
raise NotImplementedError("key type is not implmented.")
Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
from enum import Enum
2-
from functools import cache
2+
33

44
class Kind(Enum):
5-
ED25519: int = 0
5+
ED25519 = 0
66

77
def to_string(self) -> str:
88
"""return the name of the crypto kind."""
99
return self.name
10+
1011
def to_bytes(self) -> bytes:
1112
return self.value.to_bytes(1, byteorder="little")
13+
1214
@classmethod
1315
def from_bytes(cls, data: bytes) -> "Kind":
1416
"""return kind from the byte(s)"""
@@ -18,17 +20,22 @@ def from_bytes(cls, data: bytes) -> "Kind":
1820
elif num < cls.min():
1921
raise ValueError(f"bytes shound not be less then {cls.min()}")
2022
return cls(num)
23+
2124
@staticmethod
2225
def max() -> int:
2326
"""return the maximum possible enumeration number."""
2427
return 0
28+
2529
@staticmethod
2630
def min() -> int:
2731
"""return the maximum possible enumeration number."""
2832
return 0
33+
2934
def __bytes__(self) -> bytes:
3035
return self.to_bytes()
36+
3137
def __str__(self) -> str:
3238
return self.to_string()
39+
3340
def __repr__(self) -> str:
3441
return f"<synlink.crypto.kind kind={self}>"

0 commit comments

Comments
 (0)