All Downloads are FREE. Search and download functionalities are using the official Maven repository.

java-ec.com.unbound.common.crypto.ec.SecP256K1 Maven / Gradle / Ivy

Go to download

This is a collection of JAVA libraries that implement Unbound cryptographic classes for JAVA provider, PKCS11 wrapper, cryptoki, and advapi

There is a newer version: 42761
Show newest version
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




© 2015 - 2024 Weber Informatics LLC | Privacy Policy