package core:crypto/noise

⌘K
Ctrl+K
or
/

    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.

    Related Procedures With Parameters

    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.

    Related Procedures With Returns

    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.

    PSK_SIZE ¶

    PSK_SIZE :: 32
     

    PSK_SIZE is the size of an optional handshake pre-shared symmetric key.

    TAG_SIZE ¶

    TAG_SIZE :: 16
     

    TAG_SIZE is the size of the AEAD authentication 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