utils.com.unbound.common.Math Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of unbound-java-provider Show documentation
Show all versions of unbound-java-provider Show documentation
This is a collection of JAVA libraries that implement Unbound cryptographic classes for JAVA provider, PKCS11 wrapper, cryptoki, and advapi
package com.unbound.common;
import java.math.BigInteger;
public class Math
{
public static final BigInteger ZERO = BigInteger.valueOf(0);
public static final BigInteger ONE = BigInteger.valueOf(1);
public static final BigInteger TWO = BigInteger.valueOf(2);
public static final BigInteger FOUR = BigInteger.valueOf(4);
private static final int[] jacobiTable = {0, 1, 0, -1, 0, -1, 0, 1};
public static int jacobi(BigInteger A, BigInteger B)
{
BigInteger a, b, v;
long k = 1;
// test trivial cases
if (B.equals(ZERO))
{
a = A.abs();
return a.equals(ONE) ? 1 : 0;
}
if (!A.testBit(0) && !B.testBit(0))
{
return 0;
}
a = A;
b = B;
if (b.signum() == -1)
{ // b < 0
b = b.negate(); // b = -b
if (a.signum() == -1)
{
k = -1;
}
}
v = ZERO;
while (!b.testBit(0))
{
v = v.add(ONE); // v = v + 1
b = b.divide(TWO); // b = b/2
}
if (v.testBit(0))
{
k = k * jacobiTable[a.intValue() & 7];
}
if (a.signum() < 0)
{ // a < 0
if (b.testBit(1))
{
k = -k; // k = -k
}
a = a.negate(); // a = -a
}
// main loop
while (a.signum() != 0)
{
v = ZERO;
while (!a.testBit(0))
{ // a is even
v = v.add(ONE);
a = a.divide(TWO);
}
if (v.testBit(0))
{
k = k * jacobiTable[b.intValue() & 7];
}
if (a.compareTo(b) < 0)
{ // a < b
// swap and correct intermediate result
BigInteger x = a;
a = b;
b = x;
if (a.testBit(1) && b.testBit(1))
{
k = -k;
}
}
a = a.subtract(b);
}
return b.equals(ONE) ? (int) k : 0;
}
public static BigInteger sqrtP(BigInteger a, BigInteger p)
throws IllegalArgumentException
{
BigInteger v = null;
if (a.compareTo(ZERO) < 0)
{
a = a.add(p);
}
if (a.equals(ZERO))
{
return ZERO;
}
if (p.equals(TWO))
{
return a;
}
// p = 3 mod 4
if (p.testBit(0) && p.testBit(1))
{
if (jacobi(a, p) == 1)
{ // a quadr. residue mod p
v = p.add(ONE); // v = p+1
v = v.shiftRight(2); // v = v/4
return a.modPow(v, p); // return a^v mod p
// return --> a^((p+1)/4) mod p
}
throw new IllegalArgumentException("No quadratic residue: " + a + ", " + p);
}
long t = 0;
// initialization
// compute k and s, where p = 2^s (2k+1) +1
BigInteger k = p.subtract(ONE); // k = p-1
long s = 0;
while (!k.testBit(0))
{ // while k is even
s++; // s = s+1
k = k.shiftRight(1); // k = k/2
}
k = k.subtract(ONE); // k = k - 1
k = k.shiftRight(1); // k = k/2
// initial values
BigInteger r = a.modPow(k, p); // r = a^k mod p
BigInteger n = r.multiply(r).remainder(p); // n = r^2 % p
n = n.multiply(a).remainder(p); // n = n * a % p
r = r.multiply(a).remainder(p); // r = r * a %p
if (n.equals(ONE))
{
return r;
}
// non-quadratic residue
BigInteger z = TWO; // z = 2
while (jacobi(z, p) == 1)
{
// while z quadratic residue
z = z.add(ONE); // z = z + 1
}
v = k;
v = v.multiply(TWO); // v = 2k
v = v.add(ONE); // v = 2k + 1
BigInteger c = z.modPow(v, p); // c = z^v mod p
// iteration
while (n.compareTo(ONE) > 0)
{ // n > 1
k = n; // k = n
t = s; // t = s
s = 0;
while (!k.equals(ONE))
{ // k != 1
k = k.multiply(k).mod(p); // k = k^2 % p
s++; // s = s + 1
}
t -= s; // t = t - s
if (t == 0)
{
throw new IllegalArgumentException("No quadratic residue: " + a + ", " + p);
}
v = ONE;
for (long i = 0; i < t - 1; i++)
{
v = v.shiftLeft(1); // v = 1 * 2^(t - 1)
}
c = c.modPow(v, p); // c = c^v mod p
r = r.multiply(c).remainder(p); // r = r * c % p
c = c.multiply(c).remainder(p); // c = c^2 % p
n = n.multiply(c).mod(p); // n = n * c % p
}
return r;
}
public static BigInteger subP(BigInteger a, BigInteger b, BigInteger p)
{
if (a.compareTo(b)>=0) return a.subtract(b);
return a.add(p).subtract(b);
}
public static BigInteger divP(BigInteger a, BigInteger b, BigInteger p)
{
return a.multiply(b.modInverse(p)).mod(p);
}
public static BigInteger factorial(int n)
{
BigInteger ret = BigInteger.ONE;
for (int i = 2; i <= n; i++) ret = ret.multiply(BigInteger.valueOf(i));
return ret;
}
public static BigInteger lcm(BigInteger s, BigInteger s1)
{
// calculate multiplication of two bigintegers
BigInteger mul = s.multiply(s1);
// calculate gcd of two bigintegers
BigInteger gcd = s.gcd(s1);
// calculate lcm using formula: lcm * gcd = x * y
BigInteger lcm = mul.divide(gcd);
return lcm;
}
public static BigInteger[] egcd(BigInteger a, BigInteger b)
/* A nonrecursive version of GCD. It returns an array answer of 3 BigIntegers
answer[0] is the gcd, answer[1] is the coefficient of a,
answer[2] the coeff of b
*/
{
BigInteger[] answer=new BigInteger[3];
//Set up all the initial table entries
BigInteger r0 = a;
BigInteger r1 = b;
BigInteger s0 = ONE;
BigInteger s1 = ZERO;
BigInteger t0 = ZERO;
BigInteger t1 = ONE;
BigInteger q1 = r0.divide(r1);
BigInteger r2 = r0.mod(r1);
BigInteger s2,t2;
// When r2 becomes zero, the previous table entries are the answers
while (r2.compareTo(ZERO) > 0) {
s2 = s0.subtract(q1.multiply(s1));
s0 = s1;
s1 = s2;
t2 = t0.subtract(q1.multiply(t1));
t0 = t1;
t1 = t2;
r0 = r1;
r1 = r2;
q1 = r0.divide(r1);
r2 = r0.mod(r1);
}
answer[0]=r1;
answer[1]=s1;
answer[2]=t1;
return answer;
} // end of egcd()
}