public ECFieldElement add(final ECFieldElement b) { // No check performed here for performance reasons. Instead the // elements involved are checked in ECPoint.F2m // checkFieldElements(this, b); IntArray iarrClone = (IntArray) this.x.clone(); F2m bF2m = (F2m) b; iarrClone.addShifted(bF2m.x, 0); return new F2m(m, k1, k2, k3, iarrClone); }
public ECFieldElement multiply(final ECFieldElement b) { // Right-to-left comb multiplication in the IntArray // Input: Binary polynomials a(z) and b(z) of degree at most m-1 // Output: c(z) = a(z) * b(z) mod f(z) // No check performed here for performance reasons. Instead the // elements involved are checked in ECPoint.F2m // checkFieldElements(this, b); F2m bF2m = (F2m) b; IntArray mult = x.multiply(bF2m.x, m); mult.reduce(m, new int[] {k1, k2, k3}); return new F2m(m, k1, k2, k3, mult); }
public boolean equals(Object o) { if (!(o instanceof IntArray)) { return false; } IntArray other = (IntArray) o; int usedLen = getUsedLength(); if (other.getUsedLength() != usedLen) { return false; } for (int i = 0; i < usedLen; i++) { if (m_ints[i] != other.m_ints[i]) { return false; } } return true; }
public void addShifted(IntArray other, int shift) { int usedLenOther = other.getUsedLength(); int newMinUsedLen = usedLenOther + shift; if (newMinUsedLen > m_ints.length) { m_ints = resizedInts(newMinUsedLen); // System.out.println("Resize required"); } for (int i = 0; i < usedLenOther; i++) { m_ints[i + shift] ^= other.m_ints[i]; } }
public IntArray multiply(IntArray other, int m) { // Lenght of c is 2m bits rounded up to the next int (32 bit) int t = (m + 31) >> 5; if (m_ints.length < t) { m_ints = resizedInts(t); } IntArray b = new IntArray(other.resizedInts(other.getLength() + 1)); IntArray c = new IntArray((m + m + 31) >> 5); // IntArray c = new IntArray(t + t); int testBit = 1; for (int k = 0; k < 32; k++) { for (int j = 0; j < t; j++) { if ((m_ints[j] & testBit) != 0) { // The kth bit of m_ints[j] is set c.addShifted(b, j); } } testBit <<= 1; b.shiftLeft(); } return c; }
public ECFieldElement invert() { // Inversion in F2m using the extended Euclidean algorithm // Input: A nonzero polynomial a(z) of degree at most m-1 // Output: a(z)^(-1) mod f(z) // u(z) := a(z) IntArray uz = (IntArray) this.x.clone(); // v(z) := f(z) IntArray vz = new IntArray(t); vz.setBit(m); vz.setBit(0); vz.setBit(this.k1); if (this.representation == PPB) { vz.setBit(this.k2); vz.setBit(this.k3); } // g1(z) := 1, g2(z) := 0 IntArray g1z = new IntArray(t); g1z.setBit(0); IntArray g2z = new IntArray(t); // while u != 0 while (!uz.isZero()) // while (uz.getUsedLength() > 0) // while (uz.bitLength() > 1) { // j := deg(u(z)) - deg(v(z)) int j = uz.bitLength() - vz.bitLength(); // If j < 0 then: u(z) <-> v(z), g1(z) <-> g2(z), j := -j if (j < 0) { final IntArray uzCopy = uz; uz = vz; vz = uzCopy; final IntArray g1zCopy = g1z; g1z = g2z; g2z = g1zCopy; j = -j; } // u(z) := u(z) + z^j * v(z) // Note, that no reduction modulo f(z) is required, because // deg(u(z) + z^j * v(z)) <= max(deg(u(z)), j + deg(v(z))) // = max(deg(u(z)), deg(u(z)) - deg(v(z)) + deg(v(z)) // = deg(u(z)) // uz = uz.xor(vz.shiftLeft(j)); // jInt = n / 32 int jInt = j >> 5; // jInt = n % 32 int jBit = j & 0x1F; IntArray vzShift = vz.shiftLeft(jBit); uz.addShifted(vzShift, jInt); // g1(z) := g1(z) + z^j * g2(z) // g1z = g1z.xor(g2z.shiftLeft(j)); IntArray g2zShift = g2z.shiftLeft(jBit); g1z.addShifted(g2zShift, jInt); } return new ECFieldElement.F2m(this.m, this.k1, this.k2, this.k3, g2z); }
public ECFieldElement square() { IntArray squared = x.square(m); squared.reduce(m, new int[] {k1, k2, k3}); return new F2m(m, k1, k2, k3, squared); }
public BigInteger toBigInteger() { return x.toBigInteger(); }
public int hashCode() { return x.hashCode() ^ m ^ k1 ^ k2 ^ k3; }