Skip to content

[Draft] Implement a fast-key-erasure ChaCha variant - #578

Draft
dhardy wants to merge 3 commits into
RustCrypto:masterfrom
dhardy:push-mqpplwyupvtq
Draft

[Draft] Implement a fast-key-erasure ChaCha variant#578
dhardy wants to merge 3 commits into
RustCrypto:masterfrom
dhardy:push-mqpplwyupvtq

Conversation

@dhardy

@dhardy dhardy commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Motivated by rust-random/rand#1826 (comment), I wanted to see if we could support a fast-key-erasure generator. Yes, I believe we can, and without much code.

Performance penalty: 12-13% for 1kiB blocks, 20-25% for single u32 values.

Details

There are two parts to this:

  1. We overwrite the key using the first 8 (of 64) values from the results buffer after each generation.
  2. We overwrite each value consumed from the buffer with zero.

I believe this is all that's required for forward security.

Reseeding?

As noted here, forward security (backtracking resistance) arguably has more value than "backward security" (reseeding) since if an attacker has compromised the system state, there is reason to believe they may be able to do so again. On the other hand, periodic reseeding may be useful for other reasons, e.g. if a process is forked without explicit reseeding (i.e. a bug).

Anyway, there is no reason we can't layer one on top of the other.

Comment thread chacha20/src/rng.rs
// The counter is incremented like usual (i.e. it is not reset).
fn generate(&mut self, buffer: &mut [u32; BUFFER_SIZE]) -> usize {
let _ = self.0.generate(buffer);
self.0.state[4..12].copy_from_slice(&buffer[0..8]);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While this overwrites the original value, doesn't it also leave the newly generated key in the output buffer?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aah, is that what this is intended to address? rust-random/rand_core#81

@dhardy dhardy Aug 23, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While this overwrites the original value, doesn't it also leave the newly generated key in the output buffer?

Yes. We could erase it immediately but I didn't see the point: the output buffer should be right next to the key in memory and will be overwritten next time output is generated (the next key update).

Yes, it's related to that PR; see also rust-random/rand#1828 for context.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants