88Example usage:
99 >>> from libp2p.identity_utils import save_identity, load_identity
1010 >>> from libp2p.crypto.ed25519 import create_new_key_pair
11- >>>
11+ >>>
1212 >>> # Create and save an identity
1313 >>> key_pair = create_new_key_pair()
1414 >>> save_identity(key_pair, "my_peer.key")
15- >>>
15+ >>>
1616 >>> # Load it later
1717 >>> loaded_key_pair = load_identity("my_peer.key")
1818"""
2929def save_identity (key_pair : KeyPair , filepath : str | Path ) -> None :
3030 """
3131 Save a keypair to disk for later reuse.
32-
32+
3333 The private key is serialized and saved to the specified file.
3434 The file should be kept secure as it contains the peer's private key.
35-
35+
3636 Args:
3737 key_pair: The KeyPair to save
3838 filepath: Path where the private key will be saved
39-
39+
4040 Raises:
4141 OSError: If the file cannot be written
42-
42+
4343 Example:
4444 >>> from libp2p.crypto.ed25519 import create_new_key_pair
4545 >>> key_pair = create_new_key_pair()
4646 >>> save_identity(key_pair, "my_peer_identity.key")
47+
4748 """
4849 filepath = Path (filepath )
49-
50+
5051 # Serialize the private key to bytes
5152 private_key_bytes = key_pair .private_key .to_bytes ()
52-
53+
5354 # Write to file with restrictive permissions (owner read/write only)
5455 filepath .write_bytes (private_key_bytes )
55-
56+
5657 # Set file permissions to 0600 (owner read/write only) for security
5758 try :
5859 filepath .chmod (0o600 )
@@ -64,88 +65,92 @@ def save_identity(key_pair: KeyPair, filepath: str | Path) -> None:
6465def load_identity (filepath : str | Path ) -> KeyPair :
6566 """
6667 Load a keypair from disk.
67-
68+
6869 Reads a previously saved private key and reconstructs the full keypair.
6970 Currently only supports Ed25519 keys.
70-
71+
7172 Args:
7273 filepath: Path to the saved private key file
73-
74+
7475 Returns:
7576 KeyPair loaded from the file
76-
77+
7778 Raises:
7879 FileNotFoundError: If the file doesn't exist
7980 ValueError: If the file contains invalid key data
80-
81+
8182 Example:
8283 >>> key_pair = load_identity("my_peer_identity.key")
8384 >>> from libp2p import new_host
8485 >>> host = new_host(key_pair=key_pair)
86+
8587 """
8688 filepath = Path (filepath )
87-
89+
8890 # Read the private key bytes
8991 private_key_bytes = filepath .read_bytes ()
90-
92+
9193 # Reconstruct the Ed25519 private key
9294 private_key = Ed25519PrivateKey .from_bytes (private_key_bytes )
93-
95+
9496 # Derive the public key
9597 public_key = private_key .get_public_key ()
96-
98+
9799 return KeyPair (private_key , public_key )
98100
99101
100102def create_identity_from_seed (seed : bytes ) -> KeyPair :
101103 """
102104 Create a deterministic identity from a seed.
103-
105+
104106 The same seed will always produce the same keypair and peer ID.
105107 This is useful for testing or when you want a deterministic identity
106108 without saving keys to disk.
107-
109+
108110 Args:
109111 seed: A 32-byte seed for key generation. Must be exactly 32 bytes.
110-
112+
111113 Returns:
112114 KeyPair generated deterministically from the seed
113-
115+
114116 Raises:
115117 ValueError: If the seed is not 32 bytes or produces an invalid key
116-
118+
117119 Example:
118120 >>> seed = b"my_secret_seed_32_bytes_long!!!!"
119121 >>> key_pair = create_identity_from_seed(seed)
120122 >>> from libp2p import new_host
121123 >>> host = new_host(key_pair=key_pair)
122124 >>> # Same seed always produces same peer ID
123125 >>> print(host.get_id())
126+
124127 """
125128 if len (seed ) != 32 :
126129 raise ValueError (
127130 f"Seed must be exactly 32 bytes, got { len (seed )} bytes. "
128- f"Consider using hashlib.sha256(your_seed).digest() to derive a 32-byte seed."
131+ "Consider using hashlib.sha256(your_seed).digest() "
132+ "to derive a 32-byte seed."
129133 )
130-
134+
131135 return create_new_ed25519_key_pair (seed = seed )
132136
133137
134138def identity_exists (filepath : str | Path ) -> bool :
135139 """
136140 Check if an identity file exists at the given path.
137-
141+
138142 Args:
139143 filepath: Path to check for an existing identity file
140-
144+
141145 Returns:
142146 True if the file exists, False otherwise
143-
147+
144148 Example:
145149 >>> if identity_exists("my_peer.key"):
146150 ... key_pair = load_identity("my_peer.key")
147151 ... else:
148152 ... key_pair = create_new_key_pair()
149153 ... save_identity(key_pair, "my_peer.key")
154+
150155 """
151156 return Path (filepath ).exists ()
0 commit comments