So What Is XChaCha20?

So what’s the encryption that is being used to secure this article? Well, that’s easy, we can just connect to medium.com with OpenSSL:

Photo by Adrian Dascal on Unsplash

So What Is XChaCha20?

So what’s the encryption that is being used to secure this article? Well, that’s easy, we can just connect to medium.com with OpenSSL:

% openssl s_client  -connect medium.com:443  
CONNECTED(00000005)
depth=2 C = IE, O = Baltimore, OU = CyberTrust, CN = Baltimore CyberTrust Root
verify return:1
depth=1 C = US, O = "Cloudflare, Inc.", CN = Cloudflare Inc ECC CA-3
verify return:1
depth=0 C = US, ST = California, L = San Francisco, O = "Cloudflare, Inc.", CN = medium.com
verify return:1
---
Certificate chain
0 s:C = US, ST = California, L = San Francisco, O = "Cloudflare, Inc.", CN = medium.com
i:C = US, O = "Cloudflare, Inc.", CN = Cloudflare Inc ECC CA-3
1 s:C = US, O = "Cloudflare, Inc.", CN = Cloudflare Inc ECC CA-3
i:C = IE, O = Baltimore, OU = CyberTrust, CN = Baltimore CyberTrust Root
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIFETCCBLigAwIBAgIQByb9+sR9lKGEIcyuAhSUTjAKBggqhkjOPQQDAjBKMQsw
CQYDVQQGEwJVUzEZMBcGA1UEChMQQ2xvdWRmbGFyZSwgSW5jLjEgMB4GA1UEAxMX
Q2xvdWRmbGFyZSBJbmMgRUNDIENBLTMwHhcNMjEwOTAxMDAwMDAwWhcNMjExMTI5
MjM1OTU5WjBqMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQG
A1UEBxMNU2FuIEZyYW5jaXNjbzEZMBcGA1UEChMQQ2xvdWRmbGFyZSwgSW5jLjET
MBEGA1UEAxMKbWVkaXVtLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABFMm
ACdZQgB87z2inLlwoMm7lLYN2n1DPreV1fjR8tK6iRdy24J3nik8Rr9WTy1f+keK
Z781EjbLID0y1iJhHfCjggNeMIIDWjAfBgNVHSMEGDAWgBSlzjfq67B1DpRniLRF
+tkkEIeWHzAdBgNVHQ4EFgQUAdZUFH9hIHTShLf1tlLRqEy6dRIwIwYDVR0RBBww
GoIMKi5tZWRpdW0uY29tggptZWRpdW0uY29tMA4GA1UdDwEB/wQEAwIHgDAdBgNV
HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwewYDVR0fBHQwcjA3oDWgM4YxaHR0
cDovL2NybDMuZGlnaWNlcnQuY29tL0Nsb3VkZmxhcmVJbmNFQ0NDQS0zLmNybDA3
oDWgM4YxaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL0Nsb3VkZmxhcmVJbmNFQ0ND
QS0zLmNybDA+BgNVHSAENzA1MDMGBmeBDAECAjApMCcGCCsGAQUFBwIBFhtodHRw
Oi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwdgYIKwYBBQUHAQEEajBoMCQGCCsGAQUF
BzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQAYIKwYBBQUHMAKGNGh0dHA6
Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9DbG91ZGZsYXJlSW5jRUNDQ0EtMy5jcnQw
DAYDVR0TAQH/BAIwADCCAX8GCisGAQQB1nkCBAIEggFvBIIBawFpAHcA9lyUL9F3
MCIUVBgIMJRWjuNNExkzv98MLyALzE7xZOMAAAF7nrSnzAAABAMASDBGAiEA6UX8
PX8ljRUOP/oOP+VSgiFRuOjNYJ5PSSBJ9Y/ozp0CIQCNbRTzMsrPXnyNjYHqg3F+
WWe92IdjxEmYYmc2qzby7wB2AFzcQ5L+5qtFRLFemtRW5hA3+9X6R9yhc5SyXub2
xw7KAAABe560p4UAAAQDAEcwRQIgfsaGhBdF1u58Up7l4DjxyBE5OcONDWHTC7Kl
qLJG+HkCIQCobJkXD0ZYqlqHf1N3FfUOrGMuqRKdvq8Tin58XC1qTQB2AO7Ale6N
cmQPkuPDuRvHEqNpagl7S2oaFDjmR7LL7cX5AAABe560p6sAAAQDAEcwRQIgA4jB
eOUE7BGsEWeKy4yn60NLFLIORiCKSXolW6hmNtcCIQCN6yQ63/D6M1EbBVzrlfW+
5y6l1C8RnsigO5RGIr6wNTAKBggqhkjOPQQDAgNHADBEAiBYidGfaU2TGdsybZRS
gXafj8YKqpr1H8yeXfbW91RUPgIgXNntU9O9JzjgV0p0O3EEeVaHIxQ6C9qJTXBV
i5VHDJo=
-----END CERTIFICATE-----
subject=C = US, ST = California, L = San Francisco, O = "Cloudflare, Inc.", CN = medium.com

