Skip to main content

argon2/
memory.rs

1// Copyright (c) 2017 Martijn Rijkeboer <mrr@sru-systems.com>
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9use crate::block::Block;
10use std::fmt;
11use std::fmt::Debug;
12use std::ops::{Index, IndexMut};
13
14/// Structure representing the memory matrix.
15pub struct Memory {
16    /// The number of rows.
17    rows: usize,
18
19    /// The number of columns.
20    cols: usize,
21
22    /// The flat array of blocks representing the memory matrix.
23    pub blocks: Box<[Block]>,
24}
25
26impl Memory {
27    /// Creates a new memory matrix.
28    pub fn new(lanes: u32, lane_length: u32) -> Memory {
29        let rows = lanes as usize;
30        let cols = lane_length as usize;
31        let total = rows * cols;
32        let blocks = vec![Block::zero(); total].into_boxed_slice();
33        Memory { rows, cols, blocks }
34    }
35}
36
37impl Debug for Memory {
38    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
39        write!(f, "Memory {{ rows: {}, cols: {} }}", self.rows, self.cols)
40    }
41}
42
43impl Index<u32> for Memory {
44    type Output = Block;
45    fn index(&self, index: u32) -> &Block {
46        &self.blocks[index as usize]
47    }
48}
49
50impl Index<u64> for Memory {
51    type Output = Block;
52    fn index(&self, index: u64) -> &Block {
53        &self.blocks[index as usize]
54    }
55}
56
57impl Index<(u32, u32)> for Memory {
58    type Output = Block;
59    fn index(&self, index: (u32, u32)) -> &Block {
60        let pos = ((index.0 as usize) * self.cols) + (index.1 as usize);
61        &self.blocks[pos]
62    }
63}
64
65impl IndexMut<u32> for Memory {
66    fn index_mut(&mut self, index: u32) -> &mut Block {
67        &mut self.blocks[index as usize]
68    }
69}
70
71impl IndexMut<u64> for Memory {
72    fn index_mut(&mut self, index: u64) -> &mut Block {
73        &mut self.blocks[index as usize]
74    }
75}
76
77impl IndexMut<(u32, u32)> for Memory {
78    fn index_mut(&mut self, index: (u32, u32)) -> &mut Block {
79        let pos = ((index.0 as usize) * self.cols) + (index.1 as usize);
80        &mut self.blocks[pos]
81    }
82}
83
84#[cfg(test)]
85mod tests {
86
87    use crate::memory::Memory;
88
89    #[test]
90    fn new_returns_correct_instance() {
91        let lanes = 4;
92        let lane_length = 128;
93        let memory = Memory::new(lanes, lane_length);
94        assert_eq!(memory.rows, lanes as usize);
95        assert_eq!(memory.cols, lane_length as usize);
96        assert_eq!(memory.blocks.len(), 512);
97    }
98}