use bn::{BigNumber, BigNumberContext};
use errors::IndyCryptoError;
pub fn generate_RSA_modulus(size: usize,
ctx: &mut BigNumberContext) -> Result<(BigNumber, BigNumber, BigNumber), IndyCryptoError> {
if size % 2 != 0 {
return Err(IndyCryptoError::InvalidParam1(
format!("Need an even number of bits, found {}", size))
);
}
let factor_size = size / 2;
let p = BigNumber::generate_safe_prime(factor_size)?;
let q = BigNumber::generate_safe_prime(factor_size)?;
let n = p.mul(&q, Some(ctx))?;
Ok((n, p, q))
}
pub fn generate_witness(initial_witness: &BigNumber, exponents: &Vec<&BigNumber>,
modulus: &BigNumber, ctx: &mut BigNumberContext) -> Result<BigNumber, IndyCryptoError> {
let mut updated_witness = initial_witness.clone()?;
for &e in exponents.iter() {
updated_witness = updated_witness.mod_exp(&e, modulus, Some(ctx))?;
}
Ok(updated_witness)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_generate_RSA_modulus_basic() {
let mut ctx = BigNumber::new_context().unwrap();
let (n, p, q) = generate_RSA_modulus(2048, &mut ctx).unwrap();
assert!(BigNumber::is_prime(&p,Some(&mut ctx)).unwrap());
assert!(BigNumber::is_prime(&q,Some(&mut ctx)).unwrap());
assert_eq!(n, p.mul(&q, Some(&mut ctx)).unwrap());
}
#[test]
fn test_generate_witness() {
let mut ctx = BigNumber::new_context().unwrap();
let initial_witness = BigNumber::from_dec("5").unwrap();
let e1 = BigNumber::from_dec("3").unwrap();
let e2 = BigNumber::from_dec("5").unwrap();
let e3 = BigNumber::from_dec("7").unwrap();
let e4 = BigNumber::from_dec("11").unwrap();
let e5 = BigNumber::from_dec("13").unwrap();
let exps = vec![&e1, &e2, &e3, &e4, &e5];
let n = BigNumber::from_dec("17").unwrap();
assert_eq!(BigNumber::from_dec("10").unwrap(), generate_witness(&initial_witness,
&exps, &n, &mut ctx).unwrap())
}
}