issuer=C = US, O = "Cloudflare, Inc.", CN = Cloudflare Inc ECC CA-3

---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: ECDSA
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 2591 bytes and written 392 bytes
Verification: OK
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 256 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
---
Post-Handshake New Session Ticket arrived:
SSL-Session:
Protocol : TLSv1.3
Cipher : TLS_AES_256_GCM_SHA384
Session-ID: 23EE081A0FC83B1E27B454A01813609F480FEB3DF01EE1BBC5FB7C09F90E02ED
Session-ID-ctx:
Resumption PSK: A906AD6159F64DE1A67A44BD1FB2040360334B1F6C9960D9245B6BC211724DE7624AC335BCDA992F3653EA829AC34365
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 64800 (seconds)
TLS session ticket:
0000 - 64 e5 32 b4 08 20 87 7d-74 7e 37 23 d6 0f 95 c5 d.2.. .}t~7#....
0010 - 46 5d 3b 29 0d d3 4e bd-0d a5 d4 04 12 f8 db 08 F];)..N.........
0020 - e8 47 37 82 75 f9 de f8-f7 40 cc b3 4a b3 1f 3c [email protected]..<
0030 - db 4a fc 68 36 b7 32 7b-9f ea ab c8 35 e5 24 9d .J.h6.2{....5.$.
0040 - a5 ae 24 a8 22 c2 97 69-1e 93 80 aa fa 2a 56 f6 ..$."..i.....*V.
0050 - 93 f1 c2 48 11 ff 4b 62-86 9f 1f 6a 1d dd 92 18 ...H..Kb...j....
0060 - 43 90 76 32 e4 9c 71 21-38 8c 0e c3 dc 75 72 df C.v2..q!8....ur.
0070 - b1 10 22 2d d4 0d b0 c3-e3 d1 04 0c 01 64 4f 9a .."-.........dO.
0080 - 94 7c 4f fa 5a 31 fa 79-ce a4 6b 39 4b a9 99 28 .|O.Z1.y..k9K..(
0090 - e5 fa c2 fd 4d 29 11 12-f9 83 e7 79 36 06 2e f4 ....M).....y6...
00a0 - d5 42 02 c4 93 d4 47 e7-b8 a2 59 60 60 85 be 6b .B....G...Y``..k
00b0 - 43 bd 52 8e 22 e5 1b 6c-15 25 d2 f2 0b 53 c2 52 C.R."..l.%...S.R

Start Time: 1632678951
Timeout : 7200 (sec)
Verify return code: 0 (ok)
Extended master secret: no
Max Early Data: 0
---
read R BLOCK

closed

We see we have TLS_AES_256_GCM_SHA384, and which uses 256-bit AES (GCM) symmetric key encryption and with SHA-384 for the hashing method. Overall, TLS 1.3 often uses AES GCM and which is a stream cipher mode of AES. We can also use ChaCha20, and which is an alternative to AES GCM. Now let’s connect to Medium, using ChaCha20:

% openssl s_client  -connect medium.com:443 -ciphersuites: TLS_CHACHA20_POLY1305_SHA256
depth=2 C = IE, O = Baltimore, OU = CyberTrust, CN = Baltimore CyberTrust Root
verify return:1
depth=1 C = US, O = "Cloudflare, Inc.", CN = Cloudflare Inc ECC CA-3
verify return:1
depth=0 C = US, ST = California, L = San Francisco, O = "Cloudflare, Inc.", CN = medium.com
verify return:1
---
Certificate chain
0 s:C = US, ST = California, L = San Francisco, O = "Cloudflare, Inc.", CN = medium.com
i:C = US, O = "Cloudflare, Inc.", CN = Cloudflare Inc ECC CA-3
1 s:C = US, O = "Cloudflare, Inc.", CN = Cloudflare Inc ECC CA-3
i:C = IE, O = Baltimore, OU = CyberTrust, CN = Baltimore CyberTrust Root
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIFETCCBLigAwIBAgIQByb9+sR9lKGEIcyuAhSUTjAKBggqhkjOPQQDAjBKMQsw
CQYDVQQGEwJVUzEZMBcGA1UEChMQQ2xvdWRmbGFyZSwgSW5jLjEgMB4GA1UEAxMX
Q2xvdWRmbGFyZSBJbmMgRUNDIENBLTMwHhcNMjEwOTAxMDAwMDAwWhcNMjExMTI5
MjM1OTU5WjBqMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQG
A1UEBxMNU2FuIEZyYW5jaXNjbzEZMBcGA1UEChMQQ2xvdWRmbGFyZSwgSW5jLjET
MBEGA1UEAxMKbWVkaXVtLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABFMm
ACdZQgB87z2inLlwoMm7lLYN2n1DPreV1fjR8tK6iRdy24J3nik8Rr9WTy1f+keK
Z781EjbLID0y1iJhHfCjggNeMIIDWjAfBgNVHSMEGDAWgBSlzjfq67B1DpRniLRF
+tkkEIeWHzAdBgNVHQ4EFgQUAdZUFH9hIHTShLf1tlLRqEy6dRIwIwYDVR0RBBww
GoIMKi5tZWRpdW0uY29tggptZWRpdW0uY29tMA4GA1UdDwEB/wQEAwIHgDAdBgNV
HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwewYDVR0fBHQwcjA3oDWgM4YxaHR0
cDovL2NybDMuZGlnaWNlcnQuY29tL0Nsb3VkZmxhcmVJbmNFQ0NDQS0zLmNybDA3
oDWgM4YxaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL0Nsb3VkZmxhcmVJbmNFQ0ND
QS0zLmNybDA+BgNVHSAENzA1MDMGBmeBDAECAjApMCcGCCsGAQUFBwIBFhtodHRw
Oi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwdgYIKwYBBQUHAQEEajBoMCQGCCsGAQUF
BzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQAYIKwYBBQUHMAKGNGh0dHA6
Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9DbG91ZGZsYXJlSW5jRUNDQ0EtMy5jcnQw
DAYDVR0TAQH/BAIwADCCAX8GCisGAQQB1nkCBAIEggFvBIIBawFpAHcA9lyUL9F3
MCIUVBgIMJRWjuNNExkzv98MLyALzE7xZOMAAAF7nrSnzAAABAMASDBGAiEA6UX8
PX8ljRUOP/oOP+VSgiFRuOjNYJ5PSSBJ9Y/ozp0CIQCNbRTzMsrPXnyNjYHqg3F+
WWe92IdjxEmYYmc2qzby7wB2AFzcQ5L+5qtFRLFemtRW5hA3+9X6R9yhc5SyXub2
xw7KAAABe560p4UAAAQDAEcwRQIgfsaGhBdF1u58Up7l4DjxyBE5OcONDWHTC7Kl
qLJG+HkCIQCobJkXD0ZYqlqHf1N3FfUOrGMuqRKdvq8Tin58XC1qTQB2AO7Ale6N
cmQPkuPDuRvHEqNpagl7S2oaFDjmR7LL7cX5AAABe560p6sAAAQDAEcwRQIgA4jB
eOUE7BGsEWeKy4yn60NLFLIORiCKSXolW6hmNtcCIQCN6yQ63/D6M1EbBVzrlfW+
5y6l1C8RnsigO5RGIr6wNTAKBggqhkjOPQQDAgNHADBEAiBYidGfaU2TGdsybZRS
gXafj8YKqpr1H8yeXfbW91RUPgIgXNntU9O9JzjgV0p0O3EEeVaHIxQ6C9qJTXBV
i5VHDJo=
-----END CERTIFICATE-----
subject=C = US, ST = California, L = San Francisco, O = "Cloudflare, Inc.", CN = medium.com

issuer=C = US, O = "Cloudflare, Inc.", CN = Cloudflare Inc ECC CA-3

---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: ECDSA
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 2577 bytes and written 372 bytes
Verification: OK
---
New, TLSv1.3, Cipher is TLS_CHACHA20_POLY1305_SHA256
Server public key is 256 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
---
Post-Handshake New Session Ticket arrived:
SSL-Session:
Protocol : TLSv1.3
Cipher : TLS_CHACHA20_POLY1305_SHA256
Session-ID: 35034D82873D8D958664B2683EA60BDF5E9C101A54A9D65763E32B7CE8FB7F1E
Session-ID-ctx:
Resumption PSK: 5EAA9359F2ADBB48AC037B04FA5D6576E552B12F2953E4449544EBCC3F15799F
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 64800 (seconds)
TLS session ticket:
0000 - 3f e4 81 0f f1 bf 03 a5-e1 5b 33 a7 ec 04 25 ee ?........[3...%.
0010 - eb 65 94 0e 84 0d 9e 08-2e 4b b6 8c f9 5b 5b 19 .e.......K...[[.
0020 - cd 37 17 8a d5 b8 2f 1f-2a c6 c0 6f 4d 12 19 77 .7..../.*..oM..w
0030 - 82 d0 cb f5 c6 a4 a8 0a-bd b6 f4 23 11 c7 fc 86 ...........#....
0040 - ab 14 6b 17 3c 59 2f c0-76 48 9e 82 c4 c8 ad b7 ..k.<Y/.vH......
0050 - 4f 74 76 42 c8 a3 13 f3-cf 27 5c d7 1e 6e 62 41 OtvB.....'\..nbA
0060 - e6 4c a6 2e c9 97 83 f4-73 97 15 f4 df 2f 13 ae .L......s..../..
0070 - d2 5e 9d 4a 04 57 4e 3f-5a 4e 50 a3 52 82 3c 19 .^.J.WN?ZNP.R.<.
0080 - 79 e0 3a 09 d7 b1 36 62-af ec cf af 14 14 16 3d y.:...6b.......=
0090 - 0b 5c 85 68 95 cd 6d df-42 6d 2c de 3a 8b a6 dc .\.h..m.Bm,.:...
00a0 - 2a 68 0f a1 95 16 da 81-51 7e 71 18 12 8a df 4e *h......Q~q....N

Start Time: 1632679280
Timeout : 7200 (sec)
Verify return code: 0 (ok)
Extended master secret: no
Max Early Data: 0
---
read R BLOCK

You can learn about ChaCha here:

Implementing XChaCha20 and Poly1305

With symmetric-key, Bob and Alice have the same key. NaCl uses the XChaCha20 method, and which supports stream encryption (and which does not require padding as a block cipher does, and is also faster than block cipher modes). ChaCha20 was created by Daniel J. Bernstein and has an eight-byte or 16-byte nonce. XChaCha20 (eXtended-nonce ChaCha) is an update to ChaCha20, and uses a 24 byte nonce. It was created by S. Arciszewski:

XChaCha20 has a lower probability of nonce misuse than ChaCha20. The cipher text is made up of the cipher message (and which is the same length as the plaintext message) is the same number of bytes as the message (five bytes), and that the cipher text has an extra 16 bytes (used for AEAD — Authenticated Encryption with Associated Data). The MAC bytes used Poly1305 and provide an integrity check for the cipher.

For XChaCha20, we can use the PyNaCl library. The code is [here]:

import nacl.secret
import nacl.utils
import binascii
import sys

mess='hello'
if (len(sys.argv)>1):
mess=str(sys.argv[1])
print("Message: ",mess)
message=mess.encode()
key=nacl.utils.random(nacl.secret.SecretBox.KEY_SIZE)
box=nacl.secret.SecretBox(key)
nonce=nacl.utils.random(nacl.secret.SecretBox.NONCE_SIZE)
encrypted= box.encrypt(message,nonce)
plain = box.decrypt(encrypted)
print ("\nKey (32 byte): ",binascii.b2a_hex(key))
print ("Nonce (24 byte): ",binascii.b2a_hex(nonce))
print ("\nEncrypted: ",binascii.b2a_hex(encrypted.ciphertext))
print (f"Length of cipher: {len(encrypted.ciphertext)} = Cipher message: {len(message)} + MAC bytes: {box.MACBYTES}")
print ("\nDecrypted: ",plain.decode())

A sample run is [here]:

Message:  hello
Key (32 byte):  b'b3a11180166e83c3d8954dfeb9fb4ecbe5e5d222efa3d1c9014d0dfcfaedec80'
Nonce (24 byte): b'629380e6ba96504d7d84a351d63ab5c57b8a6882ef5e6e0f'
Encrypted:  b'9b23fe50e0e66b6f8c6c398ef0f01b467520b4bc06'
Length of cipher: 21 = Cipher message: 5 + MAC bytes: 16
Decrypted:  hello

We can see that the length of the cipher message is the same number of bytes as the message (five bytes) and that the ciphertext has an extra 16 bytes (used for AEAD — Authenticated Encryption with Associated Data). The MAC bytes used Poly1305. These bytes provide an integrity check for the cipher.