Skip to content

Cleverer way to implement HChacha20 #10

@LoupVaillant

Description

@LoupVaillant

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions