API Reference
Complete reference for all public APIs in NoiseFramework
NoiseHandshake
Main class for orchestrating Noise Protocol handshakes.
Parameters:
pattern_string (str): Noise pattern in format Noise_PATTERN_DH_CIPHER_HASH
Example: "Noise_XX_25519_ChaChaPoly_SHA256"
Example:
handshake = NoiseHandshake("Noise_XX_25519_ChaChaPoly_SHA256")
Methods
NoiseTransport
Transport layer for encrypted communication after handshake completion.
Parameters:
plaintext (bytes): Data to encrypt
ad (bytes): Associated data (optional)
Parameters:
ciphertext (bytes): Encrypted data
ad (bytes): Associated data (optional)
NoiseConnection (High-Level API)
Simplified API that combines handshake, transport, and framing in one interface.
Parameters:
pattern (str): Noise pattern string
role (str): "initiator" or "responder"
Example (Client):
with NoiseConnection("Noise_XX_25519_ChaChaPoly_SHA256", "initiator") as conn:
conn.connect(("example.com", 9999))
conn.send(b"Hello!")
response = conn.receive()
Message Framing
Built-in length-prefixed framing for TCP/stream transports. Handles message boundaries automatically.
writer = FramedWriter(socket)
writer.write_message(ciphertext)
reader = FramedReader(socket)
ciphertext = reader.read_message()
Key Features: 4-byte big-endian length prefix, 16 MB default max (configurable), automatic partial read handling, works with sockets, files, and pipes.
Async/Await Support
Full asyncio support with async wrappers for modern non-blocking Python applications.
from noiseframework import AsyncNoiseConnection
async def client():
async with AsyncNoiseConnection(
"Noise_XX_25519_ChaChaPoly_SHA256", "initiator"
) as conn:
await conn.connect(("localhost", 9999))
await conn.send(b"Hello async!")
response = await conn.receive()
Pre-Shared Key (PSK) Support
PSK patterns provide quantum-resistant authentication, immune to quantum computer attacks on DH key exchange.
✓ Protection against future quantum computers
✓ Additional authentication beyond public keys
✓ Suitable for government and defense use cases
from noiseframework import NoiseHandshake
# Generate or load 32-byte PSK
psk = os.urandom(32)
# Initiator with PSK
initiator = NoiseHandshake("Noise_XXpsk3_25519_ChaChaPoly_SHA256")
initiator.set_as_initiator()
initiator.generate_static_keypair()
initiator.set_psk(psk) # Set PSK before initialize
initiator.initialize()
# Responder with same PSK
responder = NoiseHandshake("Noise_XXpsk3_25519_ChaChaPoly_SHA256")
responder.set_as_responder()
responder.generate_static_keypair()
responder.set_psk(psk) # Must use same PSK
responder.initialize()
Common Patterns
- XXpsk3
- NNpsk0
- IKpsk2
PSK Modifiers
- psk0 - Early mix
- psk2 - Mid handshake
- psk3 - Late mix
Use Cases
- IoT devices
- Defense systems
- Enterprise VPNs
Fallback Pattern Support
Graceful handshake degradation when initiator's first message fails (Noise Pipes protocol).
alice_ephemeral = ik_msg1[:32] # Extract ephemeral key
# Initiate fallback to XXfallback
bob.start_fallback(alice_ephemeral)
# Continue with XXfallback pattern
fallback_msg1 = bob.write_message(b"Fallback initiated")
Use Cases: Key rotation scenarios, outdated PSKs, server identity updates, graceful degradation preferred over connection failure.
Pattern System
One-way patterns
- NN
- NK
- NX
Initiator auth
- KN
- KK
- KX
Interactive (most common)
- XX (recommended)
- XK
- XN
Mutual authentication, no pre-shared keys
Best for most use cases
Client knows server's public key
Faster handshake, requires pre-shared keys
Anonymous communication
No authentication - not recommended for production
Cryptographic Primitives
25519
Curve25519 (X25519) - 32 bytes
448
Curve448 (X448) - 56 bytes
ChaChaPoly
ChaCha20-Poly1305 (recommended)
AESGCM
AES-256-GCM
SHA256
SHA-256 - 32 bytes
SHA512
SHA-512 - 64 bytes
BLAKE2s
BLAKE2s - 32 bytes
BLAKE2b
BLAKE2b - 64 bytes
Complete Example
# Setup
initiator = NoiseHandshake("Noise_XX_25519_ChaChaPoly_SHA256")
initiator.set_as_initiator()
initiator.generate_static_keypair()
initiator.initialize()
responder = NoiseHandshake("Noise_XX_25519_ChaChaPoly_SHA256")
responder.set_as_responder()
responder.generate_static_keypair()
responder.initialize()
# Handshake
msg1 = initiator.write_message(b"")
responder.read_message(msg1)
msg2 = responder.write_message(b"")
initiator.read_message(msg2)
msg3 = initiator.write_message(b"")
responder.read_message(msg3)
# Transport
i_send, i_recv = initiator.to_transport()
r_send, r_recv = responder.to_transport()
i_transport = NoiseTransport(i_send, i_recv)
r_transport = NoiseTransport(r_send, r_recv)
# Encrypt/Decrypt
ciphertext = i_transport.send(b"Hello!")
plaintext = r_transport.receive(ciphertext)
print(plaintext.decode()) # "Hello!"
Error Handling
handshake = NoiseHandshake("Invalid_Pattern")
except ValueError as e:
print(f"Error: {e}")