org.bouncycastle.math.raw.Nat128 Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bcprov-ext-debug-jdk18on Show documentation
Show all versions of bcprov-ext-debug-jdk18on Show documentation
The Bouncy Castle Crypto package is a Java implementation of cryptographic algorithms. This jar contains JCE provider and lightweight API for the Bouncy Castle Cryptography APIs for Java 1.8 and later with debug enabled.
The newest version!
package org.bouncycastle.math.raw;
import java.math.BigInteger;
import org.bouncycastle.util.Pack;
public abstract class Nat128
{
private static final long M = 0xFFFFFFFFL;
public static int add(int[] x, int[] y, int[] z)
{
long c = 0;
c += (x[0] & M) + (y[0] & M);
z[0] = (int)c;
c >>>= 32;
c += (x[1] & M) + (y[1] & M);
z[1] = (int)c;
c >>>= 32;
c += (x[2] & M) + (y[2] & M);
z[2] = (int)c;
c >>>= 32;
c += (x[3] & M) + (y[3] & M);
z[3] = (int)c;
c >>>= 32;
return (int)c;
}
public static int addBothTo(int[] x, int[] y, int[] z)
{
long c = 0;
c += (x[0] & M) + (y[0] & M) + (z[0] & M);
z[0] = (int)c;
c >>>= 32;
c += (x[1] & M) + (y[1] & M) + (z[1] & M);
z[1] = (int)c;
c >>>= 32;
c += (x[2] & M) + (y[2] & M) + (z[2] & M);
z[2] = (int)c;
c >>>= 32;
c += (x[3] & M) + (y[3] & M) + (z[3] & M);
z[3] = (int)c;
c >>>= 32;
return (int)c;
}
public static int addTo(int[] x, int[] z)
{
long c = 0;
c += (x[0] & M) + (z[0] & M);
z[0] = (int)c;
c >>>= 32;
c += (x[1] & M) + (z[1] & M);
z[1] = (int)c;
c >>>= 32;
c += (x[2] & M) + (z[2] & M);
z[2] = (int)c;
c >>>= 32;
c += (x[3] & M) + (z[3] & M);
z[3] = (int)c;
c >>>= 32;
return (int)c;
}
public static int addTo(int[] x, int xOff, int[] z, int zOff, int cIn)
{
long c = cIn & M;
c += (x[xOff + 0] & M) + (z[zOff + 0] & M);
z[zOff + 0] = (int)c;
c >>>= 32;
c += (x[xOff + 1] & M) + (z[zOff + 1] & M);
z[zOff + 1] = (int)c;
c >>>= 32;
c += (x[xOff + 2] & M) + (z[zOff + 2] & M);
z[zOff + 2] = (int)c;
c >>>= 32;
c += (x[xOff + 3] & M) + (z[zOff + 3] & M);
z[zOff + 3] = (int)c;
c >>>= 32;
return (int)c;
}
public static int addToEachOther(int[] u, int uOff, int[] v, int vOff)
{
long c = 0;
c += (u[uOff + 0] & M) + (v[vOff + 0] & M);
u[uOff + 0] = (int)c;
v[vOff + 0] = (int)c;
c >>>= 32;
c += (u[uOff + 1] & M) + (v[vOff + 1] & M);
u[uOff + 1] = (int)c;
v[vOff + 1] = (int)c;
c >>>= 32;
c += (u[uOff + 2] & M) + (v[vOff + 2] & M);
u[uOff + 2] = (int)c;
v[vOff + 2] = (int)c;
c >>>= 32;
c += (u[uOff + 3] & M) + (v[vOff + 3] & M);
u[uOff + 3] = (int)c;
v[vOff + 3] = (int)c;
c >>>= 32;
return (int)c;
}
public static void copy(int[] x, int[] z)
{
z[0] = x[0];
z[1] = x[1];
z[2] = x[2];
z[3] = x[3];
}
public static void copy(int[] x, int xOff, int[] z, int zOff)
{
z[zOff + 0] = x[xOff + 0];
z[zOff + 1] = x[xOff + 1];
z[zOff + 2] = x[xOff + 2];
z[zOff + 3] = x[xOff + 3];
}
public static void copy64(long[] x, long[] z)
{
z[0] = x[0];
z[1] = x[1];
}
public static void copy64(long[] x, int xOff, long[] z, int zOff)
{
z[zOff + 0] = x[xOff + 0];
z[zOff + 1] = x[xOff + 1];
}
public static int[] create()
{
return new int[4];
}
public static long[] create64()
{
return new long[2];
}
public static int[] createExt()
{
return new int[8];
}
public static long[] createExt64()
{
return new long[4];
}
public static boolean diff(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
{
boolean pos = gte(x, xOff, y, yOff);
if (pos)
{
sub(x, xOff, y, yOff, z, zOff);
}
else
{
sub(y, yOff, x, xOff, z, zOff);
}
return pos;
}
public static boolean eq(int[] x, int[] y)
{
for (int i = 3; i >= 0; --i)
{
if (x[i] != y[i])
{
return false;
}
}
return true;
}
public static boolean eq64(long[] x, long[] y)
{
for (int i = 1; i >= 0; --i)
{
if (x[i] != y[i])
{
return false;
}
}
return true;
}
public static int[] fromBigInteger(BigInteger x)
{
if (x.signum() < 0 || x.bitLength() > 128)
{
throw new IllegalArgumentException();
}
int[] z = create();
// NOTE: Use a fixed number of loop iterations
for (int i = 0; i < 4; ++i)
{
z[i] = x.intValue();
x = x.shiftRight(32);
}
return z;
}
public static long[] fromBigInteger64(BigInteger x)
{
if (x.signum() < 0 || x.bitLength() > 128)
{
throw new IllegalArgumentException();
}
long[] z = create64();
// NOTE: Use a fixed number of loop iterations
for (int i = 0; i < 2; ++i)
{
z[i] = x.longValue();
x = x.shiftRight(64);
}
return z;
}
public static int getBit(int[] x, int bit)
{
if (bit == 0)
{
return x[0] & 1;
}
int w = bit >> 5;
if (w < 0 || w >= 4)
{
return 0;
}
int b = bit & 31;
return (x[w] >>> b) & 1;
}
public static boolean gte(int[] x, int[] y)
{
for (int i = 3; i >= 0; --i)
{
int x_i = x[i] ^ Integer.MIN_VALUE;
int y_i = y[i] ^ Integer.MIN_VALUE;
if (x_i < y_i)
return false;
if (x_i > y_i)
return true;
}
return true;
}
public static boolean gte(int[] x, int xOff, int[] y, int yOff)
{
for (int i = 3; i >= 0; --i)
{
int x_i = x[xOff + i] ^ Integer.MIN_VALUE;
int y_i = y[yOff + i] ^ Integer.MIN_VALUE;
if (x_i < y_i)
return false;
if (x_i > y_i)
return true;
}
return true;
}
public static boolean isOne(int[] x)
{
if (x[0] != 1)
{
return false;
}
for (int i = 1; i < 4; ++i)
{
if (x[i] != 0)
{
return false;
}
}
return true;
}
public static boolean isOne64(long[] x)
{
if (x[0] != 1L)
{
return false;
}
for (int i = 1; i < 2; ++i)
{
if (x[i] != 0L)
{
return false;
}
}
return true;
}
public static boolean isZero(int[] x)
{
for (int i = 0; i < 4; ++i)
{
if (x[i] != 0)
{
return false;
}
}
return true;
}
public static boolean isZero64(long[] x)
{
for (int i = 0; i < 2; ++i)
{
if (x[i] != 0L)
{
return false;
}
}
return true;
}
public static void mul(int[] x, int[] y, int[] zz)
{
long y_0 = y[0] & M;
long y_1 = y[1] & M;
long y_2 = y[2] & M;
long y_3 = y[3] & M;
{
long c = 0, x_0 = x[0] & M;
c += x_0 * y_0;
zz[0] = (int)c;
c >>>= 32;
c += x_0 * y_1;
zz[1] = (int)c;
c >>>= 32;
c += x_0 * y_2;
zz[2] = (int)c;
c >>>= 32;
c += x_0 * y_3;
zz[3] = (int)c;
c >>>= 32;
zz[4] = (int)c;
}
for (int i = 1; i < 4; ++i)
{
long c = 0, x_i = x[i] & M;
c += x_i * y_0 + (zz[i + 0] & M);
zz[i + 0] = (int)c;
c >>>= 32;
c += x_i * y_1 + (zz[i + 1] & M);
zz[i + 1] = (int)c;
c >>>= 32;
c += x_i * y_2 + (zz[i + 2] & M);
zz[i + 2] = (int)c;
c >>>= 32;
c += x_i * y_3 + (zz[i + 3] & M);
zz[i + 3] = (int)c;
c >>>= 32;
zz[i + 4] = (int)c;
}
}
public static void mul(int[] x, int xOff, int[] y, int yOff, int[] zz, int zzOff)
{
long y_0 = y[yOff + 0] & M;
long y_1 = y[yOff + 1] & M;
long y_2 = y[yOff + 2] & M;
long y_3 = y[yOff + 3] & M;
{
long c = 0, x_0 = x[xOff + 0] & M;
c += x_0 * y_0;
zz[zzOff + 0] = (int)c;
c >>>= 32;
c += x_0 * y_1;
zz[zzOff + 1] = (int)c;
c >>>= 32;
c += x_0 * y_2;
zz[zzOff + 2] = (int)c;
c >>>= 32;
c += x_0 * y_3;
zz[zzOff + 3] = (int)c;
c >>>= 32;
zz[zzOff + 4] = (int)c;
}
for (int i = 1; i < 4; ++i)
{
++zzOff;
long c = 0, x_i = x[xOff + i] & M;
c += x_i * y_0 + (zz[zzOff + 0] & M);
zz[zzOff + 0] = (int)c;
c >>>= 32;
c += x_i * y_1 + (zz[zzOff + 1] & M);
zz[zzOff + 1] = (int)c;
c >>>= 32;
c += x_i * y_2 + (zz[zzOff + 2] & M);
zz[zzOff + 2] = (int)c;
c >>>= 32;
c += x_i * y_3 + (zz[zzOff + 3] & M);
zz[zzOff + 3] = (int)c;
c >>>= 32;
zz[zzOff + 4] = (int)c;
}
}
public static int mulAddTo(int[] x, int[] y, int[] zz)
{
long y_0 = y[0] & M;
long y_1 = y[1] & M;
long y_2 = y[2] & M;
long y_3 = y[3] & M;
long zc = 0;
for (int i = 0; i < 4; ++i)
{
long c = 0, x_i = x[i] & M;
c += x_i * y_0 + (zz[i + 0] & M);
zz[i + 0] = (int)c;
c >>>= 32;
c += x_i * y_1 + (zz[i + 1] & M);
zz[i + 1] = (int)c;
c >>>= 32;
c += x_i * y_2 + (zz[i + 2] & M);
zz[i + 2] = (int)c;
c >>>= 32;
c += x_i * y_3 + (zz[i + 3] & M);
zz[i + 3] = (int)c;
c >>>= 32;
zc += c + (zz[i + 4] & M);
zz[i + 4] = (int)zc;
zc >>>= 32;
}
return (int)zc;
}
public static int mulAddTo(int[] x, int xOff, int[] y, int yOff, int[] zz, int zzOff)
{
long y_0 = y[yOff + 0] & M;
long y_1 = y[yOff + 1] & M;
long y_2 = y[yOff + 2] & M;
long y_3 = y[yOff + 3] & M;
long zc = 0;
for (int i = 0; i < 4; ++i)
{
long c = 0, x_i = x[xOff + i] & M;
c += x_i * y_0 + (zz[zzOff + 0] & M);
zz[zzOff + 0] = (int)c;
c >>>= 32;
c += x_i * y_1 + (zz[zzOff + 1] & M);
zz[zzOff + 1] = (int)c;
c >>>= 32;
c += x_i * y_2 + (zz[zzOff + 2] & M);
zz[zzOff + 2] = (int)c;
c >>>= 32;
c += x_i * y_3 + (zz[zzOff + 3] & M);
zz[zzOff + 3] = (int)c;
c >>>= 32;
zc += c + (zz[zzOff + 4] & M);
zz[zzOff + 4] = (int)zc;
zc >>>= 32;
++zzOff;
}
return (int)zc;
}
public static long mul33Add(int w, int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
{
// assert w >>> 31 == 0;
long c = 0, wVal = w & M;
long x0 = x[xOff + 0] & M;
c += wVal * x0 + (y[yOff + 0] & M);
z[zOff + 0] = (int)c;
c >>>= 32;
long x1 = x[xOff + 1] & M;
c += wVal * x1 + x0 + (y[yOff + 1] & M);
z[zOff + 1] = (int)c;
c >>>= 32;
long x2 = x[xOff + 2] & M;
c += wVal * x2 + x1 + (y[yOff + 2] & M);
z[zOff + 2] = (int)c;
c >>>= 32;
long x3 = x[xOff + 3] & M;
c += wVal * x3 + x2 + (y[yOff + 3] & M);
z[zOff + 3] = (int)c;
c >>>= 32;
c += x3;
return c;
}
public static int mulWordAddExt(int x, int[] yy, int yyOff, int[] zz, int zzOff)
{
// assert yyOff <= 4;
// assert zzOff <= 4;
long c = 0, xVal = x & M;
c += xVal * (yy[yyOff + 0] & M) + (zz[zzOff + 0] & M);
zz[zzOff + 0] = (int)c;
c >>>= 32;
c += xVal * (yy[yyOff + 1] & M) + (zz[zzOff + 1] & M);
zz[zzOff + 1] = (int)c;
c >>>= 32;
c += xVal * (yy[yyOff + 2] & M) + (zz[zzOff + 2] & M);
zz[zzOff + 2] = (int)c;
c >>>= 32;
c += xVal * (yy[yyOff + 3] & M) + (zz[zzOff + 3] & M);
zz[zzOff + 3] = (int)c;
c >>>= 32;
return (int)c;
}
public static int mul33DWordAdd(int x, long y, int[] z, int zOff)
{
// assert x >>> 31 == 0;
// assert zOff <= 0;
long c = 0, xVal = x & M;
long y00 = y & M;
c += xVal * y00 + (z[zOff + 0] & M);
z[zOff + 0] = (int)c;
c >>>= 32;
long y01 = y >>> 32;
c += xVal * y01 + y00 + (z[zOff + 1] & M);
z[zOff + 1] = (int)c;
c >>>= 32;
c += y01 + (z[zOff + 2] & M);
z[zOff + 2] = (int)c;
c >>>= 32;
c += (z[zOff + 3] & M);
z[zOff + 3] = (int)c;
c >>>= 32;
return (int)c;
}
public static int mul33WordAdd(int x, int y, int[] z, int zOff)
{
// assert x >>> 31 == 0;
// assert zOff <= 1;
long c = 0, xVal = x & M, yVal = y & M;
c += yVal * xVal + (z[zOff + 0] & M);
z[zOff + 0] = (int)c;
c >>>= 32;
c += yVal + (z[zOff + 1] & M);
z[zOff + 1] = (int)c;
c >>>= 32;
c += (z[zOff + 2] & M);
z[zOff + 2] = (int)c;
c >>>= 32;
return c == 0 ? 0 : Nat.incAt(4, z, zOff, 3);
}
public static int mulWordDwordAdd(int x, long y, int[] z, int zOff)
{
// assert zOff <= 1;
long c = 0, xVal = x & M;
c += xVal * (y & M) + (z[zOff + 0] & M);
z[zOff + 0] = (int)c;
c >>>= 32;
c += xVal * (y >>> 32) + (z[zOff + 1] & M);
z[zOff + 1] = (int)c;
c >>>= 32;
c += (z[zOff + 2] & M);
z[zOff + 2] = (int)c;
c >>>= 32;
return c == 0 ? 0 : Nat.incAt(4, z, zOff, 3);
}
public static int mulWordsAdd(int x, int y, int[] z, int zOff)
{
// assert zOff <= 2;
long c = 0, xVal = x & M, yVal = y & M;
c += yVal * xVal + (z[zOff + 0] & M);
z[zOff + 0] = (int)c;
c >>>= 32;
c += (z[zOff + 1] & M);
z[zOff + 1] = (int)c;
c >>>= 32;
return c == 0 ? 0 : Nat.incAt(4, z, zOff, 2);
}
public static int mulWord(int x, int[] y, int[] z, int zOff)
{
long c = 0, xVal = x & M;
int i = 0;
do
{
c += xVal * (y[i] & M);
z[zOff + i] = (int)c;
c >>>= 32;
}
while (++i < 4);
return (int)c;
}
public static void square(int[] x, int[] zz)
{
long x_0 = x[0] & M;
long zz_1;
int c = 0, w;
{
int i = 3, j = 8;
do
{
long xVal = (x[i--] & M);
long p = xVal * xVal;
zz[--j] = (c << 31) | (int)(p >>> 33);
zz[--j] = (int)(p >>> 1);
c = (int)p;
}
while (i > 0);
{
long p = x_0 * x_0;
zz_1 = ((c << 31) & M) | (p >>> 33);
zz[0] = (int)p;
c = (int)(p >>> 32) & 1;
}
}
long x_1 = x[1] & M;
long zz_2 = zz[2] & M;
{
zz_1 += x_1 * x_0;
w = (int)zz_1;
zz[1] = (w << 1) | c;
c = w >>> 31;
zz_2 += zz_1 >>> 32;
}
long x_2 = x[2] & M;
long zz_3 = zz[3] & M;
long zz_4 = zz[4] & M;
{
zz_2 += x_2 * x_0;
w = (int)zz_2;
zz[2] = (w << 1) | c;
c = w >>> 31;
zz_3 += (zz_2 >>> 32) + x_2 * x_1;
zz_4 += zz_3 >>> 32;
zz_3 &= M;
}
long x_3 = x[3] & M;
long zz_5 = (zz[5] & M) + (zz_4 >>> 32); zz_4 &= M;
long zz_6 = (zz[6] & M) + (zz_5 >>> 32); zz_5 &= M;
{
zz_3 += x_3 * x_0;
w = (int)zz_3;
zz[3] = (w << 1) | c;
c = w >>> 31;
zz_4 += (zz_3 >>> 32) + x_3 * x_1;
zz_5 += (zz_4 >>> 32) + x_3 * x_2;
zz_6 += zz_5 >>> 32;
zz_5 &= M;
}
w = (int)zz_4;
zz[4] = (w << 1) | c;
c = w >>> 31;
w = (int)zz_5;
zz[5] = (w << 1) | c;
c = w >>> 31;
w = (int)zz_6;
zz[6] = (w << 1) | c;
c = w >>> 31;
w = zz[7] + (int)(zz_6 >>> 32);
zz[7] = (w << 1) | c;
}
public static void square(int[] x, int xOff, int[] zz, int zzOff)
{
long x_0 = x[xOff + 0] & M;
long zz_1;
int c = 0, w;
{
int i = 3, j = 8;
do
{
long xVal = (x[xOff + i--] & M);
long p = xVal * xVal;
zz[zzOff + --j] = (c << 31) | (int)(p >>> 33);
zz[zzOff + --j] = (int)(p >>> 1);
c = (int)p;
}
while (i > 0);
{
long p = x_0 * x_0;
zz_1 = ((c << 31) & M) | (p >>> 33);
zz[zzOff + 0] = (int)p;
c = (int)(p >>> 32) & 1;
}
}
long x_1 = x[xOff + 1] & M;
long zz_2 = zz[zzOff + 2] & M;
{
zz_1 += x_1 * x_0;
w = (int)zz_1;
zz[zzOff + 1] = (w << 1) | c;
c = w >>> 31;
zz_2 += zz_1 >>> 32;
}
long x_2 = x[xOff + 2] & M;
long zz_3 = zz[zzOff + 3] & M;
long zz_4 = zz[zzOff + 4] & M;
{
zz_2 += x_2 * x_0;
w = (int)zz_2;
zz[zzOff + 2] = (w << 1) | c;
c = w >>> 31;
zz_3 += (zz_2 >>> 32) + x_2 * x_1;
zz_4 += zz_3 >>> 32;
zz_3 &= M;
}
long x_3 = x[xOff + 3] & M;
long zz_5 = (zz[zzOff + 5] & M) + (zz_4 >>> 32); zz_4 &= M;
long zz_6 = (zz[zzOff + 6] & M) + (zz_5 >>> 32); zz_5 &= M;
{
zz_3 += x_3 * x_0;
w = (int)zz_3;
zz[zzOff + 3] = (w << 1) | c;
c = w >>> 31;
zz_4 += (zz_3 >>> 32) + x_3 * x_1;
zz_5 += (zz_4 >>> 32) + x_3 * x_2;
zz_6 += zz_5 >>> 32;
}
w = (int)zz_4;
zz[zzOff + 4] = (w << 1) | c;
c = w >>> 31;
w = (int)zz_5;
zz[zzOff + 5] = (w << 1) | c;
c = w >>> 31;
w = (int)zz_6;
zz[zzOff + 6] = (w << 1) | c;
c = w >>> 31;
w = zz[zzOff + 7] + (int)(zz_6 >>> 32);
zz[zzOff + 7] = (w << 1) | c;
}
public static int sub(int[] x, int[] y, int[] z)
{
long c = 0;
c += (x[0] & M) - (y[0] & M);
z[0] = (int)c;
c >>= 32;
c += (x[1] & M) - (y[1] & M);
z[1] = (int)c;
c >>= 32;
c += (x[2] & M) - (y[2] & M);
z[2] = (int)c;
c >>= 32;
c += (x[3] & M) - (y[3] & M);
z[3] = (int)c;
c >>= 32;
return (int)c;
}
public static int sub(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
{
long c = 0;
c += (x[xOff + 0] & M) - (y[yOff + 0] & M);
z[zOff + 0] = (int)c;
c >>= 32;
c += (x[xOff + 1] & M) - (y[yOff + 1] & M);
z[zOff + 1] = (int)c;
c >>= 32;
c += (x[xOff + 2] & M) - (y[yOff + 2] & M);
z[zOff + 2] = (int)c;
c >>= 32;
c += (x[xOff + 3] & M) - (y[yOff + 3] & M);
z[zOff + 3] = (int)c;
c >>= 32;
return (int)c;
}
public static int subBothFrom(int[] x, int[] y, int[] z)
{
long c = 0;
c += (z[0] & M) - (x[0] & M) - (y[0] & M);
z[0] = (int)c;
c >>= 32;
c += (z[1] & M) - (x[1] & M) - (y[1] & M);
z[1] = (int)c;
c >>= 32;
c += (z[2] & M) - (x[2] & M) - (y[2] & M);
z[2] = (int)c;
c >>= 32;
c += (z[3] & M) - (x[3] & M) - (y[3] & M);
z[3] = (int)c;
c >>= 32;
return (int)c;
}
public static int subFrom(int[] x, int[] z)
{
long c = 0;
c += (z[0] & M) - (x[0] & M);
z[0] = (int)c;
c >>= 32;
c += (z[1] & M) - (x[1] & M);
z[1] = (int)c;
c >>= 32;
c += (z[2] & M) - (x[2] & M);
z[2] = (int)c;
c >>= 32;
c += (z[3] & M) - (x[3] & M);
z[3] = (int)c;
c >>= 32;
return (int)c;
}
public static int subFrom(int[] x, int xOff, int[] z, int zOff)
{
long c = 0;
c += (z[zOff + 0] & M) - (x[xOff + 0] & M);
z[zOff + 0] = (int)c;
c >>= 32;
c += (z[zOff + 1] & M) - (x[xOff + 1] & M);
z[zOff + 1] = (int)c;
c >>= 32;
c += (z[zOff + 2] & M) - (x[xOff + 2] & M);
z[zOff + 2] = (int)c;
c >>= 32;
c += (z[zOff + 3] & M) - (x[xOff + 3] & M);
z[zOff + 3] = (int)c;
c >>= 32;
return (int)c;
}
public static BigInteger toBigInteger(int[] x)
{
byte[] bs = new byte[16];
for (int i = 0; i < 4; ++i)
{
int x_i = x[i];
if (x_i != 0)
{
Pack.intToBigEndian(x_i, bs, (3 - i) << 2);
}
}
return new BigInteger(1, bs);
}
public static BigInteger toBigInteger64(long[] x)
{
byte[] bs = new byte[16];
for (int i = 0; i < 2; ++i)
{
long x_i = x[i];
if (x_i != 0L)
{
Pack.longToBigEndian(x_i, bs, (1 - i) << 3);
}
}
return new BigInteger(1, bs);
}
public static void zero(int[] z)
{
z[0] = 0;
z[1] = 0;
z[2] = 0;
z[3] = 0;
}
}