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

java-ec.com.unbound.common.crypto.ec.SecP256R1 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 SecP256R1 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 = 0xffffffffL;
  private static final long P1 = 0xffffffffL;
  private static final long P2 = 0xffffffffL;
  private static final long P3 = 0x00000000L;
  private static final long P4 = 0x00000000L;
  private static final long P5 = 0x00000000L;
  private static final long P6 = 0x00000001L;
  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 = {0x00000001, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffffffe, 0x00000000};
  private static final int[] MONT_RR  = {0x00000003, 0x00000000, 0xffffffff, 0xfffffffb, 0xfffffffe, 0xffffffff, 0xfffffffd, 0x00000004};
  private static final int[] B        = {0x27d2604b, 0x3bce3c3e, 0xcc53b0f6, 0x651d06b0, 0x769886bc, 0xb3ebbd55, 0xaa3a93e7, 0x5ac635d8};
  private static final int[] Gx       = {0xd898c296, 0xf4a13945, 0x2deb33a0, 0x77037d81, 0x63a440f2, 0xf8bce6e5, 0xe12c4247, 0x6b17d1f2};
  private static final int[] Gy       = {0x37bf51f5, 0xcbb64068, 0x6b315ece, 0x2bce3357, 0x7c0f9e16, 0x8ee7eb4a, 0xfe1a7f9b, 0x4fe342e2};
  private static final int[] q        = {0xfc632551, 0xf3b9cac2, 0xa7179e84, 0xbce6faad, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff};

  private SecP256R1()
  {
    super(256, P, 1, MONT_ONE, MONT_RR, -3, B, Gx, Gy, q);
  }

  private static SecP256R1 instance = null;
  private static Point infinityInstance = null;

  static SecP256R1 getInstance()
  {
    if (instance==null) instance = new SecP256R1();
    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);      r[3] = (int)c; c >>>= 32;
    c += (x[4] & 0xffffffffL);      r[4] = (int)c; c >>>= 32;
    c += (x[5] & 0xffffffffL);      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);      r[3] = (int)c; c >>= 32;
    c += (x[4] & 0xffffffffL);      r[4] = (int)c; c >>= 32;
    c += (x[5] & 0xffffffffL);      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)
  {
    long t0 =               (x[0] & 0xffffffffL) + (y[0] & 0xffffffffL); long r0 =              (t0 & 0xffffffffL) - 0xffffffffL;
    long t1 = (t0 >>> 32) + (x[1] & 0xffffffffL) + (y[1] & 0xffffffffL); long r1 = (r0 >> 32) + (t1 & 0xffffffffL) - 0xffffffffL;
    long t2 = (t1 >>> 32) + (x[2] & 0xffffffffL) + (y[2] & 0xffffffffL); long r2 = (r1 >> 32) + (t2 & 0xffffffffL) - 0xffffffffL;
    long t3 = (t2 >>> 32) + (x[3] & 0xffffffffL) + (y[3] & 0xffffffffL); long r3 = (r2 >> 32) + (t3 & 0xffffffffL);
    long t4 = (t3 >>> 32) + (x[4] & 0xffffffffL) + (y[4] & 0xffffffffL); long r4 = (r3 >> 32) + (t4 & 0xffffffffL);
    long t5 = (t4 >>> 32) + (x[5] & 0xffffffffL) + (y[5] & 0xffffffffL); long r5 = (r4 >> 32) + (t5 & 0xffffffffL);
    long t6 = (t5 >>> 32) + (x[6] & 0xffffffffL) + (y[6] & 0xffffffffL); long r6 = (r5 >> 32) + (t6 & 0xffffffffL) - 0x00000001L;
    long t7 = (t6 >>> 32) + (x[7] & 0xffffffffL) + (y[7] & 0xffffffffL); long r7 = (r6 >> 32) + (t7 & 0xffffffffL) - 0xffffffffL;

    long carry = t7 >>> 32;
    long borrow = r7 >> 32;

    long cond = ~carry & borrow;
    cond = -(cond & 1);

    r[0] = (int)(((r0 ^ t0) & cond) ^ r0);
    r[1] = (int)(((r1 ^ t1) & cond) ^ r1);
    r[2] = (int)(((r2 ^ t2) & cond) ^ r2);
    r[3] = (int)(((r3 ^ t3) & cond) ^ r3);
    r[4] = (int)(((r4 ^ t4) & cond) ^ r4);
    r[5] = (int)(((r5 ^ t5) & cond) ^ r5);
    r[6] = (int)(((r6 ^ t6) & cond) ^ r6);
    r[7] = (int)(((r7 ^ t7) & cond) ^ r7);
  }

  @Override
  protected void sub(int[] r, int[] x, int[] y, IntPool pool)
  {
    long t0 =              (x[0] & 0xffffffffL) - (y[0] & 0xffffffffL);
    long t1 = (t0 >> 32) + (x[1] & 0xffffffffL) - (y[1] & 0xffffffffL);
    long t2 = (t1 >> 32) + (x[2] & 0xffffffffL) - (y[2] & 0xffffffffL);
    long t3 = (t2 >> 32) + (x[3] & 0xffffffffL) - (y[3] & 0xffffffffL);
    long t4 = (t3 >> 32) + (x[4] & 0xffffffffL) - (y[4] & 0xffffffffL);
    long t5 = (t4 >> 32) + (x[5] & 0xffffffffL) - (y[5] & 0xffffffffL);
    long t6 = (t5 >> 32) + (x[6] & 0xffffffffL) - (y[6] & 0xffffffffL);
    long t7 = (t6 >> 32) + (x[7] & 0xffffffffL) - (y[7] & 0xffffffffL);

    long borrow = (t7 >> 32) & 1;
    long cond = -borrow;
    long z;

    z =              (t0 & 0xffffffffL) + 0xffffffffL; r[0] = (int)(((z ^ t0) & cond) ^ t0);
    z = (z >>> 32) + (t1 & 0xffffffffL) + 0xffffffffL; r[1] = (int)(((z ^ t1) & cond) ^ t1);
    z = (z >>> 32) + (t2 & 0xffffffffL) + 0xffffffffL; r[2] = (int)(((z ^ t2) & cond) ^ t2);
    z = (z >>> 32) + (t3 & 0xffffffffL);               r[3] = (int)(((z ^ t3) & cond) ^ t3);
    z = (z >>> 32) + (t4 & 0xffffffffL);               r[4] = (int)(((z ^ t4) & cond) ^ t4);
    z = (z >>> 32) + (t5 & 0xffffffffL);               r[5] = (int)(((z ^ t5) & cond) ^ t5);
    z = (z >>> 32) + (t6 & 0xffffffffL) + 0x00000001L; r[6] = (int)(((z ^ t6) & cond) ^ t6);
    z = (z >>> 32) + (t7 & 0xffffffffL) + 0xffffffffL; r[7] = (int)(((z ^ t7) & cond) ^ t7);
  }

  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, invp);
    //return;

    int[] rr = IntPool.alloc(pool, IntPool.BASE+2);
    UInt256.setZero(rr);
    long rs = 0;

    long x, lo, hi;

    {
      long ai   = a[0] & 0xffffffffL;
      long A    = ai * (b[0] & 0xffffffffL);
      long m    = (A & 0xffffffffL); // * invp
           A    = A >>> 32;

           x    = -m;
      long mpLo = x & 0xffffffffL;
      long mpHi = m + (x>>32);

      long B    = ((mpLo | (mpHi<<32)) + m) >>> 32;

      //----------------------------------------------

      x     = ai * (b[1] & 0xffffffffL);
      hi    = x >>> 32;
      x     = (x & 0xffffffffL) + A;
      A     = hi + (x >>> 32);

      x     = (x & 0xffffffffL) + mpLo;
      hi    = x >>> 32;
      x     = (x & 0xffffffffL) + B;
      rr[0] = (int)x;
      B     = mpHi + hi + (x >>> 32);
      //----------------------------------------------

      x     = ai * (b[2] & 0xffffffffL);

      hi    = x >>> 32;
      x     = A + (x & 0xffffffffL);
      A     = hi + (x >>> 32);

      x     = (x & 0xffffffffL) + mpLo;
      hi    = x >>> 32;
      x     = (x & 0xffffffffL) + B;
      rr[1] = (int)x;
      B     = mpHi + hi + (x >>> 32);
      //----------------------------------------------

      x     = ai * (b[3] & 0xffffffffL);
      hi    = x >>> 32;
      x     = (x & 0xffffffffL) + A;
      A     = hi + (x >>> 32);

      x     = (x & 0xffffffffL) + B;
      rr[2] = (int)x;
      B     = x >>> 32;
      //----------------------------------------------

      x     = ai * (b[4] & 0xffffffffL);
      hi    = x >>> 32;
      x     = (x & 0xffffffffL) + A;
      A     = hi + (x >>> 32);

      x     = (x & 0xffffffffL) + B;
      rr[3] = (int)x;
      B     = x >>> 32;
      //----------------------------------------------

      x     = ai * (b[5] & 0xffffffffL);
      hi    = x >>> 32;
      x     = A + (x & 0xffffffffL);
      A     = hi + (x >>> 32);

      x     = B + (x & 0xffffffffL);
      rr[4] = (int)x;
      B     = x >>> 32;
      //----------------------------------------------

      x     = ai * (b[6] & 0xffffffffL);
      hi    = (x >>> 32);
      x     = (x & 0xffffffffL) + A;
      A     = hi + (x >>> 32);

      x     = (x & 0xffffffffL) + m;
      hi    = x>>>32;
      x     = (x & 0xffffffffL) + B;
      rr[5] = (int)x;
      B     = hi + (x >>> 32);
      //----------------------------------------------

      x     = ai * (b[7] & 0xffffffffL);
      hi    = (x >>> 32);
      x     = (x & 0xffffffffL) + A;
      A     = (hi + (x >>> 32));// & 0xffffffffL;

      x     = (x & 0xffffffffL) + mpLo;
      hi    = x >>> 32;
      x     = (x & 0xffffffffL) + B;
      rr[6] = (int)x;
      //----------------------------------------------

      A    += rs;
      B     = (A & 0xffffffffL) + ((mpHi + hi + (x >>> 32)) & 0xffffffffL);
      rr[7] = (int)B;
      rs    = ((A >>> 32) + (B >>> 32));// & 0xffffffffL;
    }

    for (int i=1; i<8; i++)
    {
      long ai   = a[i] & 0xffffffffL;
      long A    = ai * (b[0] & 0xffffffffL) + (rr[0] & 0xffffffffL);
      long m    = (A & 0xffffffffL); // * invp
           A    = A >>> 32;

           x    = -m;
      long mpLo = x & 0xffffffffL;
      long mpHi = m + (x>>32);

      long B    = ((mpLo | (mpHi<<32)) + m) >>> 32;

      //----------------------------------------------

      x     = ai * (b[1] & 0xffffffffL);
      hi    = x >>> 32;
      lo    = (x & 0xffffffffL) + (rr[1] & 0xffffffffL);
      x     = lo >>> 32;
      lo    = (lo & 0xffffffffL) + A;
      A     = hi + x + (lo >>> 32);

      x     = (lo & 0xffffffffL) + mpLo;
      hi    = x >>> 32;
      x     = (x & 0xffffffffL) + B;
      rr[0] = (int)x;
      B     = mpHi + hi + (x >>> 32);
      //----------------------------------------------

      x     = ai * (b[2] & 0xffffffffL);
      hi    = x >>> 32;
      lo    = (x & 0xffffffffL) + (rr[2] & 0xffffffffL);
      x     = lo >>> 32;
      lo    = (lo & 0xffffffffL) + A;
      A     = hi + x + (lo >>> 32);

      x     = (lo & 0xffffffffL) + mpLo;
      hi    = x >>> 32;
      x     = B + (x & 0xffffffffL);
      rr[1] = (int)x;
      B     = mpHi + hi + (x >>> 32);
      //----------------------------------------------

      x     = ai * (b[3] & 0xffffffffL);
      hi    = x >>> 32;
      x     = (x & 0xffffffffL) + (rr[3] & 0xffffffffL);
      lo    = x >>> 32;
      x     = (x & 0xffffffffL) + A;
      A     = hi + lo + (x >>> 32);

      x     = (x & 0xffffffffL) + B;
      rr[2] = (int)x;
      B     = x >>> 32;
      //----------------------------------------------

      x     = ai * (b[4] & 0xffffffffL);
      hi    = x >>> 32;
      x     = (x & 0xffffffffL) + (rr[4] & 0xffffffffL);
      lo    = x >>> 32;
      x     = (x & 0xffffffffL) + A;
      A     = hi + lo + (x >>> 32);

      x     = B + (x & 0xffffffffL);
      rr[3] = (int)x;
      B     = x >>> 32;
      //----------------------------------------------

      x     = ai * (b[5] & 0xffffffffL);
      hi    = x >>> 32;
      x     = (x & 0xffffffffL) + (rr[5] & 0xffffffffL);
      lo    = x >>> 32;
      x     = (x & 0xffffffffL) + A;
      A     = hi + lo + (x >>> 32);

      x     = (x & 0xffffffffL) + B;
      rr[4] = (int)x;
      B     = x >>> 32;
      //----------------------------------------------

      x     = ai * (b[6] & 0xffffffffL);
      lo    = (x & 0xffffffffL) + (rr[6] & 0xffffffffL);
      hi    = (x >>> 32) + (lo >>> 32);
      lo    = (lo & 0xffffffffL) + A;
      A     = hi + (lo >>> 32);

      lo    = (lo & 0xffffffffL) + m;
      x     = lo>>>32;
      lo    = (lo & 0xffffffffL) + B;
      rr[5] = (int)lo;
      B     = x + (lo >>> 32);
      //----------------------------------------------

      x     = ai * (b[7] & 0xffffffffL);
      lo    = (x & 0xffffffffL) + (rr[7] & 0xffffffffL);
      hi    = (x >>> 32) + (lo >>> 32);
      x     = (lo & 0xffffffffL) + A;
      A     = hi + (x >>> 32);

      x     = (x & 0xffffffffL) + mpLo;
      hi    = x >>> 32;
      x     = (x & 0xffffffffL) + B;
      rr[6] = (int)x;
      //----------------------------------------------

      A    += rs;
      B     = (A & 0xffffffffL) + ((mpHi + hi + (x >>> 32)) & 0xffffffffL);
      rr[7] = (int)B;
      rs    = ((A >>> 32) + (B >>> 32));// & 0xffffffffL;
    }

    int cond = (int)rs;
    int[] r_minus_p = IntPool.alloc(pool, IntPool.BASE+3);//alloc();
    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]=c;
    mp[1]=c;
    mp[2]=c;
    mp[3]=0;
    mp[4]=0;
    mp[5]=0;
    mp[6]=m;
    mp[7]=c;

    //for (int i=0; i




© 2015 - 2024 Weber Informatics LLC | Privacy Policy