Skip to content

x.crypto.chacha20poly1305 #


Chacha20Poly1305 Authenticated Encryption with Additional Data (AEAD) module for V Language

This module provides authenticated encryption with additional data (AEAD) algorithm in V Language. Its backed by experimental x.crypto.chacha20 symmetric key stream cipher encryption module and x.crypto.poly1305 message authentication code (MAC) module.

[!Warning] > This is an absolutely experimental module, which is subject to change. > Please use it carefully, thoroughly and wisely.


import encoding.hex
import x.crypto.chacha20poly1305

fn main() {
    // plaintext message to be encrypted and authenticated
    message := 'Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it.'

    // sets your secure random key
    key := hex.decode('808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f')!
    // give yours nonce
    nonce := hex.decode('070000004041424344454647')!
    // yours additional data
    aad := hex.decode('50515253c0c1c2c3c4c5c6c7')!

    // lets doing authenticated encryption
    ciphertext := chacha20poly1305.encrypt(message, key, nonce, aad)!

    // lets perform decryption back
    plaintext := chacha20poly1305.decrypt(ciphertext, key, nonce, aad)!

    assert plaintext == message

Constants #

const key_size = 32

key_size is the size of key (in bytes) which the Chacha20Poly1305 AEAD accepts.

const nonce_size = 12

nonce_size is the size of the standard nonce (in bytes) which the Chacha20Poly1305 AEAD accepts.

const x_nonce_size = 24

nonce_size is the size of the extended nonce (in bytes) which the Chacha20Poly1305 AEAD accepts.

const tag_size = 16

tag_size is the size of the message authenticated code (in bytes) produced by Chacha20Poly1305 AEAD.

fn decrypt #

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

decrypt does one-shot decryption of given ciphertext with associated key, nonce and additional data. It return plaintext output and verify if resulting tag is a valid message authenticated code (mac) for given message, key and additional data.

fn encrypt #

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

encrypt does one-shot encryption of given plaintext with associated key, nonce and additional data. It return ciphertext output and authenticated tag appended into it.

fn new #

fn new(key []u8, ncsize int) !&AEAD

new creates a new Chacha20Poly1305 AEAD instance with given 32 bytes of key and the nonce size in ncsize. The ncsize should be 12 or 24 length, otherwise it would return error.

interface AEAD #

interface AEAD {
	// nonce_size return the nonce size (in bytes) used by this AEAD algorithm that should be
	// passed to `.encrypt` or `.decrypt`.
	nonce_size() int
	// overhead returns the maximum difference between the lengths of a plaintext and its ciphertext.
	overhead() int
	// encrypt encrypts and authenticates the provided plaintext along with a nonce, and
	// to be authenticated additional data in `ad`.
	// It returns ciphertext bytes where its encoded form is up to implementation and
	// not dictated by the interfaces.
	// Usually its contains encrypted text plus some authentication tag, and maybe some other bytes.
	encrypt(plaintext []u8, nonce []u8, ad []u8) ![]u8
	// decrypt decrypts and authenticates (verifies) the provided ciphertext along with a nonce, and
	// additional data. If verified successfully, it returns the plaintext and error otherwise.
	decrypt(ciphertext []u8, nonce []u8, ad []u8) ![]u8

This interface was a proposed draft for Authenticated Encryption with Additional Data (AEAD) interface AEAD likes discussion at discord channel. see But its little modified to be more v-idiomatic.

Note: This interface should be more appropriately located in crypto.cipher, we can move it into crypto.cipher later. Authenticated Encryption with Additional Data (AEAD) interface

fn (Chacha20Poly1305) nonce_size #

fn (c Chacha20Poly1305) nonce_size() int

nonce_size returns the size of underlying nonce (in bytes) of AEAD algorithm.

fn (Chacha20Poly1305) overhead #

fn (c Chacha20Poly1305) overhead() int

overhead returns maximum difference between the lengths of a plaintext to be encrypted and ciphertext's output. In the context of Chacha20Poly1305, .overhead() == .tag_size.

fn (Chacha20Poly1305) encrypt #

fn (c Chacha20Poly1305) encrypt(plaintext []u8, nonce []u8, ad []u8) ![]u8

encrypt encrypts plaintext, along with nonce and additional data and generates authenticated tag appended into ciphertext's output.

fn (Chacha20Poly1305) decrypt #

fn (c Chacha20Poly1305) decrypt(ciphertext []u8, nonce []u8, ad []u8) ![]u8

decrypt decrypts ciphertext along with provided nonce and additional data. Decryption is similar with the encryption process with slight differences in: The roles of ciphertext and plaintext are reversed, so the ChaCha20 encryption function is applied to the ciphertext, producing the plaintext. The Poly1305 function is still run on the AAD and the ciphertext, not the plaintext. The calculated mac is bitwise compared to the received mac. The message is authenticated if and only if the tags match, return error if failed to verify.