/* RSA decryption with the private key */ public static void DECRYPT(rsa_private_key PRIV, sbyte[] G, sbyte[] F) { int n = PRIV.p.getlen(); FF g = new FF(2 * n); FF.fromBytes(g, G); FF jp = g.dmod(PRIV.p); FF jq = g.dmod(PRIV.q); jp.skpow(PRIV.dp, PRIV.p); jq.skpow(PRIV.dq, PRIV.q); g.zero(); g.dscopy(jp); jp.mod(PRIV.q); if (FF.comp(jp, jq) > 0) { jq.add(PRIV.q); } jq.sub(jp); jq.norm(); FF t = FF.mul(PRIV.c, jq); jq = t.dmod(PRIV.q); t = FF.mul(jq, PRIV.p); g.add(t); g.norm(); g.toBytes(F); }
/* generate an RSA key pair */ public static void KEY_PAIR(RAND rng, int e, rsa_private_key PRIV, rsa_public_key PUB) { // IEEE1363 A16.11/A16.12 more or less int n = PUB.n.getlen() / 2; FF t = new FF(n); FF p1 = new FF(n); FF q1 = new FF(n); for (;;) { PRIV.p.random(rng); while (PRIV.p.lastbits(2) != 3) { PRIV.p.inc(1); } while (!FF.prime(PRIV.p, rng)) { PRIV.p.inc(4); } p1.copy(PRIV.p); p1.dec(1); if (p1.cfactor(e)) { continue; } break; } for (;;) { PRIV.q.random(rng); while (PRIV.q.lastbits(2) != 3) { PRIV.q.inc(1); } while (!FF.prime(PRIV.q, rng)) { PRIV.q.inc(4); } q1.copy(PRIV.q); q1.dec(1); if (q1.cfactor(e)) { continue; } break; } PUB.n = FF.mul(PRIV.p, PRIV.q); PUB.e = e; t.copy(p1); t.shr(); PRIV.dp.set(e); PRIV.dp.invmodp(t); if (PRIV.dp.parity() == 0) { PRIV.dp.add(t); } PRIV.dp.norm(); t.copy(q1); t.shr(); PRIV.dq.set(e); PRIV.dq.invmodp(t); if (PRIV.dq.parity() == 0) { PRIV.dq.add(t); } PRIV.dq.norm(); PRIV.c.copy(PRIV.p); PRIV.c.invmodp(PRIV.q); return; }