< Summary

Information
Class: Renci.SshNet.Security.Org.BouncyCastle.Math.EC.F2mFieldElement
Assembly: Renci.SshNet
File(s): \home\appveyor\projects\ssh-net\src\Renci.SshNet\Security\BouncyCastle\math\ec\ECFieldElement.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 146
Coverable lines: 146
Total lines: 972
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 52
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity Line coverage
.ctor(...)0%140%
.ctor(...)100%10%
.ctor(...)0%20%
get_BitLength()100%10%
get_IsOne()100%10%
get_IsZero()100%10%
TestBitZero()100%10%
ToBigInteger()100%10%
get_FieldName()100%10%
get_FieldSize()100%10%
CheckFieldElements(...)0%100%
Add(...)100%10%
AddOne()100%10%
Subtract(...)100%10%
Multiply(...)100%10%
MultiplyMinusProduct(...)100%10%
MultiplyPlusProduct(...)0%40%
Divide(...)100%10%
Negate()100%10%
Square()100%10%
SquareMinusProduct(...)100%10%
SquarePlusProduct(...)0%20%
SquarePow(...)0%20%
Invert()100%10%
Sqrt()0%40%
get_Representation()100%10%
get_M()100%10%
get_K1()100%10%
get_K2()0%20%
get_K3()0%20%
Equals(...)0%40%
Equals(...)0%60%
GetHashCode()100%10%

File(s)

\home\appveyor\projects\ssh-net\src\Renci.SshNet\Security\BouncyCastle\math\ec\ECFieldElement.cs

