-
Notifications
You must be signed in to change notification settings - Fork 85
Description
Hi,
Turns out we we don't really have roll as much crypto as your article says. Specifically, we can avoid implementing the round functions ourselves, and use regular Chacha20 instead. Here's an example in C, using Monocypher's public interface of IETF Chacha20:
void crypto_hchacha20(u8 out[32], const u8 key[32], const u8 in [16])
{
const u8 zero[64] = {0};
const u8 *nonce = in + 4;
const u32 ctr = load32_le(in);
const u8 *constant = (const u8*)"expand 32-byte k";
u8 block[64];
u32 words[ 8];
crypto_ietf_chacha20_ctr(block, zero, 64, key, nonce, ctr);
words[0] = load32_le(block + 0) - load32_le(constant + 0);
words[1] = load32_le(block + 4) - load32_le(constant + 4);
words[2] = load32_le(block + 8) - load32_le(constant + 8);
words[3] = load32_le(block + 12) - load32_le(constant + 12);
words[4] = load32_le(block + 48) - load32_le(in + 0);
words[5] = load32_le(block + 52) - load32_le(in + 4);
words[6] = load32_le(block + 56) - load32_le(in + 8);
words[7] = load32_le(block + 60) - load32_le(in + 12);
FOR (i, 0, 8) {
store32_le(out + i*4, words[i]);
}
WIPE_BUFFER(words);
WIPE_BUFFER(block);
}
There. No round function, and hardly any poking at Chacha20's internals. We can do this because HChacha20 is designed specifically to only reveal those values the attacker could have reconstructed, using the nonce and counter (which aren't secret). That's why the security reduction works.
Now this is still kind of a "roll your own crypto" thing, in the sense that even though I know Chacha20 like the back of my hand, I didn't get it right on the first try. But it's closest to "building HChacha20 on top of Chacha20" as you'll ever get.