package core:crypto/noise
Overview
An implementation of the Noise Protocol Framework (Revision 34).
The fallback modifier and multi-PSK patterns are not supported
for the sake of simplicity.
Index
Types (4)
Constants (4)
Variables (0)
This section is empty.
Procedures (21)
- cipherstates_n
- cipherstates_rekey
- cipherstates_reset
- cipherstates_set_n
- handshake_hash
- handshake_init
- handshake_initiator_step
- handshake_peer_identity
- handshake_read_message
- handshake_reset
- handshake_responder_step
- handshake_split
- handshake_write_message
- open_message
- pattern_is_one_way
- pattern_is_psk
- pattern_num_messages
- pattern_requires_initiator_s
- pattern_requires_responder_s
- seal_message
- split_protocol_string
Procedure Groups (0)
This section is empty.
Types
Cipher_States ¶
Cipher_States :: struct { c1_i_to_r: Cipher_State, c2_r_to_i: Cipher_State, initiator: bool, }
Cipher_States are the keyed AEAD instances and associated state, derived from a successful handshake.
Related Procedures With Parameters
Handshake_Pattern ¶
Handshake_Pattern :: enum int { Invalid, // One way patterns N, K, X, // Fundamental patterns XX, NK, NN, KN, KK, NX, KX, XN, IN, XK, IK, IX, // Deferred patterns NK1, NX1, X1N, X1K, XK1, X1K1, X1X, XX1, X1X1, K1N, K1K, KK1, K1K1, K1X, KX1, K1X1, I1N, I1K, IK1, I1K1, I1X, IX1, I1X1, // Recommended PSK patterns Npsk0, Kpsk0, Xpsk1, NNpsk0, NNpsk2, NKpsk0, NKpsk2, NXpsk2, XNpsk3, XKpsk3, XXpsk3, KNpsk0, KNpsk2, KKpsk0, KKpsk2, KXpsk2, INpsk1, INpsk2, IKpsk1, IKpsk2, IXpsk2, }
Handshake_Pattern is the list of currently supported Noise Handshake Patterns.
Related Procedures With Parameters
Related Procedures With Returns
Handshake_State ¶
Handshake_State :: struct { s: ecdh.Private_Key, e: ecdh.Private_Key, rs: ecdh.Public_Key, re: ecdh.Public_Key, psk: [32]u8, symmetric_state: Symmetric_State, message_pattern: ^Message_Pattern, current_message: int, status: Status, initiator: bool, pre_set_e: bool, }
Handshake_State is the per-handshake state.
Status ¶
Status :: enum int { Ok, // States Handshake_Pending, Handshake_Complete, Handshake_Split, Handshake_Failed, // Errors Invalid_Protocol_String, Invalid_Pre_Shared_Key, Invalid_DH_Key, No_Self_Identity, No_Peer_Identity, Unexpected_Peer_Identity, Unexpected_Pre_Shared_Key, DH_Failure, Invalid_Handshake_Message, Decryption_Failure, IV_Exhausted, Invalid_Cipher_State, Invalid_Destination_Buffer, Invalid_Payload_Message, Max_Packet_Size, Out_Of_Memory, }
Status is the status of Noise protocol operation.
Constants
MAX_PACKET_SIZE ¶
MAX_PACKET_SIZE :: 65535
MAX_PACKET_SIZE is the maximum Noise message size, including TAG_SIZE
if relevant (seal_message, open_message).
MAX_STEP_MSG_SIZE ¶
MAX_STEP_MSG_SIZE :: (MAX_DH_SIZE * 2) + TAG_SIZE + TAG_SIZE
MAX_STEP_MSG_SIZE is the maximum per-handshake step message size, excluding the optional payload.
e is DH_LEN, s is either DH_LEN or DH_LEN + TAG_SIZE, and there
is a maximum of one per each message, and a possible mandatory tag.
Variables
This section is empty.
Procedures
cipherstates_n ¶
cipherstates_n :: proc(self: ^Cipher_States, seal_key: bool, n: u64) -> (u64, Status) {…}
cipherstates_n returns the interal counter used to generate the AEAD IV. This can be used to deal with out-of-order transport messages. See 11.4 of the specification.
WARNING: Reusing n across different aad/messages with the same Cipher_States will result in catastrophic loss of security.
cipherstates_rekey ¶
cipherstates_rekey :: proc(self: ^Cipher_States, seal_key: bool) -> Status {…}
cipherstates_rekey updates the selected AEAD key, using a one way function. See 11.3 of the specification for examples of usage.
Note: If one side updates the seal_key, the other side must update the non-seal_key and vice versa.
cipherstates_reset ¶
cipherstates_reset :: proc(self: ^Cipher_States) {…}
cipherstates_reset sanitizes the Cipher_States.
cipherstates_set_n ¶
cipherstates_set_n :: proc(self: ^Cipher_States, seal_key: bool, n: u64) -> Status {…}
cipherstates_set_n sets the interal counter used to generate the AEAD IV to an explicit value. This can be used to deal with out-of-order transport messages. See 11.4 of the specification.
WARNING: Reusing n across different aad/messages with the same Cipher_States will result in catastrophic loss of security.
handshake_hash ¶
handshake_hash :: proc(self: ^Handshake_State) -> ([]u8, Status) {…}
handshake_hash returns the handshake transcript hash of a completed handshake, for the purposes of channel binding. See 11.2 of the specification for details on usage.
This returns a slice to an internal buffer that will get wiped by handshake_reset. If the hash is needed after a call to handshake_reset, the slice must be copied.
handshake_init ¶
handshake_init :: proc( self: ^Handshake_State, initiator: bool, prologue: []u8, s: ^ecdh.Private_Key, rs: ^ecdh.Public_Key, protocol_name: string, psk: []u8 = nil, _e: ^ecdh.Private_Key = nil, ) -> Status {…}
handshake_init initializes a Handshake_State with the provided parameters. The relevant values are copied into the Handshake_State instance, and can be discarded/sanitized right after handshake_init returns (eg: psk).
Note: While this implementation supports setting e, this is primarily
intended for testing, or cases where the runtime cryptographic entropy
source is unavailable. Use of this functionality is STRONGLY
discouraged.
handshake_initiator_step ¶
handshake_initiator_step :: proc(self: ^Handshake_State, input_message: []u8, payload: []u8 = nil, dst: []u8 = nil, allocator := context.allocator) -> ([]u8, []u8, Status) {…}
handshake_initiator_step takes an input_message received from the responder if any and an optional payload to be sent to the responder, and performs one step of the Noise handshake process, returning the message to be sent to the responder if any, the payload received from the responder if any, and the status of the handshake.
The output message MUST be sent to the responder even if the status code returned is .Handshake_Complete.
If the dst parameter is provided, the message and payload will be written to dst, otherwise new buffers will be allocated.
handshake_peer_identity ¶
handshake_peer_identity :: proc(self: ^Handshake_State) -> (^ecdh.Public_Key, Status) {…}
handshake_peer_identity returns the peer's static DH key used by a completed handshake.
This returns a pointer to the Handshake_State's copy of the peer's public key, that will get wiped by handshake_reset. If the key is needed after a call to handshake_reset, it must be copied.
handshake_read_message ¶
handshake_read_message :: proc(self: ^Handshake_State, message: []u8, dst: []u8 = nil, allocator := context.allocator) -> ([]u8, Status) {…}
handshake_read_message calls the Noise HandshakeState's ReadMessage function directly. In most cases you are better off using handshake_initiator_step or handshake_responder_step.
If the dst parameter is provided, the message and payload will be written to dst, otherwise new buffers will be allocated.
handshake_reset ¶
handshake_reset :: proc(self: ^Handshake_State) {…}
handshake_reset sanitizes the Handshake_State. It is both safe and recommended to call this as soon as practical (after any calls to handshake_peer_identity, handshake_hash, and handshake_split are complete).
handshake_responder_step ¶
handshake_responder_step :: proc(self: ^Handshake_State, input_message: []u8, payload: []u8 = nil, dst: []u8 = nil, allocator := context.allocator) -> ([]u8, []u8, Status) {…}
handshake_responder_step takes a input_message received from the initiator, and and an optional payload to be sent to the initiator, and performs one step of the Noise handshake process, returning the message to be sent to the initiator if any, the payload received from the initiator if any, and the status of the handshake.
The output message MUST be sent to the initiator even if the status code returned is .Handshake_Complete.
If the dst parameter is provided, the message and payload will be written to dst, otherwise new buffers will be allocated.
handshake_split ¶
handshake_split :: proc(self: ^Handshake_State, cipher_states: ^Cipher_States) -> Status {…}
handshake_split initializes a Cipher_States instance from a completed handshake. This can be called once and only once per Handshake_State instance.
handshake_write_message ¶
handshake_write_message :: proc(self: ^Handshake_State, payload: []u8, dst: []u8 = nil, allocator := context.allocator) -> ([]u8, Status) {…}
handshake_write_message calls the Noise HandshakeState's WriteMessage function directly. In most cases you are better off using handshake_initiator_step or handshake_responder_step.
If the dst parameter is provided, the message and payload will be written to dst, otherwise new buffers will be allocated.
open_message ¶
open_message :: proc(self: ^Cipher_States, aad, ciphertext: []u8, dst: []u8 = nil, allocator := context.allocator) -> ([]u8, Status) {…}
open_message authenticates the aad and ciphertext, decrypts the
ciphertext and returns the resulting plaintext. The plaintext will
ALWAYS be len(ciphertext) - TAG_SIZE bytes in length.
If the dst parameter is provided, the plaintext will be written to dst, otherwise a new buffer will be allocated.
pattern_is_one_way ¶
pattern_is_one_way :: proc(pattern: Handshake_Pattern) -> bool {…}
pattern_is_psk ¶
pattern_is_psk :: proc(pattern: Handshake_Pattern) -> bool {…}
pattern_num_messages ¶
pattern_num_messages :: proc(pattern: Handshake_Pattern) -> int {…}
pattern_requires_initiator_s ¶
pattern_requires_initiator_s :: proc(pattern: Handshake_Pattern) -> (pre: bool, hs: bool) {…}
pattern_requires_responder_s ¶
pattern_requires_responder_s :: proc(pattern: Handshake_Pattern) -> (pre: bool, hs: bool) {…}
seal_message ¶
seal_message :: proc(self: ^Cipher_States, aad, plaintext: []u8, dst: []u8 = nil, allocator := context.allocator) -> ([]u8, Status) {…}
seal_message encrypts the provided data, authenticates the aad and
ciphertext, and returns the resulting ciphertext. The ciphertext
will ALWAYS be len(plaintext) + TAG_SIZE bytes in length.
If the dst parameter is provided, the ciphertext will be written to dst, otherwise a new buffer will be allocated.
split_protocol_string ¶
split_protocol_string :: proc(protocol_name: string) -> (Handshake_Pattern, ecdh.Curve, aead.Algorithm, crypto_hash.Algorithm, Status) {…}
split_protocol_string splits a protocol string into individual components.
Procedure Groups
This section is empty.
Source Files
Generation Information
Generated with odin version dev-2026-04 (vendor "odin") Windows_amd64 @ 2026-04-21 21:38:42.492096300 +0000 UTC