#LineLine coverage
 1using System;
 2using System.Diagnostics;
 3
 4using Renci.SshNet.Security.Org.BouncyCastle.Math.Raw;
 5using Renci.SshNet.Security.Org.BouncyCastle.Utilities;
 6
 7namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC
 8{
 9    internal abstract class ECFieldElement
 10    {
 11        public abstract BigInteger ToBigInteger();
 12        public abstract string FieldName { get; }
 13        public abstract int FieldSize { get; }
 14        public abstract ECFieldElement Add(ECFieldElement b);
 15        public abstract ECFieldElement AddOne();
 16        public abstract ECFieldElement Subtract(ECFieldElement b);
 17        public abstract ECFieldElement Multiply(ECFieldElement b);
 18        public abstract ECFieldElement Divide(ECFieldElement b);
 19        public abstract ECFieldElement Negate();
 20        public abstract ECFieldElement Square();
 21        public abstract ECFieldElement Invert();
 22        public abstract ECFieldElement Sqrt();
 23
 24        public virtual int BitLength
 25        {
 26            get { return ToBigInteger().BitLength; }
 27        }
 28
 29        public virtual bool IsOne
 30        {
 31            get { return BitLength == 1; }
 32        }
 33
 34        public virtual bool IsZero
 35        {
 36            get { return 0 == ToBigInteger().SignValue; }
 37        }
 38
 39        public virtual ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
 40        {
 41            return Multiply(b).Subtract(x.Multiply(y));
 42        }
 43
 44        public virtual ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
 45        {
 46            return Multiply(b).Add(x.Multiply(y));
 47        }
 48
 49        public virtual ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y)
 50        {
 51            return Square().Subtract(x.Multiply(y));
 52        }
 53
 54        public virtual ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y)
 55        {
 56            return Square().Add(x.Multiply(y));
 57        }
 58
 59        public virtual ECFieldElement SquarePow(int pow)
 60        {
 61            ECFieldElement r = this;
 62            for (int i = 0; i < pow; ++i)
 63            {
 64                r = r.Square();
 65            }
 66            return r;
 67        }
 68
 69        public virtual bool TestBitZero()
 70        {
 71            return ToBigInteger().TestBit(0);
 72        }
 73
 74        public override bool Equals(object obj)
 75        {
 76            return Equals(obj as ECFieldElement);
 77        }
 78
 79        public virtual bool Equals(ECFieldElement other)
 80        {
 81            if (this == other)
 82                return true;
 83            if (null == other)
 84                return false;
 85            return ToBigInteger().Equals(other.ToBigInteger());
 86        }
 87
 88        public override int GetHashCode()
 89        {
 90            return ToBigInteger().GetHashCode();
 91        }
 92
 93        public override string ToString()
 94        {
 95            return this.ToBigInteger().ToString(16);
 96        }
 97
 98        public virtual byte[] GetEncoded()
 99        {
 100            return BigIntegers.AsUnsignedByteArray((FieldSize + 7) / 8, ToBigInteger());
 101        }
 102    }
 103
 104    internal abstract class AbstractFpFieldElement
 105        : ECFieldElement
 106    {
 107    }
 108
 109    internal class FpFieldElement
 110        : AbstractFpFieldElement
 111    {
 112        private readonly BigInteger q, r, x;
 113
 114        internal static BigInteger CalculateResidue(BigInteger p)
 115        {
 116            int bitLength = p.BitLength;
 117            if (bitLength >= 96)
 118            {
 119                BigInteger firstWord = p.ShiftRight(bitLength - 64);
 120                if (firstWord.LongValue == -1L)
 121                {
 122                    return BigInteger.One.ShiftLeft(bitLength).Subtract(p);
 123                }
 124                if ((bitLength & 7) == 0)
 125                {
 126                    return BigInteger.One.ShiftLeft(bitLength << 1).Divide(p).Negate();
 127                }
 128            }
 129            return null;
 130        }
 131
 132        [Obsolete("Use ECCurve.FromBigInteger to construct field elements")]
 133        public FpFieldElement(BigInteger q, BigInteger x)
 134            : this(q, CalculateResidue(q), x)
 135        {
 136        }
 137
 138        internal FpFieldElement(BigInteger q, BigInteger r, BigInteger x)
 139        {
 140            if (x == null || x.SignValue < 0 || x.CompareTo(q) >= 0)
 141                throw new ArgumentException("value invalid in Fp field element", "x");
 142
 143            this.q = q;
 144            this.r = r;
 145            this.x = x;
 146        }
 147
 148        public override BigInteger ToBigInteger()
 149        {
 150            return x;
 151        }
 152
 153        /**
 154         * return the field name for this field.
 155         *
 156         * @return the string "Fp".
 157         */
 158        public override string FieldName
 159        {
 160            get { return "Fp"; }
 161        }
 162
 163        public override int FieldSize
 164        {
 165            get { return q.BitLength; }
 166        }
 167
 168        public BigInteger Q
 169        {
 170            get { return q; }
 171        }
 172
 173        public override ECFieldElement Add(
 174            ECFieldElement b)
 175        {
 176            return new FpFieldElement(q, r, ModAdd(x, b.ToBigInteger()));
 177        }
 178
 179        public override ECFieldElement AddOne()
 180        {
 181            BigInteger x2 = x.Add(BigInteger.One);
 182            if (x2.CompareTo(q) == 0)
 183            {
 184                x2 = BigInteger.Zero;
 185            }
 186            return new FpFieldElement(q, r, x2);
 187        }
 188
 189        public override ECFieldElement Subtract(
 190            ECFieldElement b)
 191        {
 192            return new FpFieldElement(q, r, ModSubtract(x, b.ToBigInteger()));
 193        }
 194
 195        public override ECFieldElement Multiply(
 196            ECFieldElement b)
 197        {
 198            return new FpFieldElement(q, r, ModMult(x, b.ToBigInteger()));
 199        }
 200
 201        public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
 202        {
 203            BigInteger ax = this.x, bx = b.ToBigInteger(), xx = x.ToBigInteger(), yx = y.ToBigInteger();
 204            BigInteger ab = ax.Multiply(bx);
 205            BigInteger xy = xx.Multiply(yx);
 206            return new FpFieldElement(q, r, ModReduce(ab.Subtract(xy)));
 207        }
 208
 209        public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
 210        {
 211            BigInteger ax = this.x, bx = b.ToBigInteger(), xx = x.ToBigInteger(), yx = y.ToBigInteger();
 212            BigInteger ab = ax.Multiply(bx);
 213            BigInteger xy = xx.Multiply(yx);
 214            BigInteger sum = ab.Add(xy);
 215            if (r != null && r.SignValue < 0 && sum.BitLength > (q.BitLength << 1))
 216            {
 217                sum = sum.Subtract(q.ShiftLeft(q.BitLength));
 218            }
 219            return new FpFieldElement(q, r, ModReduce(sum));
 220        }
 221
 222        public override ECFieldElement Divide(
 223            ECFieldElement b)
 224        {
 225            return new FpFieldElement(q, r, ModMult(x, ModInverse(b.ToBigInteger())));
 226        }
 227
 228        public override ECFieldElement Negate()
 229        {
 230            return x.SignValue == 0 ? this : new FpFieldElement(q, r, q.Subtract(x));
 231        }
 232
 233        public override ECFieldElement Square()
 234        {
 235            return new FpFieldElement(q, r, ModMult(x, x));
 236        }
 237
 238        public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y)
 239        {
 240            BigInteger ax = this.x, xx = x.ToBigInteger(), yx = y.ToBigInteger();
 241            BigInteger aa = ax.Multiply(ax);
 242            BigInteger xy = xx.Multiply(yx);
 243            return new FpFieldElement(q, r, ModReduce(aa.Subtract(xy)));
 244        }
 245
 246        public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y)
 247        {
 248            BigInteger ax = this.x, xx = x.ToBigInteger(), yx = y.ToBigInteger();
 249            BigInteger aa = ax.Multiply(ax);
 250            BigInteger xy = xx.Multiply(yx);
 251            BigInteger sum = aa.Add(xy);
 252            if (r != null && r.SignValue < 0 && sum.BitLength > (q.BitLength << 1))
 253            {
 254                sum = sum.Subtract(q.ShiftLeft(q.BitLength));
 255            }
 256            return new FpFieldElement(q, r, ModReduce(sum));
 257        }
 258
 259        public override ECFieldElement Invert()
 260        {
 261            // TODO Modular inversion can be faster for a (Generalized) Mersenne Prime.
 262            return new FpFieldElement(q, r, ModInverse(x));
 263        }
 264
 265        /**
 266         * return a sqrt root - the routine verifies that the calculation
 267         * returns the right value - if none exists it returns null.
 268         */
 269        public override ECFieldElement Sqrt()
 270        {
 271            if (IsZero || IsOne)
 272                return this;
 273
 274            if (!q.TestBit(0))
 275                throw new NotImplementedException("even value of q");
 276
 277            if (q.TestBit(1)) // q == 4m + 3
 278            {
 279                BigInteger e = q.ShiftRight(2).Add(BigInteger.One);
 280                return CheckSqrt(new FpFieldElement(q, r, x.ModPow(e, q)));
 281            }
 282
 283            if (q.TestBit(2)) // q == 8m + 5
 284            {
 285                BigInteger t1 = x.ModPow(q.ShiftRight(3), q);
 286                BigInteger t2 = ModMult(t1, x);
 287                BigInteger t3 = ModMult(t2, t1);
 288
 289                if (t3.Equals(BigInteger.One))
 290                {
 291                    return CheckSqrt(new FpFieldElement(q, r, t2));
 292                }
 293
 294                // TODO This is constant and could be precomputed
 295                BigInteger t4 = BigInteger.Two.ModPow(q.ShiftRight(2), q);
 296
 297                BigInteger y = ModMult(t2, t4);
 298
 299                return CheckSqrt(new FpFieldElement(q, r, y));
 300            }
 301
 302            // q == 8m + 1
 303
 304            BigInteger legendreExponent = q.ShiftRight(1);
 305            if (!(x.ModPow(legendreExponent, q).Equals(BigInteger.One)))
 306                return null;
 307
 308            BigInteger X = this.x;
 309            BigInteger fourX = ModDouble(ModDouble(X)); ;
 310
 311            BigInteger k = legendreExponent.Add(BigInteger.One), qMinusOne = q.Subtract(BigInteger.One);
 312
 313            BigInteger U, V;
 314            do
 315            {
 316                BigInteger P;
 317                do
 318                {
 319                    P = BigInteger.Arbitrary(q.BitLength);
 320                }
 321                while (P.CompareTo(q) >= 0
 322                    || !ModReduce(P.Multiply(P).Subtract(fourX)).ModPow(legendreExponent, q).Equals(qMinusOne));
 323
 324                BigInteger[] result = LucasSequence(P, X, k);
 325                U = result[0];
 326                V = result[1];
 327
 328                if (ModMult(V, V).Equals(fourX))
 329                {
 330                    return new FpFieldElement(q, r, ModHalfAbs(V));
 331                }
 332            }
 333            while (U.Equals(BigInteger.One) || U.Equals(qMinusOne));
 334
 335            return null;
 336        }
 337
 338        private ECFieldElement CheckSqrt(ECFieldElement z)
 339        {
 340            return z.Square().Equals(this) ? z : null;
 341        }
 342
 343        private BigInteger[] LucasSequence(
 344            BigInteger  P,
 345            BigInteger  Q,
 346            BigInteger  k)
 347        {
 348            // TODO Research and apply "common-multiplicand multiplication here"
 349
 350            int n = k.BitLength;
 351            int s = k.GetLowestSetBit();
 352
 353            Debug.Assert(k.TestBit(s));
 354
 355            BigInteger Uh = BigInteger.One;
 356            BigInteger Vl = BigInteger.Two;
 357            BigInteger Vh = P;
 358            BigInteger Ql = BigInteger.One;
 359            BigInteger Qh = BigInteger.One;
 360
 361            for (int j = n - 1; j >= s + 1; --j)
 362            {
 363                Ql = ModMult(Ql, Qh);
 364
 365                if (k.TestBit(j))
 366                {
 367                    Qh = ModMult(Ql, Q);
 368                    Uh = ModMult(Uh, Vh);
 369                    Vl = ModReduce(Vh.Multiply(Vl).Subtract(P.Multiply(Ql)));
 370                    Vh = ModReduce(Vh.Multiply(Vh).Subtract(Qh.ShiftLeft(1)));
 371                }
 372                else
 373                {
 374                    Qh = Ql;
 375                    Uh = ModReduce(Uh.Multiply(Vl).Subtract(Ql));
 376                    Vh = ModReduce(Vh.Multiply(Vl).Subtract(P.Multiply(Ql)));
 377                    Vl = ModReduce(Vl.Multiply(Vl).Subtract(Ql.ShiftLeft(1)));
 378                }
 379            }
 380
 381            Ql = ModMult(Ql, Qh);
 382            Qh = ModMult(Ql, Q);
 383            Uh = ModReduce(Uh.Multiply(Vl).Subtract(Ql));
 384            Vl = ModReduce(Vh.Multiply(Vl).Subtract(P.Multiply(Ql)));
 385            Ql = ModMult(Ql, Qh);
 386
 387            for (int j = 1; j <= s; ++j)
 388            {
 389                Uh = ModMult(Uh, Vl);
 390                Vl = ModReduce(Vl.Multiply(Vl).Subtract(Ql.ShiftLeft(1)));
 391                Ql = ModMult(Ql, Ql);
 392            }
 393
 394            return new BigInteger[] { Uh, Vl };
 395        }
 396
 397        protected virtual BigInteger ModAdd(BigInteger x1, BigInteger x2)
 398        {
 399            BigInteger x3 = x1.Add(x2);
 400            if (x3.CompareTo(q) >= 0)
 401            {
 402                x3 = x3.Subtract(q);
 403            }
 404            return x3;
 405        }
 406
 407        protected virtual BigInteger ModDouble(BigInteger x)
 408        {
 409            BigInteger _2x = x.ShiftLeft(1);
 410            if (_2x.CompareTo(q) >= 0)
 411            {
 412                _2x = _2x.Subtract(q);
 413            }
 414            return _2x;
 415        }
 416
 417        protected virtual BigInteger ModHalf(BigInteger x)
 418        {
 419            if (x.TestBit(0))
 420            {
 421                x = q.Add(x);
 422            }
 423            return x.ShiftRight(1);
 424        }
 425
 426        protected virtual BigInteger ModHalfAbs(BigInteger x)
 427        {
 428            if (x.TestBit(0))
 429            {
 430                x = q.Subtract(x);
 431            }
 432            return x.ShiftRight(1);
 433        }
 434
 435        protected virtual BigInteger ModInverse(BigInteger x)
 436        {
 437            int bits = FieldSize;
 438            int len = (bits + 31) >> 5;
 439            uint[] p = Nat.FromBigInteger(bits, q);
 440            uint[] n = Nat.FromBigInteger(bits, x);
 441            uint[] z = Nat.Create(len);
 442            Mod.Invert(p, n, z);
 443            return Nat.ToBigInteger(len, z);
 444        }
 445
 446        protected virtual BigInteger ModMult(BigInteger x1, BigInteger x2)
 447        {
 448            return ModReduce(x1.Multiply(x2));
 449        }
 450
 451        protected virtual BigInteger ModReduce(BigInteger x)
 452        {
 453            if (r == null)
 454            {
 455                x = x.Mod(q);
 456            }
 457            else
 458            {
 459                bool negative = x.SignValue < 0;
 460                if (negative)
 461                {
 462                    x = x.Abs();
 463                }
 464                int qLen = q.BitLength;
 465                if (r.SignValue > 0)
 466                {
 467                    BigInteger qMod = BigInteger.One.ShiftLeft(qLen);
 468                    bool rIsOne = r.Equals(BigInteger.One);
 469                    while (x.BitLength > (qLen + 1))
 470                    {
 471                        BigInteger u = x.ShiftRight(qLen);
 472                        BigInteger v = x.Remainder(qMod);
 473                        if (!rIsOne)
 474                        {
 475                            u = u.Multiply(r);
 476                        }
 477                        x = u.Add(v);
 478                    }
 479                }
 480                else
 481                {
 482                    int d = ((qLen - 1) & 31) + 1;
 483                    BigInteger mu = r.Negate();
 484                    BigInteger u = mu.Multiply(x.ShiftRight(qLen - d));
 485                    BigInteger quot = u.ShiftRight(qLen + d);
 486                    BigInteger v = quot.Multiply(q);
 487                    BigInteger bk1 = BigInteger.One.ShiftLeft(qLen + d);
 488                    v = v.Remainder(bk1);
 489                    x = x.Remainder(bk1);
 490                    x = x.Subtract(v);
 491                    if (x.SignValue < 0)
 492                    {
 493                        x = x.Add(bk1);
 494                    }
 495                }
 496                while (x.CompareTo(q) >= 0)
 497                {
 498                    x = x.Subtract(q);
 499                }
 500                if (negative && x.SignValue != 0)
 501                {
 502                    x = q.Subtract(x);
 503                }
 504            }
 505            return x;
 506        }
 507
 508        protected virtual BigInteger ModSubtract(BigInteger x1, BigInteger x2)
 509        {
 510            BigInteger x3 = x1.Subtract(x2);
 511            if (x3.SignValue < 0)
 512            {
 513                x3 = x3.Add(q);
 514            }
 515            return x3;
 516        }
 517
 518        public override bool Equals(
 519            object obj)
 520        {
 521            if (obj == this)
 522                return true;
 523
 524            FpFieldElement other = obj as FpFieldElement;
 525
 526            if (other == null)
 527                return false;
 528
 529            return Equals(other);
 530        }
 531
 532        public virtual bool Equals(
 533            FpFieldElement other)
 534        {
 535            return q.Equals(other.q) && base.Equals(other);
 536        }
 537
 538        public override int GetHashCode()
 539        {
 540            return q.GetHashCode() ^ base.GetHashCode();
 541        }
 542    }
 543
 544    internal abstract class AbstractF2mFieldElement
 545        :   ECFieldElement
 546    {
 547        public virtual ECFieldElement HalfTrace()
 548        {
 549            int m = FieldSize;
 550            if ((m & 1) == 0)
 551                throw new InvalidOperationException("Half-trace only defined for odd m");
 552
 553            ECFieldElement fe = this;
 554            ECFieldElement ht = fe;
 555            for (int i = 2; i < m; i += 2)
 556            {
 557                fe = fe.SquarePow(2);
 558                ht = ht.Add(fe);
 559            }
 560
 561            return ht;
 562        }
 563
 564        public virtual int Trace()
 565        {
 566            int m = FieldSize;
 567            ECFieldElement fe = this;
 568            ECFieldElement tr = fe;
 569            for (int i = 1; i < m; ++i)
 570            {
 571                fe = fe.Square();
 572                tr = tr.Add(fe);
 573            }
 574            if (tr.IsZero)
 575                return 0;
 576            if (tr.IsOne)
 577                return 1;
 578
 579            throw new InvalidOperationException("Internal error in trace calculation");
 580        }
 581    }
 582
 583    /**
 584     * Class representing the Elements of the finite field
 585     * <code>F<sub>2<sup>m</sup></sub></code> in polynomial basis (PB)
 586     * representation. Both trinomial (Tpb) and pentanomial (Ppb) polynomial
 587     * basis representations are supported. Gaussian normal basis (GNB)
 588     * representation is not supported.
 589     */
 590    internal class F2mFieldElement
 591        :   AbstractF2mFieldElement
 592    {
 593        /**
 594         * Indicates gaussian normal basis representation (GNB). Number chosen
 595         * according to X9.62. GNB is not implemented at present.
 596         */
 597        public const int Gnb = 1;
 598
 599        /**
 600         * Indicates trinomial basis representation (Tpb). Number chosen
 601         * according to X9.62.
 602         */
 603        public const int Tpb = 2;
 604
 605        /**
 606         * Indicates pentanomial basis representation (Ppb). Number chosen
 607         * according to X9.62.
 608         */
 609        public const int Ppb = 3;
 610
 611        /**
 612         * Tpb or Ppb.
 613         */
 614        private int representation;
 615
 616        /**
 617         * The exponent <code>m</code> of <code>F<sub>2<sup>m</sup></sub></code>.
 618         */
 619        private int m;
 620
 621        private int[] ks;
 622
 623        /**
 624         * The <code>LongArray</code> holding the bits.
 625         */
 626        internal LongArray x;
 627
 628        /**
 629         * Constructor for Ppb.
 630         * @param m  The exponent <code>m</code> of
 631         * <code>F<sub>2<sup>m</sup></sub></code>.
 632         * @param k1 The integer <code>k1</code> where <code>x<sup>m</sup> +
 633         * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code>
 634         * represents the reduction polynomial <code>f(z)</code>.
 635         * @param k2 The integer <code>k2</code> where <code>x<sup>m</sup> +
 636         * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code>
 637         * represents the reduction polynomial <code>f(z)</code>.
 638         * @param k3 The integer <code>k3</code> where <code>x<sup>m</sup> +
 639         * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code>
 640         * represents the reduction polynomial <code>f(z)</code>.
 641         * @param x The BigInteger representing the value of the field element.
 642         */
 0643        public F2mFieldElement(
 0644            int      m,
 0645            int      k1,
 0646            int      k2,
 0647            int      k3,
 0648            BigInteger  x)
 0649        {
 0650            if (x == null || x.SignValue < 0 || x.BitLength > m)
 0651                throw new ArgumentException("value invalid in F2m field element", "x");
 652
 0653            if ((k2 == 0) && (k3 == 0))
 0654            {
 0655                this.representation = Tpb;
 0656                this.ks = new int[] { k1 };
 0657            }
 658            else
 0659            {
 0660                if (k2 >= k3)
 0661                    throw new ArgumentException("k2 must be smaller than k3");
 0662                if (k2 <= 0)
 0663                    throw new ArgumentException("k2 must be larger than 0");
 664
 0665                this.representation = Ppb;
 0666                this.ks = new int[] { k1, k2, k3 };
 0667            }
 668
 0669            this.m = m;
 0670            this.x = new LongArray(x);
 0671        }
 672
 673        /**
 674         * Constructor for Tpb.
 675         * @param m  The exponent <code>m</code> of
 676         * <code>F<sub>2<sup>m</sup></sub></code>.
 677         * @param k The integer <code>k</code> where <code>x<sup>m</sup> +
 678         * x<sup>k</sup> + 1</code> represents the reduction
 679         * polynomial <code>f(z)</code>.
 680         * @param x The BigInteger representing the value of the field element.
 681         */
 682        public F2mFieldElement(
 683            int      m,
 684            int      k,
 685            BigInteger  x)
 0686            : this(m, k, 0, 0, x)
 0687        {
 688            // Set k1 to k, and set k2 and k3 to 0
 0689        }
 690
 0691        internal F2mFieldElement(int m, int[] ks, LongArray x)
 0692        {
 0693            this.m = m;
 0694            this.representation = (ks.Length == 1) ? Tpb : Ppb;
 0695            this.ks = ks;
 0696            this.x = x;
 0697        }
 698
 699        public override int BitLength
 700        {
 0701            get { return x.Degree(); }
 702        }
 703
 704        public override bool IsOne
 705        {
 0706            get { return x.IsOne(); }
 707        }
 708
 709        public override bool IsZero
 710        {
 0711            get { return x.IsZero(); }
 712        }
 713
 714        public override bool TestBitZero()
 0715        {
 0716            return x.TestBitZero();
 0717        }
 718
 719        public override BigInteger ToBigInteger()
 0720        {
 0721            return x.ToBigInteger();
 0722        }
 723
 724        public override string FieldName
 725        {
 0726            get { return "F2m"; }
 727        }
 728
 729        public override int FieldSize
 730        {
 0731            get { return m; }
 732        }
 733
 734        /**
 735        * Checks, if the ECFieldElements <code>a</code> and <code>b</code>
 736        * are elements of the same field <code>F<sub>2<sup>m</sup></sub></code>
 737        * (having the same representation).
 738        * @param a field element.
 739        * @param b field element to be compared.
 740        * @throws ArgumentException if <code>a</code> and <code>b</code>
 741        * are not elements of the same field
 742        * <code>F<sub>2<sup>m</sup></sub></code> (having the same
 743        * representation).
 744        */
 745        public static void CheckFieldElements(
 746            ECFieldElement  a,
 747            ECFieldElement  b)
 0748        {
 0749            if (!(a is F2mFieldElement) || !(b is F2mFieldElement))
 0750            {
 0751                throw new ArgumentException("Field elements are not "
 0752                    + "both instances of F2mFieldElement");
 753            }
 754
 0755            F2mFieldElement aF2m = (F2mFieldElement)a;
 0756            F2mFieldElement bF2m = (F2mFieldElement)b;
 757
 0758            if (aF2m.representation != bF2m.representation)
 0759            {
 760                // Should never occur
 0761                throw new ArgumentException("One of the F2m field elements has incorrect representation");
 762            }
 763
 0764            if ((aF2m.m != bF2m.m) || !Arrays.AreEqual(aF2m.ks, bF2m.ks))
 0765            {
 0766                throw new ArgumentException("Field elements are not elements of the same field F2m");
 767            }
 0768        }
 769
 770        public override ECFieldElement Add(
 771            ECFieldElement b)
 0772        {
 773            // No check performed here for performance reasons. Instead the
 774            // elements involved are checked in ECPoint.F2m
 775            // checkFieldElements(this, b);
 0776            LongArray iarrClone = this.x.Copy();
 0777            F2mFieldElement bF2m = (F2mFieldElement)b;
 0778            iarrClone.AddShiftedByWords(bF2m.x, 0);
 0779            return new F2mFieldElement(m, ks, iarrClone);
 0780        }
 781
 782        public override ECFieldElement AddOne()
 0783        {
 0784            return new F2mFieldElement(m, ks, x.AddOne());
 0785        }
 786
 787        public override ECFieldElement Subtract(
 788            ECFieldElement b)
 0789        {
 790            // Addition and subtraction are the same in F2m
 0791            return Add(b);
 0792        }
 793
 794        public override ECFieldElement Multiply(
 795            ECFieldElement b)
 0796        {
 797            // Right-to-left comb multiplication in the LongArray
 798            // Input: Binary polynomials a(z) and b(z) of degree at most m-1
 799            // Output: c(z) = a(z) * b(z) mod f(z)
 800
 801            // No check performed here for performance reasons. Instead the
 802            // elements involved are checked in ECPoint.F2m
 803            // checkFieldElements(this, b);
 0804            return new F2mFieldElement(m, ks, x.ModMultiply(((F2mFieldElement)b).x, m, ks));
 0805        }
 806
 807        public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
 0808        {
 0809            return MultiplyPlusProduct(b, x, y);
 0810        }
 811
 812        public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
 0813        {
 0814            LongArray ax = this.x, bx = ((F2mFieldElement)b).x, xx = ((F2mFieldElement)x).x, yx = ((F2mFieldElement)y).x
 815
 0816            LongArray ab = ax.Multiply(bx, m, ks);
 0817            LongArray xy = xx.Multiply(yx, m, ks);
 818
 0819            if (ab == ax || ab == bx)
 0820            {
 0821                ab = (LongArray)ab.Copy();
 0822            }
 823
 0824            ab.AddShiftedByWords(xy, 0);
 0825            ab.Reduce(m, ks);
 826
 0827            return new F2mFieldElement(m, ks, ab);
 0828        }
 829
 830        public override ECFieldElement Divide(
 831            ECFieldElement b)
 0832        {
 833            // There may be more efficient implementations
 0834            ECFieldElement bInv = b.Invert();
 0835            return Multiply(bInv);
 0836        }
 837
 838        public override ECFieldElement Negate()
 0839        {
 840            // -x == x holds for all x in F2m
 0841            return this;
 0842        }
 843
 844        public override ECFieldElement Square()
 0845        {
 0846            return new F2mFieldElement(m, ks, x.ModSquare(m, ks));
 0847        }
 848
 849        public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y)
 0850        {
 0851            return SquarePlusProduct(x, y);
 0852        }
 853
 854        public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y)
 0855        {
 0856            LongArray ax = this.x, xx = ((F2mFieldElement)x).x, yx = ((F2mFieldElement)y).x;
 857
 0858            LongArray aa = ax.Square(m, ks);
 0859            LongArray xy = xx.Multiply(yx, m, ks);
 860
 0861            if (aa == ax)
 0862            {
 0863                aa = (LongArray)aa.Copy();
 0864            }
 865
 0866            aa.AddShiftedByWords(xy, 0);
 0867            aa.Reduce(m, ks);
 868
 0869            return new F2mFieldElement(m, ks, aa);
 0870        }
 871
 872        public override ECFieldElement SquarePow(int pow)
 0873        {
 0874            return pow < 1 ? this : new F2mFieldElement(m, ks, x.ModSquareN(pow, m, ks));
 0875        }
 876
 877        public override ECFieldElement Invert()
 0878        {
 0879            return new F2mFieldElement(this.m, this.ks, this.x.ModInverse(m, ks));
 0880        }
 881
 882        public override ECFieldElement Sqrt()
 0883        {
 0884            return (x.IsZero() || x.IsOne()) ? this : SquarePow(m - 1);
 0885        }
 886
 887        /**
 888            * @return the representation of the field
 889            * <code>F<sub>2<sup>m</sup></sub></code>, either of
 890            * {@link F2mFieldElement.Tpb} (trinomial
 891            * basis representation) or
 892            * {@link F2mFieldElement.Ppb} (pentanomial
 893            * basis representation).
 894            */
 895        public int Representation
 896        {
 0897            get { return this.representation; }
 898        }
 899
 900        /**
 901            * @return the degree <code>m</code> of the reduction polynomial
 902            * <code>f(z)</code>.
 903            */
 904        public int M
 905        {
 0906            get { return this.m; }
 907        }
 908
 909        /**
 910            * @return Tpb: The integer <code>k</code> where <code>x<sup>m</sup> +
 911            * x<sup>k</sup> + 1</code> represents the reduction polynomial
 912            * <code>f(z)</code>.<br/>
 913            * Ppb: The integer <code>k1</code> where <code>x<sup>m</sup> +
 914            * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code>
 915            * represents the reduction polynomial <code>f(z)</code>.<br/>
 916            */
 917        public int K1
 918        {
 0919            get { return this.ks[0]; }
 920        }
 921
 922        /**
 923            * @return Tpb: Always returns <code>0</code><br/>
 924            * Ppb: The integer <code>k2</code> where <code>x<sup>m</sup> +
 925            * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code>
 926            * represents the reduction polynomial <code>f(z)</code>.<br/>
 927            */
 928        public int K2
 929        {
 0930            get { return this.ks.Length >= 2 ? this.ks[1] : 0; }
 931        }
 932
 933        /**
 934            * @return Tpb: Always set to <code>0</code><br/>
 935            * Ppb: The integer <code>k3</code> where <code>x<sup>m</sup> +
 936            * x<sup>k3</sup> + x<sup>k2</sup> + x<sup>k1</sup> + 1</code>
 937            * represents the reduction polynomial <code>f(z)</code>.<br/>
 938            */
 939        public int K3
 940        {
 0941            get { return this.ks.Length >= 3 ? this.ks[2] : 0; }
 942        }
 943
 944        public override bool Equals(
 945            object obj)
 0946        {
 0947            if (obj == this)
 0948                return true;
 949
 0950            F2mFieldElement other = obj as F2mFieldElement;
 951
 0952            if (other == null)
 0953                return false;
 954
 0955            return Equals(other);
 0956        }
 957
 958        public virtual bool Equals(
 959            F2mFieldElement other)
 0960        {
 0961            return ((this.m == other.m)
 0962                && (this.representation == other.representation)
 0963                && Arrays.AreEqual(this.ks, other.ks)
 0964                && (this.x.Equals(other.x)));
 0965        }
 966
 967        public override int GetHashCode()
 0968        {
 0969            return x.GetHashCode() ^ m ^ Arrays.GetHashCode(ks);
 0970        }
 971    }
 972}

