Skip to content

ChaCha RNG block/word position #438

@dhardy

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.

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