< Summary

Information
Class: Renci.SshNet.Security.Org.BouncyCastle.Math.EC.FpFieldElement
Assembly: Renci.SshNet
File(s): \home\appveyor\projects\ssh-net\src\Renci.SshNet\Security\BouncyCastle\math\ec\ECFieldElement.cs
Line coverage
41%
Covered lines: 122
Uncovered lines: 173
Coverable lines: 295
Total lines: 972
Line coverage: 41.3%
Branch coverage
29%
Covered branches: 28
Total branches: 94
Branch coverage: 29.7%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity Line coverage
CalculateResidue(...)66.66%685.71%
.ctor(...)100%10%
.ctor(...)50%687.5%
ToBigInteger()100%1100%
get_FieldName()100%10%
get_FieldSize()100%1100%
get_Q()100%10%
Add(...)100%1100%
AddOne()0%20%
Subtract(...)100%1100%
Multiply(...)100%1100%
MultiplyMinusProduct(...)100%1100%
MultiplyPlusProduct(...)0%60%
Divide(...)100%10%
Negate()50%2100%
Square()100%1100%
SquareMinusProduct(...)100%10%
SquarePlusProduct(...)0%60%
Invert()100%1100%
Sqrt()0%240%
CheckSqrt(...)0%20%
LucasSequence(...)0%60%
ModAdd(...)100%2100%
ModDouble(...)0%20%
ModHalf(...)0%20%
ModHalfAbs(...)0%20%
ModInverse(...)100%1100%
ModMult(...)100%1100%
ModReduce(...)88.88%1888.67%
ModSubtract(...)100%2100%
Equals(...)0%40%
Equals(...)0%20%
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)
 3115        {
 3116            int bitLength = p.BitLength;
 3117            if (bitLength >= 96)
 3118            {
 3119                BigInteger firstWord = p.ShiftRight(bitLength - 64);
 3120                if (firstWord.LongValue == -1L)
 2121                {
 2122                    return BigInteger.One.ShiftLeft(bitLength).Subtract(p);
 123                }
 1124                if ((bitLength & 7) == 0)
 1125                {
 1126                    return BigInteger.One.ShiftLeft(bitLength << 1).Divide(p).Negate();
 127                }
 0128            }
 0129            return null;
 3130        }
 131
 132        [Obsolete("Use ECCurve.FromBigInteger to construct field elements")]
 133        public FpFieldElement(BigInteger q, BigInteger x)
 0134            : this(q, CalculateResidue(q), x)
 0135        {
 0136        }
 137
 126712138        internal FpFieldElement(BigInteger q, BigInteger r, BigInteger x)
 126712139        {
 126712140            if (x == null || x.SignValue < 0 || x.CompareTo(q) >= 0)
 0141                throw new ArgumentException("value invalid in Fp field element", "x");
 142
 126712143            this.q = q;
 126712144            this.r = r;
 126712145            this.x = x;
 126712146        }
 147
 148        public override BigInteger ToBigInteger()
 130303149        {
 130303150            return x;
 130303151        }
 152
 153        /**
 154         * return the field name for this field.
 155         *
 156         * @return the string "Fp".
 157         */
 158        public override string FieldName
 159        {
 0160            get { return "Fp"; }
 161        }
 162
 163        public override int FieldSize
 164        {
 207165            get { return q.BitLength; }
 166        }
 167
 168        public BigInteger Q
 169        {
 0170            get { return q; }
 171        }
 172
 173        public override ECFieldElement Add(
 174            ECFieldElement b)
 41661175        {
 41661176            return new FpFieldElement(q, r, ModAdd(x, b.ToBigInteger()));
 41661177        }
 178
 179        public override ECFieldElement AddOne()
 0180        {
 0181            BigInteger x2 = x.Add(BigInteger.One);
 0182            if (x2.CompareTo(q) == 0)
 0183            {
 0184                x2 = BigInteger.Zero;
 0185            }
 0186            return new FpFieldElement(q, r, x2);
 0187        }
 188
 189        public override ECFieldElement Subtract(
 190            ECFieldElement b)
 20547191        {
 20547192            return new FpFieldElement(q, r, ModSubtract(x, b.ToBigInteger()));
 20547193        }
 194
 195        public override ECFieldElement Multiply(
 196            ECFieldElement b)
 35586197        {
 35586198            return new FpFieldElement(q, r, ModMult(x, b.ToBigInteger()));
 35586199        }
 200
 201        public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
 1401202        {
 5604203            BigInteger ax = this.x, bx = b.ToBigInteger(), xx = x.ToBigInteger(), yx = y.ToBigInteger();
 1401204            BigInteger ab = ax.Multiply(bx);
 1401205            BigInteger xy = xx.Multiply(yx);
 1401206            return new FpFieldElement(q, r, ModReduce(ab.Subtract(xy)));
 1401207        }
 208
 209        public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
 0210        {
 0211            BigInteger ax = this.x, bx = b.ToBigInteger(), xx = x.ToBigInteger(), yx = y.ToBigInteger();
 0212            BigInteger ab = ax.Multiply(bx);
 0213            BigInteger xy = xx.Multiply(yx);
 0214            BigInteger sum = ab.Add(xy);
 0215            if (r != null && r.SignValue < 0 && sum.BitLength > (q.BitLength << 1))
 0216            {
 0217                sum = sum.Subtract(q.ShiftLeft(q.BitLength));
 0218            }
 0219            return new FpFieldElement(q, r, ModReduce(sum));
 0220        }
 221
 222        public override ECFieldElement Divide(
 223            ECFieldElement b)
 0224        {
 0225            return new FpFieldElement(q, r, ModMult(x, ModInverse(b.ToBigInteger())));
 0226        }
 227
 228        public override ECFieldElement Negate()
 2925229        {
 2925230            return x.SignValue == 0 ? this : new FpFieldElement(q, r, q.Subtract(x));
 2925231        }
 232
 233        public override ECFieldElement Square()
 22372234        {
 22372235            return new FpFieldElement(q, r, ModMult(x, x));
 22372236        }
 237
 238        public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y)
 0239        {
 0240            BigInteger ax = this.x, xx = x.ToBigInteger(), yx = y.ToBigInteger();
 0241            BigInteger aa = ax.Multiply(ax);
 0242            BigInteger xy = xx.Multiply(yx);
 0243            return new FpFieldElement(q, r, ModReduce(aa.Subtract(xy)));
 0244        }
 245
 246        public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y)
 0247        {
 0248            BigInteger ax = this.x, xx = x.ToBigInteger(), yx = y.ToBigInteger();
 0249            BigInteger aa = ax.Multiply(ax);
 0250            BigInteger xy = xx.Multiply(yx);
 0251            BigInteger sum = aa.Add(xy);
 0252            if (r != null && r.SignValue < 0 && sum.BitLength > (q.BitLength << 1))
 0253            {
 0254                sum = sum.Subtract(q.ShiftLeft(q.BitLength));
 0255            }
 0256            return new FpFieldElement(q, r, ModReduce(sum));
 0257        }
 258
 259        public override ECFieldElement Invert()
 33260        {
 261            // TODO Modular inversion can be faster for a (Generalized) Mersenne Prime.
 33262            return new FpFieldElement(q, r, ModInverse(x));
 33263        }
 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()
 0270        {
 0271            if (IsZero || IsOne)
 0272                return this;
 273
 0274            if (!q.TestBit(0))
 0275                throw new NotImplementedException("even value of q");
 276
 0277            if (q.TestBit(1)) // q == 4m + 3
 0278            {
 0279                BigInteger e = q.ShiftRight(2).Add(BigInteger.One);
 0280                return CheckSqrt(new FpFieldElement(q, r, x.ModPow(e, q)));
 281            }
 282
 0283            if (q.TestBit(2)) // q == 8m + 5
 0284            {
 0285                BigInteger t1 = x.ModPow(q.ShiftRight(3), q);
 0286                BigInteger t2 = ModMult(t1, x);
 0287                BigInteger t3 = ModMult(t2, t1);
 288
 0289                if (t3.Equals(BigInteger.One))
 0290                {
 0291                    return CheckSqrt(new FpFieldElement(q, r, t2));
 292                }
 293
 294                // TODO This is constant and could be precomputed
 0295                BigInteger t4 = BigInteger.Two.ModPow(q.ShiftRight(2), q);
 296
 0297                BigInteger y = ModMult(t2, t4);
 298
 0299                return CheckSqrt(new FpFieldElement(q, r, y));
 300            }
 301
 302            // q == 8m + 1
 303
 0304            BigInteger legendreExponent = q.ShiftRight(1);
 0305            if (!(x.ModPow(legendreExponent, q).Equals(BigInteger.One)))
 0306                return null;
 307
 0308            BigInteger X = this.x;
 0309            BigInteger fourX = ModDouble(ModDouble(X)); ;
 310
 0311            BigInteger k = legendreExponent.Add(BigInteger.One), qMinusOne = q.Subtract(BigInteger.One);
 312
 313            BigInteger U, V;
 314            do
 0315            {
 316                BigInteger P;
 317                do
 0318                {
 0319                    P = BigInteger.Arbitrary(q.BitLength);
 0320                }
 0321                while (P.CompareTo(q) >= 0
 0322                    || !ModReduce(P.Multiply(P).Subtract(fourX)).ModPow(legendreExponent, q).Equals(qMinusOne));
 323
 0324                BigInteger[] result = LucasSequence(P, X, k);
 0325                U = result[0];
 0326                V = result[1];
 327
 0328                if (ModMult(V, V).Equals(fourX))
 0329                {
 0330                    return new FpFieldElement(q, r, ModHalfAbs(V));
 331                }
 0332            }
 0333            while (U.Equals(BigInteger.One) || U.Equals(qMinusOne));
 334
 0335            return null;
 0336        }
 337
 338        private ECFieldElement CheckSqrt(ECFieldElement z)
 0339        {
 0340            return z.Square().Equals(this) ? z : null;
 0341        }
 342
 343        private BigInteger[] LucasSequence(
 344            BigInteger  P,
 345            BigInteger  Q,
 346            BigInteger  k)
 0347        {
 348            // TODO Research and apply "common-multiplicand multiplication here"
 349
 0350            int n = k.BitLength;
 0351            int s = k.GetLowestSetBit();
 352
 0353            Debug.Assert(k.TestBit(s));
 354
 0355            BigInteger Uh = BigInteger.One;
 0356            BigInteger Vl = BigInteger.Two;
 0357            BigInteger Vh = P;
 0358            BigInteger Ql = BigInteger.One;
 0359            BigInteger Qh = BigInteger.One;
 360
 0361            for (int j = n - 1; j >= s + 1; --j)
 0362            {
 0363                Ql = ModMult(Ql, Qh);
 364
 0365                if (k.TestBit(j))
 0366                {
 0367                    Qh = ModMult(Ql, Q);
 0368                    Uh = ModMult(Uh, Vh);
 0369                    Vl = ModReduce(Vh.Multiply(Vl).Subtract(P.Multiply(Ql)));
 0370                    Vh = ModReduce(Vh.Multiply(Vh).Subtract(Qh.ShiftLeft(1)));
 0371                }
 372                else
 0373                {
 0374                    Qh = Ql;
 0375                    Uh = ModReduce(Uh.Multiply(Vl).Subtract(Ql));
 0376                    Vh = ModReduce(Vh.Multiply(Vl).Subtract(P.Multiply(Ql)));
 0377                    Vl = ModReduce(Vl.Multiply(Vl).Subtract(Ql.ShiftLeft(1)));
 0378                }
 0379            }
 380
 0381            Ql = ModMult(Ql, Qh);
 0382            Qh = ModMult(Ql, Q);
 0383            Uh = ModReduce(Uh.Multiply(Vl).Subtract(Ql));
 0384            Vl = ModReduce(Vh.Multiply(Vl).Subtract(P.Multiply(Ql)));
 0385            Ql = ModMult(Ql, Qh);
 386
 0387            for (int j = 1; j <= s; ++j)
 0388            {
 0389                Uh = ModMult(Uh, Vl);
 0390                Vl = ModReduce(Vl.Multiply(Vl).Subtract(Ql.ShiftLeft(1)));
 0391                Ql = ModMult(Ql, Ql);
 0392            }
 393
 0394            return new BigInteger[] { Uh, Vl };
 0395        }
 396
 397        protected virtual BigInteger ModAdd(BigInteger x1, BigInteger x2)
 41661398        {
 41661399            BigInteger x3 = x1.Add(x2);
 41661400            if (x3.CompareTo(q) >= 0)
 20844401            {
 20844402                x3 = x3.Subtract(q);
 20844403            }
 41661404            return x3;
 41661405        }
 406
 407        protected virtual BigInteger ModDouble(BigInteger x)
 0408        {
 0409            BigInteger _2x = x.ShiftLeft(1);
 0410            if (_2x.CompareTo(q) >= 0)
 0411            {
 0412                _2x = _2x.Subtract(q);
 0413            }
 0414            return _2x;
 0415        }
 416
 417        protected virtual BigInteger ModHalf(BigInteger x)
 0418        {
 0419            if (x.TestBit(0))
 0420            {
 0421                x = q.Add(x);
 0422            }
 0423            return x.ShiftRight(1);
 0424        }
 425
 426        protected virtual BigInteger ModHalfAbs(BigInteger x)
 0427        {
 0428            if (x.TestBit(0))
 0429            {
 0430                x = q.Subtract(x);
 0431            }
 0432            return x.ShiftRight(1);
 0433        }
 434
 435        protected virtual BigInteger ModInverse(BigInteger x)
 33436        {
 33437            int bits = FieldSize;
 33438            int len = (bits + 31) >> 5;
 33439            uint[] p = Nat.FromBigInteger(bits, q);
 33440            uint[] n = Nat.FromBigInteger(bits, x);
 33441            uint[] z = Nat.Create(len);
 33442            Mod.Invert(p, n, z);
 33443            return Nat.ToBigInteger(len, z);
 33444        }
 445
 446        protected virtual BigInteger ModMult(BigInteger x1, BigInteger x2)
 57958447        {
 57958448            return ModReduce(x1.Multiply(x2));
 57958449        }
 450
 451        protected virtual BigInteger ModReduce(BigInteger x)
 59359452        {
 59359453            if (r == null)
 0454            {
 0455                x = x.Mod(q);
 0456            }
 457            else
 59359458            {
 59359459                bool negative = x.SignValue < 0;
 59359460                if (negative)
 683461                {
 683462                    x = x.Abs();
 683463                }
 59359464                int qLen = q.BitLength;
 59359465                if (r.SignValue > 0)
 45726466                {
 45726467                    BigInteger qMod = BigInteger.One.ShiftLeft(qLen);
 45726468                    bool rIsOne = r.Equals(BigInteger.One);
 109990469                    while (x.BitLength > (qLen + 1))
 64264470                    {
 64264471                        BigInteger u = x.ShiftRight(qLen);
 64264472                        BigInteger v = x.Remainder(qMod);
 64264473                        if (!rIsOne)
 38659474                        {
 38659475                            u = u.Multiply(r);
 38659476                        }
 64264477                        x = u.Add(v);
 64264478                    }
 45726479                }
 480                else
 13633481                {
 13633482                    int d = ((qLen - 1) & 31) + 1;
 13633483                    BigInteger mu = r.Negate();
 13633484                    BigInteger u = mu.Multiply(x.ShiftRight(qLen - d));
 13633485                    BigInteger quot = u.ShiftRight(qLen + d);
 13633486                    BigInteger v = quot.Multiply(q);
 13633487                    BigInteger bk1 = BigInteger.One.ShiftLeft(qLen + d);
 13633488                    v = v.Remainder(bk1);
 13633489                    x = x.Remainder(bk1);
 13633490                    x = x.Subtract(v);
 13633491                    if (x.SignValue < 0)
 0492                    {
 0493                        x = x.Add(bk1);
 0494                    }
 13633495                }
 67022496                while (x.CompareTo(q) >= 0)
 7663497                {
 7663498                    x = x.Subtract(q);
 7663499                }
 59359500                if (negative && x.SignValue != 0)
 683501                {
 683502                    x = q.Subtract(x);
 683503                }
 59359504            }
 59359505            return x;
 59359506        }
 507
 508        protected virtual BigInteger ModSubtract(BigInteger x1, BigInteger x2)
 20547509        {
 20547510            BigInteger x3 = x1.Subtract(x2);
 20547511            if (x3.SignValue < 0)
 10248512            {
 10248513                x3 = x3.Add(q);
 10248514            }
 20547515            return x3;
 20547516        }
 517
 518        public override bool Equals(
 519            object obj)
 0520        {
 0521            if (obj == this)
 0522                return true;
 523
 0524            FpFieldElement other = obj as FpFieldElement;
 525
 0526            if (other == null)
 0527                return false;
 528
 0529            return Equals(other);
 0530        }
 531
 532        public virtual bool Equals(
 533            FpFieldElement other)
 0534        {
 0535            return q.Equals(other.q) && base.Equals(other);
 0536        }
 537
 538        public override int GetHashCode()
 0539        {
 0540            return q.GetHashCode() ^ base.GetHashCode();
 0541        }
 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         */
 643        public F2mFieldElement(
 644            int      m,
 645            int      k1,
 646            int      k2,
 647            int      k3,
 648            BigInteger  x)
 649        {
 650            if (x == null || x.SignValue < 0 || x.BitLength > m)
 651                throw new ArgumentException("value invalid in F2m field element", "x");
 652
 653            if ((k2 == 0) && (k3 == 0))
 654            {
 655                this.representation = Tpb;
 656                this.ks = new int[] { k1 };
 657            }
 658            else
 659            {
 660                if (k2 >= k3)
 661                    throw new ArgumentException("k2 must be smaller than k3");
 662                if (k2 <= 0)
 663                    throw new ArgumentException("k2 must be larger than 0");
 664
 665                this.representation = Ppb;
 666                this.ks = new int[] { k1, k2, k3 };
 667            }
 668
 669            this.m = m;
 670            this.x = new LongArray(x);
 671        }
 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)
 686            : this(m, k, 0, 0, x)
 687        {
 688            // Set k1 to k, and set k2 and k3 to 0
 689        }
 690
 691        internal F2mFieldElement(int m, int[] ks, LongArray x)
 692        {
 693            this.m = m;
 694            this.representation = (ks.Length == 1) ? Tpb : Ppb;
 695            this.ks = ks;
 696            this.x = x;
 697        }
 698
 699        public override int BitLength
 700        {
 701            get { return x.Degree(); }
 702        }
 703
 704        public override bool IsOne
 705        {
 706            get { return x.IsOne(); }
 707        }
 708
 709        public override bool IsZero
 710        {
 711            get { return x.IsZero(); }
 712        }
 713
 714        public override bool TestBitZero()
 715        {
 716            return x.TestBitZero();
 717        }
 718
 719        public override BigInteger ToBigInteger()
 720        {
 721            return x.ToBigInteger();
 722        }
 723
 724        public override string FieldName
 725        {
 726            get { return "F2m"; }
 727        }
 728
 729        public override int FieldSize
 730        {
 731            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)
 748        {
 749            if (!(a is F2mFieldElement) || !(b is F2mFieldElement))
 750            {
 751                throw new ArgumentException("Field elements are not "
 752                    + "both instances of F2mFieldElement");
 753            }
 754
 755            F2mFieldElement aF2m = (F2mFieldElement)a;
 756            F2mFieldElement bF2m = (F2mFieldElement)b;
 757
 758            if (aF2m.representation != bF2m.representation)
 759            {
 760                // Should never occur
 761                throw new ArgumentException("One of the F2m field elements has incorrect representation");
 762            }
 763
 764            if ((aF2m.m != bF2m.m) || !Arrays.AreEqual(aF2m.ks, bF2m.ks))
 765            {
 766                throw new ArgumentException("Field elements are not elements of the same field F2m");
 767            }
 768        }
 769
 770        public override ECFieldElement Add(
 771            ECFieldElement b)
 772        {
 773            // No check performed here for performance reasons. Instead the
 774            // elements involved are checked in ECPoint.F2m
 775            // checkFieldElements(this, b);
 776            LongArray iarrClone = this.x.Copy();
 777            F2mFieldElement bF2m = (F2mFieldElement)b;
 778            iarrClone.AddShiftedByWords(bF2m.x, 0);
 779            return new F2mFieldElement(m, ks, iarrClone);
 780        }
 781
 782        public override ECFieldElement AddOne()
 783        {
 784            return new F2mFieldElement(m, ks, x.AddOne());
 785        }
 786
 787        public override ECFieldElement Subtract(
 788            ECFieldElement b)
 789        {
 790            // Addition and subtraction are the same in F2m
 791            return Add(b);
 792        }
 793
 794        public override ECFieldElement Multiply(
 795            ECFieldElement b)
 796        {
 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);
 804            return new F2mFieldElement(m, ks, x.ModMultiply(((F2mFieldElement)b).x, m, ks));
 805        }
 806
 807        public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
 808        {
 809            return MultiplyPlusProduct(b, x, y);
 810        }
 811
 812        public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
 813        {
 814            LongArray ax = this.x, bx = ((F2mFieldElement)b).x, xx = ((F2mFieldElement)x).x, yx = ((F2mFieldElement)y).x
 815
 816            LongArray ab = ax.Multiply(bx, m, ks);
 817            LongArray xy = xx.Multiply(yx, m, ks);
 818
 819            if (ab == ax || ab == bx)
 820            {
 821                ab = (LongArray)ab.Copy();
 822            }
 823
 824            ab.AddShiftedByWords(xy, 0);
 825            ab.Reduce(m, ks);
 826
 827            return new F2mFieldElement(m, ks, ab);
 828        }
 829
 830        public override ECFieldElement Divide(
 831            ECFieldElement b)
 832        {
 833            // There may be more efficient implementations
 834            ECFieldElement bInv = b.Invert();
 835            return Multiply(bInv);
 836        }
 837
 838        public override ECFieldElement Negate()
 839        {
 840            // -x == x holds for all x in F2m
 841            return this;
 842        }
 843
 844        public override ECFieldElement Square()
 845        {
 846            return new F2mFieldElement(m, ks, x.ModSquare(m, ks));
 847        }
 848
 849        public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y)
 850        {
 851            return SquarePlusProduct(x, y);
 852        }
 853
 854        public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y)
 855        {
 856            LongArray ax = this.x, xx = ((F2mFieldElement)x).x, yx = ((F2mFieldElement)y).x;
 857
 858            LongArray aa = ax.Square(m, ks);
 859            LongArray xy = xx.Multiply(yx, m, ks);
 860
 861            if (aa == ax)
 862            {
 863                aa = (LongArray)aa.Copy();
 864            }
 865
 866            aa.AddShiftedByWords(xy, 0);
 867            aa.Reduce(m, ks);
 868
 869            return new F2mFieldElement(m, ks, aa);
 870        }
 871
 872        public override ECFieldElement SquarePow(int pow)
 873        {
 874            return pow < 1 ? this : new F2mFieldElement(m, ks, x.ModSquareN(pow, m, ks));
 875        }
 876
 877        public override ECFieldElement Invert()
 878        {
 879            return new F2mFieldElement(this.m, this.ks, this.x.ModInverse(m, ks));
 880        }
 881
 882        public override ECFieldElement Sqrt()
 883        {
 884            return (x.IsZero() || x.IsOne()) ? this : SquarePow(m - 1);
 885        }
 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        {
 897            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        {
 906            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        {
 919            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        {
 930            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        {
 941            get { return this.ks.Length >= 3 ? this.ks[2] : 0; }
 942        }
 943
 944        public override bool Equals(
 945            object obj)
 946        {
 947            if (obj == this)
 948                return true;
 949
 950            F2mFieldElement other = obj as F2mFieldElement;
 951
 952            if (other == null)
 953                return false;
 954
 955            return Equals(other);
 956        }
 957
 958        public virtual bool Equals(
 959            F2mFieldElement other)
 960        {
 961            return ((this.m == other.m)
 962                && (this.representation == other.representation)
 963                && Arrays.AreEqual(this.ks, other.ks)
 964                && (this.x.Equals(other.x)));
 965        }
 966
 967        public override int GetHashCode()
 968        {
 969            return x.GetHashCode() ^ m ^ Arrays.GetHashCode(ks);
 970        }
 971    }
 972}

Methods/Properties

CalculateResidue(Renci.SshNet.Security.Org.BouncyCastle.Math.BigInteger)
.ctor(Renci.SshNet.Security.Org.BouncyCastle.Math.BigInteger,Renci.SshNet.Security.Org.BouncyCastle.Math.BigInteger)
.ctor(Renci.SshNet.Security.Org.BouncyCastle.Math.BigInteger,Renci.SshNet.Security.Org.BouncyCastle.Math.BigInteger,Renci.SshNet.Security.Org.BouncyCastle.Math.BigInteger)
ToBigInteger()
get_FieldName()
get_FieldSize()
get_Q()
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)
Invert()
Sqrt()
CheckSqrt(Renci.SshNet.Security.Org.BouncyCastle.Math.EC.ECFieldElement)
LucasSequence(Renci.SshNet.Security.Org.BouncyCastle.Math.BigInteger,Renci.SshNet.Security.Org.BouncyCastle.Math.BigInteger,Renci.SshNet.Security.Org.BouncyCastle.Math.BigInteger)
ModAdd(Renci.SshNet.Security.Org.BouncyCastle.Math.BigInteger,Renci.SshNet.Security.Org.BouncyCastle.Math.BigInteger)
ModDouble(Renci.SshNet.Security.Org.BouncyCastle.Math.BigInteger)
ModHalf(Renci.SshNet.Security.Org.BouncyCastle.Math.BigInteger)
ModHalfAbs(Renci.SshNet.Security.Org.BouncyCastle.Math.BigInteger)
ModInverse(Renci.SshNet.Security.Org.BouncyCastle.Math.BigInteger)
ModMult(Renci.SshNet.Security.Org.BouncyCastle.Math.BigInteger,Renci.SshNet.Security.Org.BouncyCastle.Math.BigInteger)
ModReduce(Renci.SshNet.Security.Org.BouncyCastle.Math.BigInteger)
ModSubtract(Renci.SshNet.Security.Org.BouncyCastle.Math.BigInteger,Renci.SshNet.Security.Org.BouncyCastle.Math.BigInteger)
Equals(System.Object)
Equals(Renci.SshNet.Security.Org.BouncyCastle.Math.EC.FpFieldElement)
GetHashCode()