Methods/Properties

.ctor(System.Int32,System.Int32,System.Int32,System.Int32,Renci.SshNet.Security.Org.BouncyCastle.Math.BigInteger)
.ctor(System.Int32,System.Int32,Renci.SshNet.Security.Org.BouncyCastle.Math.BigInteger)
.ctor(System.Int32,System.Int32[],Renci.SshNet.Security.Org.BouncyCastle.Math.EC.LongArray)
get_BitLength()
get_IsOne()
get_IsZero()
TestBitZero()
ToBigInteger()
get_FieldName()
get_FieldSize()
CheckFieldElements(Renci.SshNet.Security.Org.BouncyCastle.Math.EC.ECFieldElement,Renci.SshNet.Security.Org.BouncyCastle.Math.EC.ECFieldElement)
Add(Renci.SshNet.Security.Org.BouncyCastle.Math.EC.ECFieldElement)
AddOne()
Subtract(Renci.SshNet.Security.Org.BouncyCastle.Math.EC.ECFieldElement)
Multiply(Renci.SshNet.Security.Org.BouncyCastle.Math.EC.ECFieldElement)
MultiplyMinusProduct(Renci.SshNet.Security.Org.BouncyCastle.Math.EC.ECFieldElement,Renci.SshNet.Security.Org.BouncyCastle.Math.EC.ECFieldElement,Renci.SshNet.Security.Org.BouncyCastle.Math.EC.ECFieldElement)
MultiplyPlusProduct(Renci.SshNet.Security.Org.BouncyCastle.Math.EC.ECFieldElement,Renci.SshNet.Security.Org.BouncyCastle.Math.EC.ECFieldElement,Renci.SshNet.Security.Org.BouncyCastle.Math.EC.ECFieldElement)
Divide(Renci.SshNet.Security.Org.BouncyCastle.Math.EC.ECFieldElement)
Negate()
Square()
SquareMinusProduct(Renci.SshNet.Security.Org.BouncyCastle.Math.EC.ECFieldElement,Renci.SshNet.Security.Org.BouncyCastle.Math.EC.ECFieldElement)
SquarePlusProduct(Renci.SshNet.Security.Org.BouncyCastle.Math.EC.ECFieldElement,Renci.SshNet.Security.Org.BouncyCastle.Math.EC.ECFieldElement)
SquarePow(System.Int32)
Invert()
Sqrt()
get_Representation()
get_M()
get_K1()
get_K2()
get_K3()
Equals(System.Object)
Equals(Renci.SshNet.Security.Org.BouncyCastle.Math.EC.F2mFieldElement)
GetHashCode()