use crate::rsa2048::big;
use crate::rsa2048::ff;
use crate::rsa2048::ff::SF;
use crate::rsa2048::ff::DF;
use crate::rand::RAND;
pub const RFS: usize = (big::MODBYTES as usize) * ff::FFLEN;
pub const SHA256: usize = 32;
pub const SHA384: usize = 48;
pub const SHA512: usize = 64;
pub const SL: usize = ff::SL;
pub const DL: usize = ff::DL;
pub const HASH_TYPE: usize = SHA256;
pub struct RsaPrivateKey {
p: SF,
q: SF,
dp: SF,
dq: SF,
c: SF,
}
pub struct RsaPublicKey {
e: isize,
n: DF,
}
pub fn new_private_key() -> RsaPrivateKey {
RsaPrivateKey {
p: SF::new(),
q: SF::new(),
dp: SF::new(),
dq: SF::new(),
c: SF::new(),
}
}
pub fn new_public_key() -> RsaPublicKey {
RsaPublicKey {
e: 0,
n: DF::new(),
}
}
pub fn set_public_key(pk: &mut RsaPublicKey,e: isize, f: &[u8]) {
pk.e=e;
let mut r = DF::new();
r.frombytes(f);
pk.n.copy(&r);
}
pub fn rsa_private_key_from_openssl(p: &[u8],q: &[u8],dp: &[u8],dq: &[u8],c: &[u8], prv: &mut RsaPrivateKey) {
prv.p.frombytes(q);
prv.q.frombytes(p);
prv.dp.frombytes(dq);
prv.dq.frombytes(dp);
prv.c.frombytes(c);
}
pub fn key_pair_from_openssl(e: isize, p: &[u8],q: &[u8],dp: &[u8],dq: &[u8],c: &[u8], prv: &mut RsaPrivateKey, pbc: &mut RsaPublicKey) {
rsa_private_key_from_openssl(p,q,dp,dq,c,prv);
pbc.n = prv.p.mul(&prv.q);
pbc.e = e;
}
pub fn key_pair(rng: &mut impl RAND, e: isize, prv: &mut RsaPrivateKey, pbc: &mut RsaPublicKey) {
let mut t = SF::new();
let mut p1 = SF::new();
let mut q1 = SF::new();
loop {
prv.p.random(rng);
while prv.p.lastbits(2) != 3 {
prv.p.inc(1)
}
while !prv.p.isprime(rng) {
prv.p.inc(4);
}
p1.copy(&prv.p);
p1.dec(1);
if p1.cfactor(e) {
continue;
}
break;
}
loop {
prv.q.random(rng);
while prv.q.lastbits(2) != 3 {
prv.q.inc(1)
}
while !prv.q.isprime(rng) {
prv.q.inc(4);
}
q1.copy(&prv.q);
q1.dec(1);
if q1.cfactor(e) {
continue;
}
break;
}
pbc.n = prv.p.mul(&prv.q);
pbc.e = e;
t.copy(&p1);
t.shr();
prv.dp.set(e);
prv.dp.invmodp(&t);
if prv.dp.parity() == 0 {
prv.dp.add(&t)
}
prv.dp.norm();
t.copy(&q1);
t.shr();
prv.dq.set(e);
prv.dq.invmodp(&t);
if prv.dq.parity() == 0 {
prv.dq.add(&t)
}
prv.dq.norm();
prv.c.copy(&prv.p);
prv.c.invmodp(&prv.q);
}
pub fn private_key_kill(prv: &mut RsaPrivateKey) {
prv.p.zero();
prv.q.zero();
prv.dp.zero();
prv.dq.zero();
prv.c.zero();
}
pub fn encrypt(pbc: &RsaPublicKey, f: &[u8], g: &mut [u8]) {
let mut r = DF::new();
r.frombytes(f);
r.power(pbc.e, &pbc.n);
r.tobytes(g);
}
pub fn decrypt(prv: &RsaPrivateKey, g: &[u8], f: &mut [u8]) {
let mut r = DF::new();
r.frombytes(g);
let mut jp = r.dmod(&prv.p);
let mut jq = r.dmod(&prv.q);
jp.skpow(&prv.dp, &prv.p);
jq.skpow(&prv.dq, &prv.q);
r.zero();
r.dscopy(&jp);
jp.rmod(&prv.q);
if jp.comp(&jq) > 0 {
jq.add(&prv.q)
}
jq.sub(&jp);
jq.norm();
let mut t = prv.c.mul(&jq);
jq = t.dmod(&prv.q);
t = jq.mul(&prv.p);
r.add(&t);
r.norm();
r.tobytes(f);
}