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

org.bouncycastle.pqc.legacy.math.linearalgebra.PolynomialRingGF2 Maven / Gradle / Ivy

Go to download

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.pqc.legacy.math.linearalgebra;

/**
 * This class describes operations with polynomials over finite field GF(2), i e
 * polynomial ring R = GF(2)[X]. All operations are defined only for polynomials
 * with degree <=32. For the polynomial representation the map f: R->Z,
 * poly(X)->poly(2) is used, where integers have the binary representation. For
 * example: X^7+X^3+X+1 -> (00...0010001011)=139 Also for polynomials type
 * Integer is used.
 *
 * @see GF2mField
 */
public final class PolynomialRingGF2
{

    /**
     * Default constructor (private).
     */
    private PolynomialRingGF2()
    {
        // empty
    }

    /**
     * Return sum of two polyomials
     *
     * @param p polynomial
     * @param q polynomial
     * @return p+q
     */

    public static int add(int p, int q)
    {
        return p ^ q;
    }

    /**
     * Return product of two polynomials
     *
     * @param p polynomial
     * @param q polynomial
     * @return p*q
     */

    public static long multiply(int p, int q)
    {
        long result = 0;
        if (q != 0)
        {
            long q1 = q & 0x00000000ffffffffL;

            while (p != 0)
            {
                byte b = (byte)(p & 0x01);
                if (b == 1)
                {
                    result ^= q1;
                }
                p >>>= 1;
                q1 <<= 1;

            }
        }
        return result;
    }

    /**
     * Compute the product of two polynomials modulo a third polynomial.
     *
     * @param a the first polynomial
     * @param b the second polynomial
     * @param r the reduction polynomial
     * @return a * b mod r
     */
    public static int modMultiply(int a, int b, int r)
    {
        int result = 0;
        int p = remainder(a, r);
        int q = remainder(b, r);
        if (q != 0)
        {
            int d = 1 << degree(r);

            while (p != 0)
            {
                byte pMod2 = (byte)(p & 0x01);
                if (pMod2 == 1)
                {
                    result ^= q;
                }
                p >>>= 1;
                q <<= 1;
                if (q >= d)
                {
                    q ^= r;
                }
            }
        }
        return result;
    }

    /**
     * Return the degree of a polynomial
     *
     * @param p polynomial p
     * @return degree(p)
     */

    public static int degree(int p)
    {
        int result = -1;
        while (p != 0)
        {
            result++;
            p >>>= 1;
        }
        return result;
    }

    /**
     * Return the degree of a polynomial
     *
     * @param p polynomial p
     * @return degree(p)
     */

    public static int degree(long p)
    {
        int result = 0;
        while (p != 0)
        {
            result++;
            p >>>= 1;
        }
        return result - 1;
    }

    /**
     * Return the remainder of a polynomial division of two polynomials.
     *
     * @param p dividend
     * @param q divisor
     * @return p mod q
     */
    public static int remainder(int p, int q)
    {
        int result = p;

        if (q == 0)
        {
            // -DM System.err.println
            System.err.println("Error: to be divided by 0");
            return 0;
        }

        while (degree(result) >= degree(q))
        {
            result ^= q << (degree(result) - degree(q));
        }

        return result;
    }

    /**
     * Return the rest of devision two polynomials
     *
     * @param p polinomial
     * @param q polinomial
     * @return p mod q
     */

    public static int rest(long p, int q)
    {
        long p1 = p;
        if (q == 0)
        {
            // -DM System.err.println
            System.err.println("Error: to be divided by 0");
            return 0;
        }
        long q1 = q & 0x00000000ffffffffL;
        while ((p1 >>> 32) != 0)
        {
            p1 ^= q1 << (degree(p1) - degree(q1));
        }

        int result = (int)(p1 & 0xffffffff);
        while (degree(result) >= degree(q))
        {
            result ^= q << (degree(result) - degree(q));
        }

        return result;
    }

    /**
     * Return the greatest common divisor of two polynomials
     *
     * @param p polinomial
     * @param q polinomial
     * @return GCD(p, q)
     */

    public static int gcd(int p, int q)
    {
        int a, b, c;
        a = p;
        b = q;
        while (b != 0)
        {
            c = remainder(a, b);
            a = b;
            b = c;

        }
        return a;
    }

    /**
     * Checking polynomial for irreducibility
     *
     * @param p polinomial
     * @return true if p is irreducible and false otherwise
     */

    public static boolean isIrreducible(int p)
    {
        if (p == 0)
        {
            return false;
        }
        int d = degree(p) >>> 1;
        int u = 2;
        for (int i = 0; i < d; i++)
        {
            u = modMultiply(u, u, p);
            if (gcd(u ^ 2, p) != 1)
            {
                return false;
            }
        }
        return true;
    }

    /**
     * Creates irreducible polynomial with degree d
     *
     * @param deg polynomial degree
     * @return irreducible polynomial p
     */
    public static int getIrreduciblePolynomial(int deg)
    {
        if (deg < 0)
        {
            // -DM System.err.println
            System.err.println("The Degree is negative");
            return 0;
        }
        if (deg > 31)
        {
            // -DM System.err.println
            System.err.println("The Degree is more then 31");
            return 0;
        }
        if (deg == 0)
        {
            return 1;
        }
        int a = 1 << deg;
        a++;
        int b = 1 << (deg + 1);
        for (int i = a; i < b; i += 2)
        {
            if (isIrreducible(i))
            {
                return i;
            }
        }
        return 0;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy