Skip to content

x.crypto.chacha20 #

module chacha20


Chacha20 (and XChacha20) stream cipher encryption algorithm in pure V. Its mostly based on RFC 8439 and inspired by Go version of the same library.


module main

import encoding.hex
import x.crypto.chacha20

fn main() {
    // example of random key
    // you should make sure the key (and nonce) are random enough.
    // The security guarantees of the ChaCha20 require that the same nonce
    // value is never used twice with the same key.
    key := hex.decode('bf32a829ebf86d23f6a32a74ef0333401e54a6b2900d35bfadef82c5d49da15f')!
    nonce := hex.decode('a7d7cf3405631f25cc1054bd')!

    input := 'Good of gambler'.bytes()

    // encrypt and the decrypt back
    output := chacha20.encrypt(key, nonce, input)!
    input_back := chacha20.decrypt(key, nonce, output)!

    // should true
    assert input == input_back

Constants #

const key_size = 32

size of ChaCha20 key, ie 256 bits size, in bytes

const nonce_size = 12

size of ietf ChaCha20 nonce, ie 96 bits size, in bytes

const x_nonce_size = 24

size of extended ChaCha20 nonce, called XChaCha20, 192 bits

fn decrypt #

fn decrypt(key []u8, nonce []u8, ciphertext []u8) ![]u8

decrypt does reverse of encrypt operation by decrypting ciphertext with ChaCha20 cipher instance with provided key and nonce.

fn encrypt #

fn encrypt(key []u8, nonce []u8, plaintext []u8) ![]u8

encrypt encrypts plaintext bytes with ChaCha20 cipher instance with provided key and nonce. It was a thin wrapper around two supported nonce size, ChaCha20 with 96 bits and XChaCha20 with 192 bits nonce. Internally, encrypt start with 0's counter value. If you want more control, use Cipher instance and setup the counter by your self.

fn new_cipher #

fn new_cipher(key []u8, nonce []u8) !&Cipher

new_cipher creates a new ChaCha20 stream cipher with the given 32 bytes key, a 12 or 24 bytes nonce. If 24 bytes of nonce was provided, the XChaCha20 construction will be used. It returns new ChaCha20 cipher instance or an error if key or nonce have any other length.

fn (Cipher) xor_key_stream #

fn (mut c Cipher) xor_key_stream(mut dst []u8, src []u8)

xor_key_stream xors each byte in the given slice in the src with a byte from the cipher's key stream. It fulfills cipher.Stream interface. It encrypts the plaintext message in src and stores the ciphertext result in dst in a single run of encryption. You must never use the same (key, nonce) pair more than once for encryption. This would void any confidentiality guarantees for the messages encrypted with the same nonce and key.

fn (Cipher) free #

fn (mut c Cipher) free()

free the resources taken by the Cipher c. Dont use cipher after .free call

fn (Cipher) reset #

fn (mut c Cipher) reset()

reset quickly sets all Cipher's fields to default value

fn (Cipher) set_counter #

fn (mut c Cipher) set_counter(ctr u32)

set_counter sets Cipher's counter

fn (Cipher) rekey #

fn (mut c Cipher) rekey(key []u8, nonce []u8) !

rekey resets internal Cipher's state and reinitializes state with the provided key and nonce