gpgrv/
mpi.rs

1use num::bigint::BigUint;
2use num::integer::Integer;
3
4#[inline]
5pub fn pow_mod(val: &[u8], exp: &[u8], modulus: &[u8]) -> BigUint {
6    let modulus = BigUint::from_bytes_be(modulus);
7    let exp = BigUint::from_bytes_be(exp);
8
9    assert!(modulus.is_odd());
10    assert!(exp.is_odd());
11
12    BigUint::from_bytes_be(val).modpow(&exp, &modulus)
13}
14
15#[inline]
16pub fn eq(left: &BigUint, right: &[u8]) -> bool {
17    BigUint::from_bytes_be(right).eq(left)
18}
19
20#[cfg(test)]
21mod tests {
22    use num::bigint::BigUint;
23    use num::Zero;
24
25    #[test]
26    fn powm() {
27        assert_eq!(
28            &[125],
29            super::pow_mod(&[5], &[3], &[255]).to_bytes_be().as_slice()
30        );
31        // (259^3) % 513 == 283
32        assert_eq!(
33            &[1, 211],
34            super::pow_mod(&[1, 7], &[3], &[2, 1])
35                .to_bytes_be()
36                .as_slice()
37        );
38    }
39
40    #[test]
41    fn empty_vec() {
42        assert!(BigUint::from_bytes_be(&[]).is_zero());
43    }
44}