chacha20poly1305
nimony/lib/std/crypto/chacha20poly1305.nim
ChaCha20, Poly1305 and their AEAD construction (RFC 8439).
Constant time by construction: ChaCha20 is additions, rotations and xors only, and Poly1305 is done in 26-bit limbs so that every product fits a uint64 and the final reduction is a mask, not a branch.
type ChaChaKey = array[0..31, uint8]type ChaChaNonce = array[0..11, uint8]type Poly1305Tag = array[0..15, uint8]func chachaBlock(key: array[0..31, uint8]; counter: uint32; nonce: array[0..11, uint8]; output: var array[0..63, uint8])One 64-byte keystream block.
func chacha20Xor(key: array[0..31, uint8]; counter: uint32; nonce: array[0..11, uint8]; data: var openArray[uint8])Encrypts (or, identically, decrypts)
datain place with the keystream starting at blockcounter. The 32-bit block counter is all one (key, nonce) pair has:datalonger than the blocks left before it would wrap is a bug in the caller and stops the program, because past the wrap the keystream repeats -- from block 0, which the AEAD uses as the Poly1305 key.type Poly1305 = object r: array[0..4, uint32] h: array[0..4, uint32] pad: array[0..3, uint32] buf: array[0..15, uint8] bufLen: 0..15
func initPoly1305(key: array[0..31, uint8]): Poly1305func update(p: var Poly1305; data: openArray[uint8])func finish(p: Poly1305): array[0..15, uint8]func poly1305(key: array[0..31, uint8]; msg: openArray[uint8]): array[0..15, uint8]const MaxAeadData: int64The most bytes one (key, nonce) pair can seal (RFC 8439 ยง2.8's P_MAX): the data blocks are counted from 1 up to
high(uint32).func chacha20Poly1305Seal(key: array[0..31, uint8]; nonce: array[0..11, uint8]; aad: openArray[uint8]; data: var openArray[uint8]): array[0..15, uint8]Encrypts
datain place and returns the tag that authenticates it together withaad. At mostMaxAeadDatabytes; more is a bug that stops the program (seechacha20Xor).func chacha20Poly1305Open(key: array[0..31, uint8]; nonce: array[0..11, uint8]; aad: openArray[uint8]; data: var openArray[uint8]; tag: openArray[uint8]): boolChecks
tagand, only if it is right, decryptsdatain place. Onfalsethe ciphertext is left untouched: nothing derived from an unauthenticated message ever reaches the caller. More thanMaxAeadDatabytes cannot have been sealed and are refused.