1+ """This module handles private key operations for ECDSA and Ed25519."""
12import warnings
23from typing import Optional , Union
34
@@ -13,13 +14,15 @@ class PrivateKey:
1314 """
1415
1516 def __init__ (
16- self ,
17+ self ,
1718 private_key : Union [ec .EllipticCurvePrivateKey , ed25519 .Ed25519PrivateKey ]
1819 ) -> None :
1920 """
2021 Initializes a PrivateKey from a cryptography PrivateKey object.
2122 """
22- self ._private_key : Union [ec .EllipticCurvePrivateKey , ed25519 .Ed25519PrivateKey ] = private_key
23+ self ._private_key : Union [
24+ ec .EllipticCurvePrivateKey , ed25519 .Ed25519PrivateKey
25+ ] = private_key
2326
2427 #
2528 # ---------------------------------
@@ -42,9 +45,8 @@ def from_string(cls, key_str: str) -> "PrivateKey":
4245
4346 try :
4447 key_bytes = bytes .fromhex (key_str )
45- except ValueError :
46- raise ValueError (f"Invalid hex string for private key: { key_str } " )
47-
48+ except ValueError as exc :
49+ raise ValueError (f"Invalid hex string for private key: { key_str } " ) from exc
4850 return cls .from_bytes (key_bytes )
4951
5052 @classmethod
@@ -56,8 +58,8 @@ def from_string_ed25519(cls, hex_str: str) -> "PrivateKey":
5658 hex_str = hex_str .removeprefix ("0x" )
5759 try :
5860 key_bytes = bytes .fromhex (hex_str )
59- except ValueError :
60- raise ValueError (f"Invalid hex string for Ed25519 private key: { hex_str } " )
61+ except ValueError as exc :
62+ raise ValueError (f"Invalid hex string for Ed25519 private key: { hex_str } " ) from exc
6163 return cls .from_bytes_ed25519 (key_bytes )
6264
6365 @classmethod
@@ -69,8 +71,8 @@ def from_string_ecdsa(cls, hex_str: str) -> "PrivateKey":
6971 hex_str = hex_str .removeprefix ("0x" )
7072 try :
7173 key_bytes = bytes .fromhex (hex_str )
72- except ValueError :
73- raise ValueError (f"Invalid hex string for ECDSA private key: { hex_str } " )
74+ except ValueError as exc :
75+ raise ValueError (f"Invalid hex string for ECDSA private key: { hex_str } " ) from exc
7476 return cls .from_bytes_ecdsa (key_bytes )
7577
7678 @classmethod
@@ -82,15 +84,15 @@ def from_string_der(cls, hex_str: str) -> "PrivateKey":
8284 hex_str = hex_str .removeprefix ("0x" )
8385 try :
8486 der_data = bytes .fromhex (hex_str )
85- except ValueError :
86- raise ValueError (f"Invalid hex string for DER private key: { hex_str } " )
87+ except ValueError as exc :
88+ raise ValueError (f"Invalid hex string for DER private key: { hex_str } " ) from exc
8789 return cls .from_der (der_data )
88-
90+
8991 #
9092 # ---------------------------------
9193 # Generation
9294 # ---------------------------------
93- #
95+ #
9496
9597 @classmethod
9698 def generate (cls , key_type : str = "ed25519" ) -> "PrivateKey" :
@@ -99,10 +101,9 @@ def generate(cls, key_type: str = "ed25519") -> "PrivateKey":
99101 """
100102 if key_type .lower () == "ed25519" :
101103 return cls .generate_ed25519 ()
102- elif key_type .lower () == "ecdsa" :
104+ if key_type .lower () == "ecdsa" :
103105 return cls .generate_ecdsa ()
104- else :
105- raise ValueError ("Invalid key_type. Use 'ed25519' or 'ecdsa'." )
106+ raise ValueError ("Invalid key_type. Use 'ed25519' or 'ecdsa'." )
106107
107108 @classmethod
108109 def generate_ed25519 (cls ) -> "PrivateKey" :
@@ -157,7 +158,9 @@ def from_bytes(cls, key_bytes: bytes) -> "PrivateKey":
157158 return cls (der_key )
158159
159160 # If all attempts failed, raise an error
160- raise ValueError ("Failed to load private key from bytes (not Ed25519 seed, ECDSA scalar, or valid DER)." )
161+ raise ValueError (
162+ "Failed to load private key from bytes (not Ed25519 seed, ECDSA scalar, or valid DER)."
163+ )
161164
162165 @staticmethod
163166 def _try_load_ed25519 (key_bytes : bytes ) -> Optional [ed25519 .Ed25519PrivateKey ]:
@@ -185,7 +188,9 @@ def _try_load_ecdsa(key_bytes: bytes) -> Optional[ec.EllipticCurvePrivateKey]:
185188 return None
186189
187190 @staticmethod
188- def _try_load_der (key_bytes : bytes ) -> Optional [Union [ed25519 .Ed25519PrivateKey , ec .EllipticCurvePrivateKey ]]:
191+ def _try_load_der (key_bytes : bytes ) -> Optional [Union [
192+ ed25519 .Ed25519PrivateKey , ec .EllipticCurvePrivateKey
193+ ]]:
189194 """
190195 Attempt to parse the bytes as a DER-encoded private key.
191196 Auto-detect Ed25519 vs. ECDSA(secp256k1). Return None on failure.
@@ -213,7 +218,7 @@ def from_bytes_ed25519(cls, seed_32: bytes) -> "PrivateKey":
213218 try :
214219 return cls (ed25519 .Ed25519PrivateKey .from_private_bytes (seed_32 ))
215220 except Exception as e :
216- raise ValueError (f"Could not load Ed25519 private key from seed: { e } " )
221+ raise ValueError (f"Could not load Ed25519 private key from seed: { e } " ) from e
217222
218223 @classmethod
219224 def from_bytes_ecdsa (cls , scalar_32 : bytes ) -> "PrivateKey" :
@@ -230,7 +235,7 @@ def from_bytes_ecdsa(cls, scalar_32: bytes) -> "PrivateKey":
230235 ec_priv = ec .derive_private_key (private_int , ec .SECP256K1 ())
231236 return cls (ec_priv )
232237 except Exception as e :
233- raise ValueError (f"Could not load ECDSA private key from scalar: { e } " )
238+ raise ValueError (f"Could not load ECDSA private key from scalar: { e } " ) from e
234239
235240 @classmethod
236241 def from_der (cls , der_data : bytes ) -> "PrivateKey" :
@@ -241,7 +246,7 @@ def from_der(cls, der_data: bytes) -> "PrivateKey":
241246 try :
242247 private_key = serialization .load_der_private_key (der_data , password = None )
243248 except Exception as e :
244- raise ValueError (f"Could not parse DER private key: { e } " )
249+ raise ValueError (f"Could not parse DER private key: { e } " ) from e
245250
246251 if isinstance (private_key , ed25519 .Ed25519PrivateKey ):
247252 return cls (private_key )
@@ -268,17 +273,16 @@ def sign(self, data: bytes) -> bytes:
268273 if isinstance (self ._private_key , ed25519 .Ed25519PrivateKey ):
269274 # Ed25519 automatically handles the hashing internally
270275 return self ._private_key .sign (data )
271- else :
272- # ECDSA requires specifying a hash algorithm
273- return self ._private_key .sign (data , ec .ECDSA (hashes .SHA256 ()))
276+ # ECDSA requires specifying a hash algorithm
277+ return self ._private_key .sign (data , ec .ECDSA (hashes .SHA256 ()))
274278
275279 def public_key (self ) -> PublicKey :
276280 """
277281 Derive the public key from this private key.
278282 """
279283 return PublicKey (self ._private_key .public_key ())
280284
281-
285+
282286 #
283287 # ---------------------------------
284288 # Serialization
@@ -291,10 +295,9 @@ def to_bytes_raw(self) -> bytes:
291295 """
292296 if self .is_ed25519 ():
293297 return self .to_bytes_ed25519_raw ()
294- elif self .is_ecdsa ():
298+ if self .is_ecdsa ():
295299 return self .to_bytes_ecdsa_raw ()
296- else :
297- raise ValueError ("Unknown key type; cannot extract raw bytes." )
300+ raise ValueError ("Unknown key type; cannot extract raw bytes." )
298301
299302 def to_bytes_ed25519_raw (self ) -> bytes :
300303 """
@@ -329,12 +332,11 @@ def to_bytes_der(self) -> bytes:
329332 format = serialization .PrivateFormat .PKCS8 ,
330333 encryption_algorithm = serialization .NoEncryption ()
331334 )
332- else :
333- # ECDSA can be exported in Traditional OpenSSL or PKCS#8
334- return self ._private_key .private_bytes (
335- encoding = serialization .Encoding .DER ,
336- format = serialization .PrivateFormat .TraditionalOpenSSL ,
337- encryption_algorithm = serialization .NoEncryption ()
335+ # ECDSA can be exported in Traditional OpenSSL or PKCS#8
336+ return self ._private_key .private_bytes (
337+ encoding = serialization .Encoding .DER ,
338+ format = serialization .PrivateFormat .TraditionalOpenSSL ,
339+ encryption_algorithm = serialization .NoEncryption ()
338340 )
339341
340342 def to_string_raw (self ) -> str :
@@ -354,7 +356,7 @@ def to_string_ecdsa_raw(self) -> str:
354356 Returns the ECDSA private key as a hex string (raw).
355357 """
356358 return self .to_bytes_ecdsa_raw ().hex ()
357-
359+
358360 def to_string_der (self ) -> str :
359361 """
360362 Returns the DER-encoded private key as a hex string.
@@ -372,7 +374,7 @@ def to_string(self) -> str:
372374 # is_ed25519 / is_ecdsa checks
373375 # ---------------------------------
374376 #
375-
377+
376378 def is_ed25519 (self ) -> bool :
377379 """
378380 Check if this private key is Ed25519.
0 commit comments