fn gen_decryption_key()

in crypto/src/paillier.rs [70:110]


fn gen_decryption_key(key: MinimalDecryptionKey) -> DecryptionKey {
    assert!(key.p > BigUint::one());
    assert!(key.q > BigUint::one());

    let l_n = &key.p * &key.q;
    let l_pp = &key.p * &key.p;
    let l_qq = &key.q * &key.q;
    let l_nn = &l_n * &l_n;

    let l_p_1 = &key.p - BigUint::one();
    let l_q_1 = &key.q - BigUint::one();
    let l_p_inv = mod_inverse(&key.p, &key.q).unwrap().to_biguint().unwrap();
    let g = &l_n + BigUint::one();

    let l_p = l(&(g.modpow(&l_p_1, &l_pp)), &key.p);
    let l_q = l(&(g.modpow(&l_q_1, &l_qq)), &key.q);
    let l_h_p = mod_inverse(&l_p, &key.p).unwrap().to_biguint().unwrap();
    let l_h_q = mod_inverse(&l_q, &key.q).unwrap().to_biguint().unwrap();

    // let l = (&key.p - BigUint::one()) * (&key.q - BigUint::one());
    let l = &l_p_1 * &l_q_1;
    let m = mod_inverse(&l, &l_n).unwrap().to_biguint().unwrap();

    assert!(((&l * &m) % &l_n) == BigUint::one());

    DecryptionKey {
        p: key.p,
        q: key.q,
        p_1: l_p_1,
        q_1: l_q_1,
        p_inv: l_p_inv,
        n: l_n,
        pp: l_pp,
        qq: l_qq,
        nn: l_nn,
        h_p: l_h_p,
        h_q: l_h_q,
        lambda: l,
        mu: m,
    }
}