/* 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); }
/* U=1/a mod 2^m - Arazi & Qi */ private FF invmod2m() { int i, n = length; FF b = new FF(n); FF c = new FF(n); FF U = new FF(n); FF t; U.zero(); U.v[0].copy(v[0]); U.v[0].invmod2m(); for (i = 1; i < n; i <<= 1) { b.copy(this); b.mod2m(i); t = mul(U, b); t.shrw(i); b.copy(t); c.copy(this); c.shrw(i); c.mod2m(i); c.lmul(U); c.mod2m(i); b.add(c); b.norm(); b.lmul(U); b.mod2m(i); c.one(); c.shlw(i); b.revsub(c); b.norm(); b.shlw(i); U.add(b); } U.norm(); return(U); }
/* Set return=1/this mod p. Binary method - a<p on entry */ public void invmodp(FF p) { int n = p.length; FF u = new FF(n); FF v = new FF(n); FF x1 = new FF(n); FF x2 = new FF(n); FF t = new FF(n); FF one = new FF(n); one.one(); u.copy(this); v.copy(p); x1.copy(one); x2.zero(); // reduce n in here as well! while (comp(u, one) != 0 && comp(v, one) != 0) { while (u.parity() == 0) { u.shr(); if (x1.parity() != 0) { x1.add(p); x1.norm(); } x1.shr(); } while (v.parity() == 0) { v.shr(); if (x2.parity() != 0) { x2.add(p); x2.norm(); } x2.shr(); } if (comp(u, v) >= 0) { u.sub(v); u.norm(); if (comp(x1, x2) >= 0) { x1.sub(x2); } else { t.copy(p); t.sub(x2); x1.add(t); } x1.norm(); } else { v.sub(u); v.norm(); if (comp(x2, x1) >= 0) { x2.sub(x1); } else { t.copy(p); t.sub(x1); x2.add(t); } x2.norm(); } } if (comp(u, one) == 0) { copy(x1); } else { copy(x2); } }