67 lines
1.8 KiB
Rust
67 lines
1.8 KiB
Rust
use openssl::bn::{BigNum, BigNumContext};
|
||
use rust_util::XResult;
|
||
|
||
#[derive(Debug)]
|
||
pub struct RsaCrt {
|
||
// n = p * q
|
||
pub modulus: BigNum,
|
||
// e
|
||
pub public_exponent: BigNum,
|
||
// d = e mod inverse ((p - 1) * (q - 1))
|
||
pub private_exponent: BigNum,
|
||
// p
|
||
pub prime1: BigNum,
|
||
// q
|
||
pub prime2: BigNum,
|
||
// dp = d mod (p−1)
|
||
pub exponent1: BigNum,
|
||
// dq = d mod (q−1)
|
||
pub exponent2: BigNum,
|
||
// qinv = q^−1 mod p
|
||
pub coefficient: BigNum,
|
||
}
|
||
|
||
impl RsaCrt {
|
||
pub fn from(p: BigNum, q: BigNum, e: BigNum) -> XResult<RsaCrt> {
|
||
Ok(opt_result!( inner_from(p, q, e), "Calc RsaCrt failed: {}"))
|
||
}
|
||
}
|
||
|
||
pub fn clone_big_num(n: &BigNum) -> XResult<BigNum> {
|
||
Ok(opt_result!(BigNum::from_slice(n.to_vec().as_slice()), "Clone big num:{}, failed: {}", n))
|
||
}
|
||
|
||
fn inner_from(p: BigNum, q: BigNum, e: BigNum) -> XResult<RsaCrt> {
|
||
let mut n = BigNum::new()?;
|
||
n.checked_mul(&p, &q, &mut BigNumContext::new().unwrap())?;
|
||
|
||
let mut p_m1 = clone_big_num(&p)?;
|
||
p_m1.sub_word(1)?;
|
||
let mut q_m1 = clone_big_num(&q)?;
|
||
q_m1.sub_word(1)?;
|
||
let mut m = BigNum::new()?;
|
||
m.checked_mul(&p_m1, &q_m1, &mut BigNumContext::new().unwrap())?;
|
||
|
||
let mut d = BigNum::new()?;
|
||
d.mod_inverse(&e, &m, &mut BigNumContext::new().unwrap())?;
|
||
|
||
let mut dp = BigNum::new()?;
|
||
dp.nnmod(&d, &p_m1, &mut BigNumContext::new().unwrap())?;
|
||
|
||
let mut dq = BigNum::new()?;
|
||
dq.nnmod(&d, &q_m1, &mut BigNumContext::new().unwrap())?;
|
||
|
||
let mut qinv = BigNum::new()?;
|
||
qinv.mod_inverse(&q, &p, &mut BigNumContext::new().unwrap())?;
|
||
|
||
Ok(RsaCrt {
|
||
modulus: n,
|
||
public_exponent: e,
|
||
private_exponent: d,
|
||
prime1: p,
|
||
prime2: q,
|
||
exponent1: dp,
|
||
exponent2: dq,
|
||
coefficient: qinv,
|
||
})
|
||
} |