/// <summary> /// Calculates the multiplicative inverse of <c>this</c> and returns the result in a new GF2nPolynomialElement /// </summary> /// /// <returns>Returns <c>this</c>^(-1)</returns> public GF2nPolynomialElement InvertEEA() { if (IsZero()) throw new ArithmeticException(); GF2Polynomial b = new GF2Polynomial(mDegree + 32, "ONE"); b.ReduceN(); GF2Polynomial c = new GF2Polynomial(mDegree + 32); c.ReduceN(); GF2Polynomial u = GetGF2Polynomial(); GF2Polynomial v = mField.FieldPolynomial; GF2Polynomial h; int j; u.ReduceN(); while (!u.IsOne()) { u.ReduceN(); v.ReduceN(); j = u.Length - v.Length; if (j < 0) { h = u; u = v; v = h; h = b; b = c; c = h; j = -j; c.ReduceN(); // this increases the performance } u.ShiftLeftAddThis(v, j); b.ShiftLeftAddThis(c, j); } b.ReduceN(); return new GF2nPolynomialElement((GF2nPolynomialField)mField, b); }
/// <summary> /// Does the recursion for Karatzuba multiplication /// </summary> /// /// <param name="B">A GF2Polynomial</param> /// /// <returns><c>this * B</c></returns> private GF2Polynomial KaraMult(GF2Polynomial B) { GF2Polynomial result = new GF2Polynomial(_length << 1); if (_length <= 32) { result._value = Mult32(_value[0], B._value[0]); return result; } if (_length <= 64) { result._value = Mult64(_value, B._value); return result; } if (_length <= 128) { result._value = Mult128(_value, B._value); return result; } if (_length <= 256) { result._value = Mult256(_value, B._value); return result; } if (_length <= 512) { result._value = Mult512(_value, B._value); return result; } int n = BigMath.FloorLog(_length - 1); n = _bitMask[n]; GF2Polynomial a0 = Lower(((n - 1) >> 5) + 1); GF2Polynomial a1 = Upper(((n - 1) >> 5) + 1); GF2Polynomial b0 = B.Lower(((n - 1) >> 5) + 1); GF2Polynomial b1 = B.Upper(((n - 1) >> 5) + 1); GF2Polynomial c = a1.KaraMult(b1); // c = a1*b1 GF2Polynomial e = a0.KaraMult(b0); // e = a0*b0 a0.AddToThis(a1); // a0 = a0 + a1 b0.AddToThis(b1); // b0 = b0 + b1 GF2Polynomial d = a0.KaraMult(b0); // d = (a0+a1)*(b0+b1) result.ShiftLeftAddThis(c, n << 1); result.ShiftLeftAddThis(c, n); result.ShiftLeftAddThis(d, n); result.ShiftLeftAddThis(e, n); result.AddToThis(e); return result; }