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);
		}
示例#4
0
		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;
		}
示例#5
0
		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;
		}
示例#6
0
		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];
			}
		}