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

org.testifyproject.bouncycastle.pqc.math.linearalgebra.GF2mField Maven / Gradle / Ivy

package org.testifyproject.bouncycastle.pqc.math.linearalgebra;

import java.security.SecureRandom;

/**
 * This class org.testifyproject.testifyprojectscribes operations with elements from the finite field F =
 * GF(2^m). ( GF(2^m)= GF(2)[A] where A is a root of irreducible polynomial with
 * org.testifyproject.testifyprojectgree m, each field element B has a polynomial basis representation, i.e. it
 * is represented by a different binary polynomial of org.testifyproject.testifyprojectgree less than m, B =
 * poly(A) ) All operations are org.testifyproject.testifyprojectfined only for field with 1< m <32. For the
 * representation of field elements the map f: F->Z, poly(A)->poly(2) is used,
 * where integers have the binary representation. For example: A^7+A^3+A+1 ->
 * (00...0010001011)=139 Also for elements type Integer is used.
 *
 * @see PolynomialRingGF2
 */
public class GF2mField
{

    /*
      * org.testifyproject.testifyprojectgree - org.testifyproject.testifyprojectgree of the field polynomial - the field polynomial ring -
      * polynomial ring over the finite field GF(2)
      */

    private int org.testifyproject.testifyprojectgree = 0;

    private int polynomial;

    /**
     * create a finite field GF(2^m)
     *
     * @param org.testifyproject.testifyprojectgree the org.testifyproject.testifyprojectgree of the field
     */
    public GF2mField(int org.testifyproject.testifyprojectgree)
    {
        if (org.testifyproject.testifyprojectgree >= 32)
        {
            throw new IllegalArgumentException(
                " Error: the org.testifyproject.testifyprojectgree of field is too large ");
        }
        if (org.testifyproject.testifyprojectgree < 1)
        {
            throw new IllegalArgumentException(
                " Error: the org.testifyproject.testifyprojectgree of field is non-positive ");
        }
        this.org.testifyproject.testifyprojectgree = org.testifyproject.testifyprojectgree;
        polynomial = PolynomialRingGF2.getIrreduciblePolynomial(org.testifyproject.testifyprojectgree);
    }

    /**
     * create a finite field GF(2^m) with the fixed field polynomial
     *
     * @param org.testifyproject.testifyprojectgree the org.testifyproject.testifyprojectgree of the field
     * @param poly   the field polynomial
     */
    public GF2mField(int org.testifyproject.testifyprojectgree, int poly)
    {
        if (org.testifyproject.testifyprojectgree != PolynomialRingGF2.org.testifyproject.testifyprojectgree(poly))
        {
            throw new IllegalArgumentException(
                " Error: the org.testifyproject.testifyprojectgree is not correct");
        }
        if (!PolynomialRingGF2.isIrreducible(poly))
        {
            throw new IllegalArgumentException(
                " Error: given polynomial is reducible");
        }
        this.org.testifyproject.testifyprojectgree = org.testifyproject.testifyprojectgree;
        polynomial = poly;

    }

    public GF2mField(byte[] enc)
    {
        if (enc.length != 4)
        {
            throw new IllegalArgumentException(
                "byte array is not an encoded finite field");
        }
        polynomial = LittleEndianConversions.OS2IP(enc);
        if (!PolynomialRingGF2.isIrreducible(polynomial))
        {
            throw new IllegalArgumentException(
                "byte array is not an encoded finite field");
        }

        org.testifyproject.testifyprojectgree = PolynomialRingGF2.org.testifyproject.testifyprojectgree(polynomial);
    }

    public GF2mField(GF2mField field)
    {
        org.testifyproject.testifyprojectgree = field.org.testifyproject.testifyprojectgree;
        polynomial = field.polynomial;
    }

    /**
     * return org.testifyproject.testifyprojectgree of the field
     *
     * @return org.testifyproject.testifyprojectgree of the field
     */
    public int getDegree()
    {
        return org.testifyproject.testifyprojectgree;
    }

    /**
     * return the field polynomial
     *
     * @return the field polynomial
     */
    public int getPolynomial()
    {
        return polynomial;
    }

    /**
     * return the encoded form of this field
     *
     * @return the field in byte array form
     */
    public byte[] getEncoded()
    {
        return LittleEndianConversions.I2OSP(polynomial);
    }

    /**
     * Return sum of two elements
     *
     * @param a
     * @param b
     * @return a+b
     */
    public int add(int a, int b)
    {
        return a ^ b;
    }

