---
name: "libressl-ChaCha"
section: "3"
platform: "linux"
package: "libressl"
version: "4.4.0-1"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/libressl-ChaCha"
---

# libressl-ChaCha(3)

ChaCha20 stream cipher

## NAME

**ChaCha\_set\_key**, **ChaCha\_set\_iv**, **ChaCha**, **CRYPTO\_chacha\_20**, **CRYPTO\_hchacha\_20**, **CRYPTO\_xchacha\_20** – ChaCha20 stream cipher

## SYNOPSIS

Crypto Library (libcrypto, -lcrypto)

**#include \<openssl/chacha.h\>**

*void*\

**ChaCha\_set\_key**(*ChaCha\_ctx \*ctx*, *const unsigned char \*key*, *unsigned int keybits*);

*void*\

**ChaCha\_set\_iv**(*ChaCha\_ctx \*ctx*, *const unsigned char \*iv*, *const unsigned char \*counter*);

*void*\

**ChaCha**(*ChaCha\_ctx \*ctx*, *unsigned char \*out*, *const unsigned char \*in*, *size\_t len*);

*void*\

**CRYPTO\_chacha\_20**(*unsigned char \*out*, *const unsigned char \*in*, *size\_t len*, *const unsigned char key\[32\]*, *const unsigned char iv\[8\]*, *uint64\_t counter*);

*void*\

**CRYPTO\_hchacha\_20**(*unsigned char out\[32\]*, *const unsigned char key\[32\]*, *const unsigned char iv\[16\]*);

*void*\

**CRYPTO\_xchacha\_20**(*unsigned char \*out*, *const unsigned char \*in*, *size\_t len*, *const unsigned char key\[32\]*, *const unsigned char iv\[24\]*);

## DESCRIPTION

These functions provide a low-level implementation of the ChaCha stream cipher with 256 and 128-bit keys. The number of rounds is hardcoded to 20; variants with 8 or 12 rounds are not supported.

Instead of using these functions directly, application programs normally use the more portable EVP\_chacha20(3) high-level interface.

The ChaCha state is contained in the *ChaCha\_ctx* structure and consists of sixteen 32-bit unsigned integers.

For the recommended value of 256 *keybits*, **ChaCha\_set\_key**() copies 32 bytes (256 bits) from *key* to the middle eight integers of the ChaCha state, using little endian order for each integer. For the alternative value of 128 *keybits*, only 16 bytes (128 bits) are copied from *key* to the ChaCha state, but they are copied twice, once to the second quarter and once to the third quarter. The first quarter of the ChaCha state is set to four constant integers; these constants differ depending on whether *keybits* is 128 or 256. The last quarter of the ChaCha state remains unchanged.

**ChaCha\_set\_iv**() copies eight bytes (64 bits) from *counter* and eight bytes (64 bits) from *iv* to the last quarter of the ChaCha state, the counter to the first two integers and the initialization vector to the last two integers, again in little endian order. If *counter* is NULL, the two respective integers are set to 0 instead. The first three quarters of the ChaCha state remain unchanged.

**ChaCha**() encrypts *len* bytes of data from *in* to *out* using the *ctx* that was previously set up with **ChaCha\_set\_key**() and **ChaCha\_set\_iv**(). Providing an *out* buffer of at least *len* bytes is the responsibility of the caller. This function can be called multiple times in a row with varying *len* arguments. The *len* does not need to be a multiple of 64.

**CRYPTO\_chacha\_20**() encrypts *len* bytes of data from *in* to *out* in a one-shot operation, using the given *key* and *iv* as described for **ChaCha\_set\_key**() and **ChaCha\_set\_iv**() and copying the less significant half of *counter* to the first counter integer in the initial ChaCha state and the more significant half to the second integer. Providing an *out* buffer of at least *len* bytes is again the responsibility of the caller. The maximum supported value for *len* is 2^32 - 1.

XChaCha is a variant of ChaCha designed to support longer nonces, just like XSalsa20 is a variant of Salsa20 supporting longer nonces.

**CRYPTO\_xchacha\_20**() encrypts *len* bytes of data from *in* to *out* in a one-shot operation with the XChaCha algorithm, using the given *key* and *iv*. It is equivalent to **CRYPTO\_chacha\_20**() with the last third of *iv*, a *counter* of 0, and a key generated with **CRYPTO\_hchacha\_20**() from the first two thirds of *iv*.

## SEE ALSO

[crypto(3)](/crypto/3.md), EVP\_chacha20(3) Daniel J. Bernstein, *ChaCha, a variant of Salsa20*, Chicago, January 28, 2008, https://cr.yp.to/chacha/chacha-20080128.pdf. Daniel J. Bernstein, *Extending the Salsa20 nonce*, Chicago, August 22, 2017, https://cr.yp.to/snuffle/xsalsa-20110204.pdf.

## STANDARDS

RFC 8439: ChaCha20 and Poly1305 for IETF Protocols

Note that the standard specifies a 32-bit counter and a 96-bit initialization vector whereas this implementation follows Bernstein's original specification and uses a 64-bit counter and a 64-bit initialization vector.

These functions are specific to LibreSSL and not provided by OpenSSL. BoringSSL does provide **CRYPTO\_chacha\_20**(), but with an incompatible interface, taking a 96-bit *iv* and a 32-bit *counter*.

## HISTORY

**ChaCha\_set\_key**(), **ChaCha\_set\_iv**(), **ChaCha**(), and **CRYPTO\_chacha\_20**() first appeared in OpenBSD 5.6.

**CRYPTO\_hchacha\_20**() and **CRYPTO\_xchacha\_20**() first appeared in OpenBSD 6.5.

## AUTHORS

This implementation was written by Daniel J. Bernstein ⟨*djb@cr.yp.to*⟩. The API layer was added by Joel Sing ⟨*jsing@openbsd.org*⟩ for ChaCha, and for XChaCha by David Gwynne ⟨*dlg@openbsd.org*⟩.
