x.crypto.chacha20 #
module chacha20
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.
Examples
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.
struct Cipher #
struct Cipher {
mut:
// internal's of ChaCha20 states, ie, 16 of u32 words, 4 of ChaCha20 constants,
// 8 word (32 bytes) of keys, 3 word (24 bytes) of nonces and 1 word of counter
key [8]u32
nonce [3]u32
counter u32
overflow bool
// internal buffer for storing key stream results
block []u8 = []u8{len: block_size}
// additional fields, follow the go version
precomp bool
p1 u32
p5 u32
p9 u32
p13 u32
p2 u32
p6 u32
p10 u32
p14 u32
p3 u32
p7 u32
p11 u32
p15 u32
}
Cipher represents ChaCha20 stream cipher instances.
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