    /**
     * Return product of two elements
     *
     * @param a
     * @param b
     * @return a*b
     */
    public int mult(int a, int b)
    {
        return PolynomialRingGF2.modMultiply(a, b, polynomial);
    }

    /**
     * org.testifyproject.testifyprojectpute exponentiation a^k
     *
     * @param a a field element a
     * @param k k org.testifyproject.testifyprojectgree
     * @return a^k
     */
    public int exp(int a, int k)
    {
        if (a == 0)
        {
            return 0;
        }
        if (a == 1)
        {
            return 1;
        }
        int result = 1;
        if (k < 0)
        {
            a = inverse(a);
            k = -k;
        }
        while (k != 0)
        {
            if ((k & 1) == 1)
            {
                result = mult(result, a);
            }
            a = mult(a, a);
            k >>>= 1;
        }
        return result;
    }

    /**
     * org.testifyproject.testifyprojectpute the multiplicative inverse of a
     *
     * @param a a field element a
     * @return a-1
     */
    public int inverse(int a)
    {
        int d = (1 << org.testifyproject.testifyprojectgree) - 2;

        return exp(a, d);
    }

    /**
     * org.testifyproject.testifyprojectpute the square root of an integer
     *
     * @param a a field element a
     * @return a1/2
     */
    public int sqRoot(int a)
    {
        for (int i = 1; i < org.testifyproject.testifyprojectgree; i++)
        {
            a = mult(a, a);
        }
        return a;
    }

    /**
     * create a random field element using PRNG sr
     *
     * @param sr SecureRandom
     * @return a random element
     */
    public int getRandomElement(SecureRandom sr)
    {
        int result = RandUtils.nextInt(sr, 1 << org.testifyproject.testifyprojectgree);
        return result;
    }

    /**
     * create a random non-zero field element
     *
     * @return a random element
     */
    public int getRandomNonZeroElement()
    {
        return getRandomNonZeroElement(new SecureRandom());
    }

    /**
     * create a random non-zero field element using PRNG sr
     *
     * @param sr SecureRandom
     * @return a random non-zero element
     */
    public int getRandomNonZeroElement(SecureRandom sr)
    {
        int controltime = 1 << 20;
        int count = 0;
        int result = RandUtils.nextInt(sr, 1 << org.testifyproject.testifyprojectgree);
        while ((result == 0) && (count < controltime))
        {
            result = RandUtils.nextInt(sr, 1 << org.testifyproject.testifyprojectgree);
            count++;
        }
        if (count == controltime)
        {
            result = 1;
        }
        return result;
    }

    /**
     * @return true if e is encoded element of this field and false otherwise
     */
    public boolean isElementOfThisField(int e)
    {
        // e is encoded element of this field iff 0<= e < |2^m|
        if (org.testifyproject.testifyprojectgree == 31)
        {
            return e >= 0;
        }
        return e >= 0 && e < (1 << org.testifyproject.testifyprojectgree);
    }

    /*
      * help method for visual control
      */
    public String elementToStr(int a)
    {
        String s = "";
        for (int i = 0; i < org.testifyproject.testifyprojectgree; i++)
        {
            if (((byte)a & 0x01) == 0)
            {
                s = "0" + s;
            }
            else
            {
                s = "1" + s;
            }
            a >>>= 1;
        }
        return s;
    }

    /**
     * checks if given object is equal to this field.
     * 

* The method returns false whenever the given object is not GF2m. * * @param other object * @return true or false */ public boolean equals(Object other) { if ((other == null) || !(other instanceof GF2mField)) { return false; } GF2mField otherField = (GF2mField)other; if ((org.testifyproject.testifyprojectgree == otherField.org.testifyproject.testifyprojectgree) && (polynomial == otherField.polynomial)) { return true; } return false; } public int hashCode() { return polynomial; } /** * Returns a human readable form of this field. * * @return a human readable form of this field. */ public String toString() { String str = "Finite Field GF(2^" + org.testifyproject.testifyprojectgree + ") = " + "GF(2)[X]/<" + polyToString(polynomial) + "> "; return str; } private static String polyToString(int p) { String str = ""; if (p == 0) { str = "0"; } else { byte b = (byte)(p & 0x01); if (b == 1) { str = "1"; } p >>>= 1; int i = 1; while (p != 0) { b = (byte)(p & 0x01); if (b == 1) { str = str + "+x^" + i; } p >>>= 1; i++; } } return str; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy