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
The size of ChaCha20 key, ie 256 bits size, in bytes
const nonce_size = 12
The size of standard IETF ChaCha20 nonce, ie 96 bits size, in bytes
const x_nonce_size = 24
The size of extended variant of standard ChaCha20 (XChaCha20) nonce, 192 bits
const orig_nonce_size = 8
The size of original ChaCha20 nonce, 64 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 and bytes of nonce with supported size, ie, 8, 12 or 24 bytes nonce. Standard IETF variant use 12 bytes nonce's, if you want create original ChaCha20 cipher with support for 64-bit counter, use 8 bytes length nonce's instead 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 {
// The mode of ChaCha20 cipher, set on cipher's creation.
mode CipherMode = .standard
mut:
// The internal's of ChaCha20 states contains 512 bits (64 bytes), contains of
// 4 words (16 bytes) of ChaCha20 constants,
// 8 words (32 bytes) of ChaCha20 keys,
// 4 words (16 bytes) of raw nonces, with internal counter, support for 32 and 64 bit counters.
key [8]u32
nonce [4]u32
// Flag indicates whether this cipher's counter has reached the limit
overflow bool
// Flag that tells whether this cipher was an extended XChaCha20 standard variant.
// only make sense when mode == .standard
extended bool
// internal buffer for storing key stream results
block []u8 = []u8{len: block_size}
// The last length of leftover unprocessed keystream from internal buffer
length int
// Additional fields, follows the go version. Its mainly used to optimize
// standard IETF ciphers operations by pre-chache some quarter_round step.
// vfmt off
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
// vfmt on
}
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 key stream fashion. 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) encrypt #
fn (mut c Cipher) encrypt(mut dst []u8, src []u8)
encrypt encrypts src and stores into dst buffer. It works like xor_key_stream
except its ignore key streaming process by ignoring remaining key stream in the internal buffer, so, its works in one shot of fashion. Its added to allow chacha20poly1305
modules to work without key stream fashion.
Todo: integrates it with the rest
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