1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
pub mod rsa;

use std::fs::File;
use std::io::prelude::Read;

// calculate b ^ e
pub fn pow(b: i128, e: i128) -> i128 {
    if e == 0 {
        return 0;
    }
    let mut r = b;
    for _ in 0..e - 1 {
        r *= b;
    }
    r
}

// calculate (b ^ e) % e
pub fn mod_pow(b: i128, e: i128, m: i128) -> i128 {
    let mut r: i128 = 1;
    for _ in 0..e {
        r = (r * b) % m;
    }
    r
}

// random Vec<u8> from /dev/urandom
pub fn random(size: usize) -> Option<Vec<u8>> {
    let mut file = match File::open("/dev/urandom") {
        Ok(file) => file,
        Err(_) => return None,
    };
    let mut buf = vec![0; size];
    match file.read_exact(&mut buf) {
        Ok(_) => {}
        Err(_) => return None,
    };
    Some(buf)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_pow() {
        assert_eq!(pow(1547, 3), 3_702_294_323);
        assert_eq!(pow(123, 5), 28_153_056_843);
        assert_eq!(pow(123, 3), 1_860_867);
        assert_eq!(pow(123, 2), 15_129);
        assert_eq!(pow(123, 1), 123);
        assert_eq!(pow(123, 0), 0);
    }

    #[test]
    fn test_mod_pow() {
        assert_eq!(mod_pow(1_547, 3, 5), 3);
        assert_eq!(mod_pow(9_715, 24, 7), 1);
    }

    #[test]
    fn test_random() {
        assert_eq!(random(10).unwrap().len(), 10);
    }
}