private F2mFieldElement(int m, int k1, int k2, int k3, IntArray x) { t = (m + 31) >> 5; this.x = x; this.m = m; this.k1 = k1; this.k2 = k2; this.k3 = k3; if ((k2 == 0) && (k3 == 0)) { this.representation = Tpb; } else { this.representation = Ppb; } }
/** * Constructor for Ppb. * @param m The exponent <code>m</code> of * <code>F<sub>2<sup>m</sup></sub></code>. * @param k1 The integer <code>k1</code> where <code>x<sup>m</sup> + * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code> * represents the reduction polynomial <code>f(z)</code>. * @param k2 The integer <code>k2</code> where <code>x<sup>m</sup> + * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code> * represents the reduction polynomial <code>f(z)</code>. * @param k3 The integer <code>k3</code> where <code>x<sup>m</sup> + * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code> * represents the reduction polynomial <code>f(z)</code>. * @param x The BigInteger representing the value of the field element. */ public F2mFieldElement( int m, int k1, int k2, int k3, BigInteger x) { // t = m / 32 rounded up to the next integer this.t = (m + 31) >> 5; this.x = new IntArray(x, t); if ((k2 == 0) && (k3 == 0)) { this.representation = Tpb; } else { if (k2 >= k3) throw new ArgumentException("k2 must be smaller than k3"); if (k2 <= 0) throw new ArgumentException("k2 must be larger than 0"); this.representation = Ppb; } if (x.Sign < 0) throw new ArgumentException("x value cannot be negative"); this.m = m; this.k1 = k1; this.k2 = k2; this.k3 = k3; }
public override 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.Copy(); // 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.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) { IntArray uzCopy = uz; uz = vz; vz = uzCopy; 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 F2mFieldElement(this.m, this.k1, this.k2, this.k3, g2z); }
public IntArray Square(int m) { // TODO make the table static readonly int[] table = { 0x0, 0x1, 0x4, 0x5, 0x10, 0x11, 0x14, 0x15, 0x40, 0x41, 0x44, 0x45, 0x50, 0x51, 0x54, 0x55 }; int t = (m + 31) >> 5; if (m_ints.Length < t) { m_ints = resizedInts(t); } IntArray c = new IntArray(t + t); // TODO twice the same code, put in separate private method for (int i = 0; i < t; i++) { int v0 = 0; for (int j = 0; j < 4; j++) { v0 = (int)((uint) v0 >> 8); int u = (int)((uint)m_ints[i] >> (j * 4)) & 0xF; int w = table[u] << 24; v0 |= w; } c.m_ints[i + i] = v0; v0 = 0; int upper = (int)((uint) m_ints[i] >> 16); for (int j = 0; j < 4; j++) { v0 = (int)((uint) v0 >> 8); int u = (int)((uint)upper >> (j * 4)) & 0xF; int w = table[u] << 24; v0 |= w; } c.m_ints[i + i + 1] = v0; } return c; }
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.Length + 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 void AddShifted(IntArray other, int shift) { int usedLenOther = other.GetUsedLength(); int newMinUsedLen = usedLenOther + shift; if (newMinUsedLen > m_ints.Length) { m_ints = resizedInts(newMinUsedLen); //Console.WriteLine("Resize required"); } for (int i = 0; i < usedLenOther; i++) { m_ints[i + shift] ^= other.m_ints[i]; } }