java-ec.com.unbound.common.crypto.ec.SecP256K1 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.crypto.ec;
import com.unbound.common.crypto.ec.math.UInt256;
public final class SecP256K1 extends Curve
{
private static final long LM = 0xffffffffL;
private static long U64(int x) { return x & 0xffffffffL; }
private static long LO(long x) { return x & 0xffffffffL; }
private static long HI(long x) { return x >>> 32; }
private static final long P0 = 0xfffffc2fL;
private static final long P1 = 0xfffffffeL;
private static final long P2 = 0xffffffffL;
private static final long P3 = 0xffffffffL;
private static final long P4 = 0xffffffffL;
private static final long P5 = 0xffffffffL;
private static final long P6 = 0xffffffffL;
private static final long P7 = 0xffffffffL;
private static final int[] P = {(int)P0, (int)P1, (int)P2, (int)P3, (int)P4, (int)P5, (int)P6, (int)P7};
private static final int[] MONT_ONE = {0x000003d1, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000};
private static final int[] MONT_RR = {0x000e90a1, 0x000007a2, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000};
private static final int[] B = {0x00000007, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000};
private static final int[] Gx = {0x16f81798, 0x59f2815b, 0x2dce28d9, 0x029bfcdb, 0xce870b07, 0x55a06295, 0xf9dcbbac, 0x79be667e};
private static final int[] Gy = {0xfb10d4b8, 0x9c47d08f, 0xa6855419, 0xfd17b448, 0x0e1108a8, 0x5da4fbfc, 0x26a3c465, 0x483ada77};
private static final int[] q = {0xd0364141, 0xbfd25e8c, 0xaf48a03b, 0xbaaedce6, 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff};
private static long invp = 0xd2253531;
private SecP256K1()
{
super(256, P, (int)invp, MONT_ONE, MONT_RR, 0, B, Gx, Gy, q);
}
private static SecP256K1 instance = null;
private static Point infinityInstance = null;
static SecP256K1 getInstance()
{
if (instance==null) instance = new SecP256K1();
return instance;
}
@Override
public Point infinity()
{
if (infinityInstance==null) infinityInstance = new Point(getInstance());
return infinityInstance;
}
@Override
protected int[] alloc() { return new int[8]; }
@Override
protected int addP(int[] r, int[] x)
{
long c = 0;
c += (x[0] & 0xffffffffL) + P0; r[0] = (int)c; c >>>= 32;
c += (x[1] & 0xffffffffL) + P1; r[1] = (int)c; c >>>= 32;
c += (x[2] & 0xffffffffL) + P2; r[2] = (int)c; c >>>= 32;
c += (x[3] & 0xffffffffL) + P3; r[3] = (int)c; c >>>= 32;
c += (x[4] & 0xffffffffL) + P4; r[4] = (int)c; c >>>= 32;
c += (x[5] & 0xffffffffL) + P5; r[5] = (int)c; c >>>= 32;
c += (x[6] & 0xffffffffL) + P6; r[6] = (int)c; c >>>= 32;
c += (x[7] & 0xffffffffL) + P7; r[7] = (int)c; c >>>= 32;
return (int)c;
}
@Override
protected int subP(int[] r, int[] x)
{
long c = 0;
c += (x[0] & 0xffffffffL) - P0; r[0] = (int)c; c >>= 32;
c += (x[1] & 0xffffffffL) - P1; r[1] = (int)c; c >>= 32;
c += (x[2] & 0xffffffffL) - P2; r[2] = (int)c; c >>= 32;
c += (x[3] & 0xffffffffL) - P3; r[3] = (int)c; c >>= 32;
c += (x[4] & 0xffffffffL) - P4; r[4] = (int)c; c >>= 32;
c += (x[5] & 0xffffffffL) - P5; r[5] = (int)c; c >>= 32;
c += (x[6] & 0xffffffffL) - P6; r[6] = (int)c; c >>= 32;
c += (x[7] & 0xffffffffL) - P7; r[7] = (int)c; c >>= 32;
return (int)c;
}
@Override
protected void add(int[] r, int[] x, int[] y, IntPool pool)
{
//int[] temp = IntPool.alloc(pool, IntPool.BASE+0);//alloc();
//int carry = UInt256.add(temp, x, y);
int t0, t1, t2, t3, t4, t5, t6, t7;
int r0, r1, r2, r3, r4, r5, r6, r7;
long c, b;
c = (x[0] & 0xffffffffL) +(y[0] & 0xffffffffL); t0 = (int)c; c >>>= 32; b = (t0 & 0xffffffffL) - 0xfffffc2fL; r0 = (int)b; b >>= 32;
c += (x[1] & 0xffffffffL) +(y[1] & 0xffffffffL); t1 = (int)c; c >>>= 32; b += (t1 & 0xffffffffL) - 0xfffffffeL; r1 = (int)b; b >>= 32;
c += (x[2] & 0xffffffffL) +(y[2] & 0xffffffffL); t2 = (int)c; c >>>= 32; b += (t2 & 0xffffffffL) - 0xffffffffL; r2 = (int)b; b >>= 32;
c += (x[3] & 0xffffffffL) +(y[3] & 0xffffffffL); t3 = (int)c; c >>>= 32; b += (t3 & 0xffffffffL) - 0xffffffffL; r3 = (int)b; b >>= 32;
c += (x[4] & 0xffffffffL) +(y[4] & 0xffffffffL); t4 = (int)c; c >>>= 32; b += (t4 & 0xffffffffL) - 0xffffffffL; r4 = (int)b; b >>= 32;
c += (x[5] & 0xffffffffL) +(y[5] & 0xffffffffL); t5 = (int)c; c >>>= 32; b += (t5 & 0xffffffffL) - 0xffffffffL; r5 = (int)b; b >>= 32;
c += (x[6] & 0xffffffffL) +(y[6] & 0xffffffffL); t6 = (int)c; c >>>= 32; b += (t6 & 0xffffffffL) - 0xffffffffL; r6 = (int)b; b >>= 32;
c += (x[7] & 0xffffffffL) +(y[7] & 0xffffffffL); t7 = (int)c; c >>>= 32; b += (t7 & 0xffffffffL) - 0xffffffffL; r7 = (int)b; b >>= 32;
int carry = (int)c;
int borrow = (int)b;// & 1;
//int borrow = subP(r, temp);
//cmov(r, ~carry & borrow, temp);
int cond = ~carry & borrow;
cond = -(cond & 1);
r[0] = ((r0 ^ t0) & cond) ^ r0;
r[1] = ((r1 ^ t1) & cond) ^ r1;
r[2] = ((r2 ^ t2) & cond) ^ r2;
r[3] = ((r3 ^ t3) & cond) ^ r3;
r[4] = ((r4 ^ t4) & cond) ^ r4;
r[5] = ((r5 ^ t5) & cond) ^ r5;
r[6] = ((r6 ^ t6) & cond) ^ r6;
r[7] = ((r7 ^ t7) & cond) ^ r7;
}
@Override
protected void sub(int[] r, int[] x, int[] y, IntPool pool)
{
//int[] temp = IntPool.alloc(pool, IntPool.BASE+1);//alloc();
int t0, t1, t2, t3, t4, t5, t6, t7;
int r0, r1, r2, r3, r4, r5, r6, r7;
//int borrow = UInt256.sub(temp, x, y);
long c, b;
b = (x[0] & 0xffffffffL) - (y[0] & 0xffffffffL); t0 = (int)b; b >>= 32; c = (t0 & 0xffffffffL) + 0xfffffc2fL; r0 = (int)c; c >>>= 32;
b += (x[1] & 0xffffffffL) - (y[1] & 0xffffffffL); t1 = (int)b; b >>= 32; c += (t1 & 0xffffffffL) + 0xfffffffeL; r1 = (int)c; c >>>= 32;
b += (x[2] & 0xffffffffL) - (y[2] & 0xffffffffL); t2 = (int)b; b >>= 32; c += (t2 & 0xffffffffL) + 0xffffffffL; r2 = (int)c; c >>>= 32;
b += (x[3] & 0xffffffffL) - (y[3] & 0xffffffffL); t3 = (int)b; b >>= 32; c += (t3 & 0xffffffffL) + 0xffffffffL; r3 = (int)c; c >>>= 32;
b += (x[4] & 0xffffffffL) - (y[4] & 0xffffffffL); t4 = (int)b; b >>= 32; c += (t4 & 0xffffffffL) + 0xffffffffL; r4 = (int)c; c >>>= 32;
b += (x[5] & 0xffffffffL) - (y[5] & 0xffffffffL); t5 = (int)b; b >>= 32; c += (t5 & 0xffffffffL) + 0xffffffffL; r5 = (int)c; c >>>= 32;
b += (x[6] & 0xffffffffL) - (y[6] & 0xffffffffL); t6 = (int)b; b >>= 32; c += (t6 & 0xffffffffL) + 0xffffffffL; r6 = (int)c; c >>>= 32;
b += (x[7] & 0xffffffffL) - (y[7] & 0xffffffffL); t7 = (int)b; b >>= 32; c += (t7 & 0xffffffffL) + 0xffffffffL; r7 = (int)c;
int borrow = (int)b & 1;
//addP(r, temp);
//cmov(r, ~borrow, temp);
//int cond = ~borrow;
//cond = -(cond & 1);
int cond = borrow-1;
r[0] = ((r0 ^ t0) & cond) ^ r0;
r[1] = ((r1 ^ t1) & cond) ^ r1;
r[2] = ((r2 ^ t2) & cond) ^ r2;
r[3] = ((r3 ^ t3) & cond) ^ r3;
r[4] = ((r4 ^ t4) & cond) ^ r4;
r[5] = ((r5 ^ t5) & cond) ^ r5;
r[6] = ((r6 ^ t6) & cond) ^ r6;
r[7] = ((r7 ^ t7) & cond) ^ r7;
}
static long mul_0xffffffff(long a)
{
//return a * 0xffffffffL;
long c = -a;
return (c & 0xffffffffL) | ((a + (c>>32)) << 32);
}
@Override
protected void mul(int[] r, int a[], int b[], IntPool pool)
{
//UInt.montMul(r, a, b, p, (int)invp, IntPool.alloc(pool, IntPool.BASE+2), IntPool.alloc(pool, IntPool.BASE+3));
//return;
int[] rr = IntPool.alloc(pool, IntPool.BASE+2); // setZero
long rs = 0;
long b_0 = b[0] & 0xffffffffL;
long x, x2, xHi;
{
long ai = a[0] & 0xffffffffL;
long A = b_0 * ai;
long m = ((A & 0xffffffffL) * invp) & 0xffffffffL;
long B = ((m * 0xfffffc2fL) + (A & 0xffffffffL)) >>> 32; // p0
A >>>= 32;
//long m_mul_minus_one = -m;
//m_mul_minus_one = (m_mul_minus_one & 0xffffffffL) | ((m + (m_mul_minus_one>>32)) << 32);
{
x = ai * (b[1] & 0xffffffffL);
xHi = x >>> 32;
x = A + (x & 0xffffffffL);
A = xHi + (x >>> 32);
x2 = m * 0xfffffffeL;//(p[1] & 0xffffffffL);
x = (x & 0xffffffffL) + (x2 & 0xffffffffL);
xHi = (x >>> 32) + (x2 >>> 32);
x = B + (x & 0xffffffffL);
B = xHi + (x >>> 32);
rr[0] = (int)x;
}
long mxLo = -m;
long mxHi = (m + (mxLo>>32)) & 0xffffffffL;
mxLo &= 0xffffffffL;
for (int index=2; index<8; index++)
{
x = ai * (b[index] & 0xffffffffL);
xHi = x >>> 32;
x = A + (x & 0xffffffffL);
A = xHi + (x >>> 32);
//x2 = m * (p[index] & 0xffffffffL);
x = (x & 0xffffffffL) + mxLo;
xHi = (x >>> 32) + mxHi;
x = B + (x & 0xffffffffL);
B = xHi + (x >>> 32);
rr[index-1] = (int)x;
}
A += rs;
B += A & 0xffffffffL;
rs = (A >>> 32) + (B >>> 32);
rr[7] = (int)B;
}
for (int i=1; i<8; i++)
{
long ai = a[i] & 0xffffffffL;
long A = b_0 * ai + (rr[0] & 0xffffffffL);
long m = ((A & 0xffffffffL) * invp) & 0xffffffffL;
long B = ((m * 0xfffffc2fL) + (A & 0xffffffffL)) >>> 32; // p0
A >>>= 32;
// for (int index=1; index>> 32;
x = (x & 0xffffffffL) + (rr[1] & 0xffffffffL);
xHi = xHi + (x >>> 32);
x = A + (x & 0xffffffffL);
A = (xHi + (x >>> 32));
x2 = m * 0xfffffffeL;//(p[1] & 0xffffffffL);
x = (x & 0xffffffffL) + (x2 & 0xffffffffL);
xHi = (x >>> 32) + (x2 >>> 32);
x = B + (x & 0xffffffffL);
B = xHi + (x >>> 32);
rr[0] = (int)x;
}
long mxLo = -m;
long mxHi = (m + (mxLo>>32)) & 0xffffffffL;
mxLo &= 0xffffffffL;
for (int index=2; index<8; index++)
{
x = ai * (b[index] & 0xffffffffL);
xHi = x >>> 32;
x = (x & 0xffffffffL) + (rr[index] & 0xffffffffL);
xHi = xHi + (x >>> 32);
x = A + (x & 0xffffffffL);
A = (xHi + (x >>> 32));
//x2 = m * (p[i] & 0xffffffffL);
x = (x & 0xffffffffL) + mxLo;
xHi = (x >>> 32) + mxHi;
x = B + (x & 0xffffffffL);
B = xHi + (x >>> 32);
rr[index-1] = (int)x;
}
A += rs;
B += A & 0xffffffffL;
rs = (A >>> 32) + (B >>> 32);
rr[7] = (int)B;
}
int cond = (int)rs;
int[] r_minus_p = IntPool.alloc(pool, IntPool.BASE+3);
int borrow = UInt256.sub(r_minus_p, rr, p);
cond |= 1-borrow;
cond |= UInt256.isZero(r_minus_p);
UInt256.cmov(r, cond, rr, r_minus_p);
}
/*
@Override
protected void prepareMontMul(long m, long[] mp)
{
long c = -m;
c = (c & 0xffffffffL) | ((m + (c>>32)) << 32);
mp[0]=m * 0xfffffc2fL;
mp[1]=m * 0xfffffffeL;
mp[2]=c;
mp[3]=c;
mp[4]=c;
mp[5]=c;
mp[6]=c;
mp[7]=c;
//for (int i=0; i