{"id":7453,"library":"noiseprotocol","title":"Noise Protocol Framework Implementation","description":"The `noiseprotocol` library provides a Python implementation of the Noise Protocol Framework (Revision 5), a widely used framework for building secure cryptographic protocols. It focuses on offering a robust and flexible API for performing handshakes and secure transport of data, supporting various handshake patterns and cipher suites. The current version is 0.3.1, and releases are infrequent, reflecting the stability of the underlying protocol.","status":"active","version":"0.3.1","language":"en","source_language":"en","source_url":"https://github.com/plizonczyk/noiseprotocol","tags":["cryptography","network","security","noise-protocol","handshake","encryption"],"install":[{"cmd":"pip install noiseprotocol","lang":"bash","label":"Install stable version"}],"dependencies":[],"imports":[{"note":"Main class for initiating and responding to Noise handshakes.","symbol":"HandshakeState","correct":"from noiseprotocol.handshake import HandshakeState"},{"note":"Class for managing cryptographic keypairs (private and public keys).","symbol":"Keypair","correct":"from noiseprotocol.handshake import Keypair"},{"note":"Enum for specifying the Noise handshake pattern (e.g., IK, XX, N).","symbol":"HandshakePattern","correct":"from noiseprotocol.constants import HandshakePattern"},{"note":"Enum for specifying the cryptographic suite (e.g., AESGCM256_SHA256_X25519).","symbol":"CipherSuite","correct":"from noiseprotocol.constants import CipherSuite"},{"note":"Enum for specifying if the connection is an INITIATOR or RESPONDER.","symbol":"NoiseConnectionRole","correct":"from noiseprotocol.constants import NoiseConnectionRole"}],"quickstart":{"code":"import secrets\nfrom noiseprotocol.constants import HandshakePattern, CipherSuite, NoiseConnectionRole\nfrom noiseprotocol.handshake import HandshakeState, Keypair\n\n# 1. Define static keys (can be pre-shared or generated once)\ninitiator_static_key = Keypair(private=secrets.token_bytes(32))\nresponder_static_key = Keypair(private=secrets.token_bytes(32))\n\n# 2. Setup Initiator\ninitiator_hs = HandshakeState(\n    role=NoiseConnectionRole.INITIATOR,\n    pattern=HandshakePattern.IK,\n    static_key=initiator_static_key,\n    remote_static_key=responder_static_key.public, # Initiator knows Responder's public key\n    cipher_suite=CipherSuite.AESGCM256_SHA256_X25519\n)\ninitiator_hs.initialize()\n\n# 3. Setup Responder\nresponder_hs = HandshakeState(\n    role=NoiseConnectionRole.RESPONDER,\n    pattern=HandshakePattern.IK,\n    static_key=responder_static_key,\n    cipher_suite=CipherSuite.AESGCM256_SHA256_X25519\n)\nresponder_hs.initialize()\n\n# 4. Perform Handshake (simplified for example, messages would be sent over network)\n# Initiator sends first message\nmessage_initiator_to_responder, _ = initiator_hs.write_message(b\"\")\n\n# Responder receives message\n_, post_handshake_state_responder = responder_hs.read_message(message_initiator_to_responder)\n\n# Responder sends second message\nmessage_responder_to_initiator, _ = responder_hs.write_message(b\"\")\n\n# Initiator receives message\n_, post_handshake_state_initiator = initiator_hs.read_message(message_responder_to_initiator)\n\n# Handshake complete, now use post_handshake_state for transport\nif post_handshake_state_initiator and post_handshake_state_responder:\n    plaintext = b\"Hello, secure world!\"\n    ciphertext = post_handshake_state_initiator.write_message(plaintext)\n    decrypted = post_handshake_state_responder.read_message(ciphertext)\n\n    assert plaintext == decrypted\n    print(\"Handshake and transport successful!\")\nelse:\n    print(\"Handshake failed.\")","lang":"python","description":"This example demonstrates a basic Noise Protocol handshake using the IK pattern, followed by secure transport of a message. It sets up an initiator and a responder, performs the handshake by exchanging messages, and then uses the resulting transport states to encrypt and decrypt a payload."},"warnings":[{"fix":"Ensure the `HandshakePattern` and `CipherSuite` provided to `HandshakeState` are identical for both the initiator and responder.","message":"Mismatch in HandshakePattern or CipherSuite between Initiator and Responder will prevent a successful handshake. Both sides must agree on these parameters.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Do not regenerate static private keys for every connection. Securely store and load them. For testing, `secrets.token_bytes(32)` is acceptable, but for production, use a secure key generation and storage mechanism.","message":"Keypair management is crucial. Static private keys must be kept secret and ideally persisted for consistent peer identification. Ephemeral keys are generated per handshake.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Always encode strings to bytes (e.g., `\"hello\".encode('utf-8')`) before passing them to `write_message` or using them in key material.","message":"The library expects byte-like objects for all message payloads and key material. Passing strings directly without encoding will result in `TypeError`.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Always capture and use the `next_state` returned by these methods. For example, `_, post_handshake_state = responder_hs.read_message(...)` where `post_handshake_state` becomes your transport state.","message":"The `read_message` and `write_message` methods return a tuple of `(payload, next_state)`. It's critical to use the `next_state` for subsequent message processing or transport, as the handshake state evolves.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Run `pip install noiseprotocol` to install the package.","cause":"The `noiseprotocol` package is not installed in your Python environment.","error":"ModuleNotFoundError: No module named 'noiseprotocol'"},{"fix":"Ensure that `HandshakePattern` (e.g., `HandshakePattern.IK`) is identical for both the initiator's and responder's `HandshakeState` initialization.","cause":"The initiator and responder have been configured with different `HandshakePattern` enums, which is a protocol violation.","error":"ValueError: Mismatched handshake pattern"},{"fix":"Encode your string to bytes using `.encode()` (e.g., `my_string.encode('utf-8')`) before passing it to `noiseprotocol` functions.","cause":"You are attempting to pass a Python string to a method that expects raw bytes (e.g., `write_message` or key material).","error":"TypeError: expected bytes-like object, not str"},{"fix":"Verify that no data was altered during transmission. Check that both peers are using the correct and synchronized `HandshakeState` or transport state, and that static keys are correctly configured and shared (if applicable).","cause":"This error indicates that a message's Message Authentication Code (MAC) failed validation, usually due to data tampering in transit or incorrect keying/state management between peers.","error":"noiseprotocol.exceptions.NoiseProtocolException: MAC mismatch"}]}