Skip to content

ChaCha RNG block/word position #438

Description

@dhardy

Currently this consists of:

// return 36 bit counter
pub fn get_word_pos(&self) -> u64;

// supports `u64` or `[u8; 5]`
// NOTE: [u8; 5] input uses a weird mixed-endian format
pub fn set_word_pos<W: Into<WordPosInput>>(&mut self, word_offset: W);

// supports `u32` or `[u8; 4]`
pub fn set_block_pos<B: Into<BlockPos>>(&mut self, block_pos: B);

pub fn get_block_pos(&self) -> u32;

First, we need 64-bit counters; thats #334 and #399.

Second, there are some weird Endian-conversions going on here. I would go into them except a more radical reform might be better.

Third, I don't think there's a good reason we need to support byte-arrays. Let users call to_le_bytes if they need that. (We don't technically need get_word_pos below either, but it's very little code and serves as an example.)

Proposal:

/// Get block position and sub-block index
///
/// Returns `(block_position, index)` where `index` is a value in the range `0..=16`.
pub fn get_block_pos(&self) -> (u64, u8) {
    self.core.core.0.state[12] as u64 | (self.core.core.0.state[13] as u64) << 32
}

/// Get the word position
///
/// This is a 68-bit index.
#[inline]
pub fn get_word_pos(&self) -> u128 {
    let (block, index) = self.get_block_pos();
    (block as u128) << 4 | ((index & 0b1111) as u128)
}

/// Set the block position
///
/// The sub-block index is reset to 0.
pub fn set_block_pos(&mut self, block: u64) {
    self.core.core.0.state[12] = block as u32;
    self.core.core.0.state[13] = (block >> 32) as u32;
    self.core.reset();
}

/// Set the word position
///
/// The low 68 bits are used; higher bits are ignored.
pub fn set_word_pos(&mut self, word: u128) {
    self.set_block_pos((word >> 4) as u64);
    let index = (word >> 4) as usize;
    self.core.generate_and_set(index);
}

I won't make a PR because I don't want to interfere with #399 or whatever @nstilt1 is up to.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions