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

nl.open.jwtdependency.org.bouncycastle.asn1.ua.DSTU4145PointEncoder Maven / Gradle / Ivy

Go to download

This is a drop in replacement for the auth0 java-jwt library (see https://github.com/auth0/java-jwt). This jar makes sure there are no external dependencies (e.g. fasterXml, Apacha Commons) needed. This is useful when deploying to an application server (e.g. tomcat with Alfreso or Pega).

The newest version!
package org.bouncycastle.asn1.ua;

import java.math.BigInteger;
import java.util.Random;

import org.bouncycastle.math.ec.ECConstants;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECFieldElement;
import org.bouncycastle.math.ec.ECPoint;

/**
 * DSTU4145 encodes points somewhat differently than X9.62
 * It compresses the point to the size of the field element
 */
public abstract class DSTU4145PointEncoder
{
    private static ECFieldElement trace(ECFieldElement fe)
    {
        ECFieldElement t = fe;
        for (int i = 1; i < fe.getFieldSize(); ++i)
        {
            t = t.square().add(fe);
        }
        return t;
    }

    /**
     * Solves a quadratic equation z2 + z = beta(X9.62
     * D.1.6) The other solution is z + 1.
     *
     * @param beta The value to solve the quadratic equation for.
     * @return the solution for z2 + z = beta or
     *         null if no solution exists.
     */
    private static ECFieldElement solveQuadraticEquation(ECCurve curve, ECFieldElement beta)
    {
        if (beta.isZero())
        {
            return beta;
        }

        ECFieldElement zeroElement = curve.fromBigInteger(ECConstants.ZERO);

        ECFieldElement z = null;
        ECFieldElement gamma = null;

        Random rand = new Random();
        int m = beta.getFieldSize();
        do
        {
            ECFieldElement t = curve.fromBigInteger(new BigInteger(m, rand));
            z = zeroElement;
            ECFieldElement w = beta;
            for (int i = 1; i <= m - 1; i++)
            {
                ECFieldElement w2 = w.square();
                z = z.square().add(w2.multiply(t));
                w = w2.add(beta);
            }
            if (!w.isZero())
            {
                return null;
            }
            gamma = z.square().add(z);
        }
        while (gamma.isZero());

        return z;
    }

    public static byte[] encodePoint(ECPoint Q)
    {
        /*if (!Q.isCompressed())
              Q=new ECPoint.F2m(Q.getCurve(),Q.getX(),Q.getY(),true);

          byte[] bytes=Q.getEncoded();

          if (bytes[0]==0x02)
              bytes[bytes.length-1]&=0xFE;
          else if (bytes[0]==0x02)
              bytes[bytes.length-1]|=0x01;

          return Arrays.copyOfRange(bytes, 1, bytes.length);*/

        Q = Q.normalize();

        ECFieldElement x = Q.getAffineXCoord();

        byte[] bytes = x.getEncoded();

        if (!x.isZero())
        {
            ECFieldElement z = Q.getAffineYCoord().divide(x);
            if (trace(z).isOne())
            {
                bytes[bytes.length - 1] |= 0x01;
            }
            else
            {
                bytes[bytes.length - 1] &= 0xFE;
            }
        }

        return bytes;
    }

    public static ECPoint decodePoint(ECCurve curve, byte[] bytes)
    {
        /*byte[] bp_enc=new byte[bytes.length+1];
          if (0==(bytes[bytes.length-1]&0x1))
              bp_enc[0]=0x02;
          else
              bp_enc[0]=0x03;
          System.arraycopy(bytes, 0, bp_enc, 1, bytes.length);
          if (!trace(curve.fromBigInteger(new BigInteger(1, bytes))).equals(curve.getA().toBigInteger()))
              bp_enc[bp_enc.length-1]^=0x01;

          return curve.decodePoint(bp_enc);*/

        ECFieldElement k = curve.fromBigInteger(BigInteger.valueOf(bytes[bytes.length - 1] & 0x1));

        ECFieldElement xp = curve.fromBigInteger(new BigInteger(1, bytes));
        if (!trace(xp).equals(curve.getA()))
        {
            xp = xp.addOne();
        }

        ECFieldElement yp = null;
        if (xp.isZero())
        {
            yp = curve.getB().sqrt();
        }
        else
        {
            ECFieldElement beta = xp.square().invert().multiply(curve.getB()).add(curve.getA()).add(xp);
            ECFieldElement z = solveQuadraticEquation(curve, beta);
            if (z != null)
            {
                if (!trace(z).equals(k))
                {
                    z = z.addOne();
                }
                yp = xp.multiply(z);
            }
        }

        if (yp == null)
        {
            throw new IllegalArgumentException("Invalid point compression");
        }

        return curve.validatePoint(xp.toBigInteger(), yp.toBigInteger());
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy