diff --git a/crypto/src/crypto/tls/Certificate.cs b/crypto/src/crypto/tls/Certificate.cs
index 95050abcd..12bfa9214 100644
--- a/crypto/src/crypto/tls/Certificate.cs
+++ b/crypto/src/crypto/tls/Certificate.cs
@@ -12,14 +12,14 @@ namespace Org.BouncyCastle.Crypto.Tls
* Parsing and encoding of a <i>Certificate</i> struct from RFC 4346.
* <p/>
* <pre>
- * opaque ASN.1Cert<2^24-1>;
+ * opaque ASN.1Cert<2^24-1>;
*
* struct {
- * ASN.1Cert certificate_list<0..2^24-1>;
+ * ASN.1Cert certificate_list<0..2^24-1>;
* } Certificate;
* </pre>
*
- * @see org.bouncycastle.asn1.x509.Certificate
+ * @see Org.BouncyCastle.Asn1.X509.X509CertificateStructure
*/
public class Certificate
{
diff --git a/crypto/src/crypto/tls/CertificateRequest.cs b/crypto/src/crypto/tls/CertificateRequest.cs
index db72a0fc1..8ab265513 100644
--- a/crypto/src/crypto/tls/CertificateRequest.cs
+++ b/crypto/src/crypto/tls/CertificateRequest.cs
@@ -13,8 +13,8 @@ namespace Org.BouncyCastle.Crypto.Tls
* <p/>
* <pre>
* struct {
- * ClientCertificateType certificate_types<1..2^8-1>;
- * DistinguishedName certificate_authorities<3..2^16-1>;
+ * ClientCertificateType certificate_types<1..2^8-1>;
+ * DistinguishedName certificate_authorities<3..2^16-1>
* } CertificateRequest;
* </pre>
*
diff --git a/crypto/src/math/ec/ECCurve.cs b/crypto/src/math/ec/ECCurve.cs
index 67c6097c0..ab98af8f1 100644
--- a/crypto/src/math/ec/ECCurve.cs
+++ b/crypto/src/math/ec/ECCurve.cs
@@ -114,12 +114,13 @@ namespace Org.BouncyCastle.Math.EC
*/
public class FpCurve : ECCurve
{
- private readonly BigInteger q;
+ private readonly BigInteger q, r;
private readonly FpPoint infinity;
public FpCurve(BigInteger q, BigInteger a, BigInteger b)
{
this.q = q;
+ this.r = FpFieldElement.CalculateResidue(q);
this.a = FromBigInteger(a);
this.b = FromBigInteger(b);
this.infinity = new FpPoint(this, null, null);
@@ -142,7 +143,7 @@ namespace Org.BouncyCastle.Math.EC
public override ECFieldElement FromBigInteger(BigInteger x)
{
- return new FpFieldElement(this.q, x);
+ return new FpFieldElement(this.q, this.r, x);
}
public override ECPoint CreatePoint(
diff --git a/crypto/src/math/ec/ECFieldElement.cs b/crypto/src/math/ec/ECFieldElement.cs
index 1205cdbcb..180f97fd5 100644
--- a/crypto/src/math/ec/ECFieldElement.cs
+++ b/crypto/src/math/ec/ECFieldElement.cs
@@ -5,49 +5,69 @@ using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Math.EC
{
- public abstract class ECFieldElement
- {
- public abstract BigInteger ToBigInteger();
- public abstract string FieldName { get; }
- public abstract int FieldSize { get; }
- public abstract ECFieldElement Add(ECFieldElement b);
- public abstract ECFieldElement Subtract(ECFieldElement b);
- public abstract ECFieldElement Multiply(ECFieldElement b);
- public abstract ECFieldElement Divide(ECFieldElement b);
- public abstract ECFieldElement Negate();
- public abstract ECFieldElement Square();
- public abstract ECFieldElement Invert();
- public abstract ECFieldElement Sqrt();
-
- public override bool Equals(
- object obj)
- {
- if (obj == this)
- return true;
-
- ECFieldElement other = obj as ECFieldElement;
-
- if (other == null)
- return false;
-
- return Equals(other);
- }
-
- protected virtual bool Equals(
- ECFieldElement other)
- {
- return ToBigInteger().Equals(other.ToBigInteger());
- }
-
- public override int GetHashCode()
- {
- return ToBigInteger().GetHashCode();
- }
-
- public override string ToString()
- {
- return this.ToBigInteger().ToString(2);
- }
+ public abstract class ECFieldElement
+ {
+ public abstract BigInteger ToBigInteger();
+ public abstract string FieldName { get; }
+ public abstract int FieldSize { get; }
+ public abstract ECFieldElement Add(ECFieldElement b);
+ public abstract ECFieldElement Subtract(ECFieldElement b);
+ public abstract ECFieldElement Multiply(ECFieldElement b);
+ public abstract ECFieldElement Divide(ECFieldElement b);
+ public abstract ECFieldElement Negate();
+ public abstract ECFieldElement Square();
+ public abstract ECFieldElement Invert();
+ public abstract ECFieldElement Sqrt();
+
+ public virtual int BitLength
+ {
+ get { return ToBigInteger().BitLength; }
+ }
+
+ public virtual bool IsOne
+ {
+ get { return BitLength == 1; }
+ }
+
+ public virtual bool IsZero
+ {
+ get { return 0 == ToBigInteger().SignValue; }
+ }
+
+ public virtual bool TestBitZero()
+ {
+ return ToBigInteger().TestBit(0);
+ }
+
+ public override bool Equals(
+ object obj)
+ {
+ if (obj == this)
+ return true;
+
+ ECFieldElement other = obj as ECFieldElement;
+
+ if (other == null)
+ return false;
+
+ return Equals(other);
+ }
+
+ protected virtual bool Equals(
+ ECFieldElement other)
+ {
+ return ToBigInteger().Equals(other.ToBigInteger());
+ }
+
+ public override int GetHashCode()
+ {
+ return ToBigInteger().GetHashCode();
+ }
+
+ public override string ToString()
+ {
+ return this.ToBigInteger().ToString(16);
+ }
public virtual byte[] GetEncoded()
{
@@ -55,320 +75,321 @@ namespace Org.BouncyCastle.Math.EC
}
}
- public class FpFieldElement
- : ECFieldElement
- {
- private readonly BigInteger q, x;
-
- public FpFieldElement(
- BigInteger q,
- BigInteger x)
- {
- if (x.CompareTo(q) >= 0)
- throw new ArgumentException("x value too large in field element");
-
- this.q = q;
- this.x = x;
- }
-
- public override BigInteger ToBigInteger()
- {
- return x;
- }
-
- /**
- * return the field name for this field.
- *
- * @return the string "Fp".
- */
- public override string FieldName
- {
- get { return "Fp"; }
- }
-
- public override int FieldSize
- {
- get { return q.BitLength; }
- }
-
- public BigInteger Q
- {
- get { return q; }
- }
-
- public override ECFieldElement Add(
- ECFieldElement b)
- {
- return new FpFieldElement(q, x.Add(b.ToBigInteger()).Mod(q));
- }
-
- public override ECFieldElement Subtract(
- ECFieldElement b)
- {
- return new FpFieldElement(q, x.Subtract(b.ToBigInteger()).Mod(q));
- }
-
- public override ECFieldElement Multiply(
- ECFieldElement b)
- {
- return new FpFieldElement(q, x.Multiply(b.ToBigInteger()).Mod(q));
- }
-
- public override ECFieldElement Divide(
- ECFieldElement b)
- {
- return new FpFieldElement(q, x.Multiply(b.ToBigInteger().ModInverse(q)).Mod(q));
- }
-
- public override ECFieldElement Negate()
- {
- return new FpFieldElement(q, x.Negate().Mod(q));
- }
-
- public override ECFieldElement Square()
- {
- return new FpFieldElement(q, x.Multiply(x).Mod(q));
- }
-
- public override ECFieldElement Invert()
- {
- return new FpFieldElement(q, x.ModInverse(q));
- }
-
- // D.1.4 91
- /**
- * return a sqrt root - the routine verifies that the calculation
- * returns the right value - if none exists it returns null.
- */
- public override ECFieldElement Sqrt()
- {
- if (!q.TestBit(0))
- throw Platform.CreateNotImplementedException("even value of q");
-
- // p mod 4 == 3
- if (q.TestBit(1))
- {
- // TODO Can this be optimised (inline the Square?)
- // z = g^(u+1) + p, p = 4u + 3
- ECFieldElement z = new FpFieldElement(q, x.ModPow(q.ShiftRight(2).Add(BigInteger.One), q));
-
- return this.Equals(z.Square()) ? z : null;
- }
-
- // p mod 4 == 1
- BigInteger qMinusOne = q.Subtract(BigInteger.One);
-
- BigInteger legendreExponent = qMinusOne.ShiftRight(1);
- if (!(x.ModPow(legendreExponent, q).Equals(BigInteger.One)))
- return null;
-
- BigInteger u = qMinusOne.ShiftRight(2);
- BigInteger k = u.ShiftLeft(1).Add(BigInteger.One);
-
- BigInteger Q = this.x;
- BigInteger fourQ = Q.ShiftLeft(2).Mod(q);
-
- BigInteger U, V;
- do
- {
- Random rand = new Random();
- BigInteger P;
- do
- {
- P = new BigInteger(q.BitLength, rand);
- }
- while (P.CompareTo(q) >= 0
- || !(P.Multiply(P).Subtract(fourQ).ModPow(legendreExponent, q).Equals(qMinusOne)));
-
- BigInteger[] result = fastLucasSequence(q, P, Q, k);
- U = result[0];
- V = result[1];
-
- if (V.Multiply(V).Mod(q).Equals(fourQ))
- {
- // Integer division by 2, mod q
- if (V.TestBit(0))
- {
- V = V.Add(q);
- }
-
- V = V.ShiftRight(1);
-
- Debug.Assert(V.Multiply(V).Mod(q).Equals(x));
-
- return new FpFieldElement(q, V);
- }
- }
- while (U.Equals(BigInteger.One) || U.Equals(qMinusOne));
-
- return null;
-
-
-// BigInteger qMinusOne = q.Subtract(BigInteger.One);
-//
-// BigInteger legendreExponent = qMinusOne.ShiftRight(1);
-// if (!(x.ModPow(legendreExponent, q).Equals(BigInteger.One)))
-// return null;
-//
-// Random rand = new Random();
-// BigInteger fourX = x.ShiftLeft(2);
-//
-// BigInteger r;
-// do
-// {
-// r = new BigInteger(q.BitLength, rand);
-// }
-// while (r.CompareTo(q) >= 0
-// || !(r.Multiply(r).Subtract(fourX).ModPow(legendreExponent, q).Equals(qMinusOne)));
-//
-// BigInteger n1 = qMinusOne.ShiftRight(2);
-// BigInteger n2 = n1.Add(BigInteger.One);
-//
-// BigInteger wOne = WOne(r, x, q);
-// BigInteger wSum = W(n1, wOne, q).Add(W(n2, wOne, q)).Mod(q);
-// BigInteger twoR = r.ShiftLeft(1);
-//
-// BigInteger root = twoR.ModPow(q.Subtract(BigInteger.Two), q)
-// .Multiply(x).Mod(q)
-// .Multiply(wSum).Mod(q);
-//
-// return new FpFieldElement(q, root);
- }
+ public class FpFieldElement
+ : ECFieldElement
+ {
+ private readonly BigInteger q, r, x;
-// private static BigInteger W(BigInteger n, BigInteger wOne, BigInteger p)
-// {
-// if (n.Equals(BigInteger.One))
-// return wOne;
-//
-// bool isEven = !n.TestBit(0);
-// n = n.ShiftRight(1);
-// if (isEven)
-// {
-// BigInteger w = W(n, wOne, p);
-// return w.Multiply(w).Subtract(BigInteger.Two).Mod(p);
-// }
-// BigInteger w1 = W(n.Add(BigInteger.One), wOne, p);
-// BigInteger w2 = W(n, wOne, p);
-// return w1.Multiply(w2).Subtract(wOne).Mod(p);
-// }
-//
-// private BigInteger WOne(BigInteger r, BigInteger x, BigInteger p)
-// {
-// return r.Multiply(r).Multiply(x.ModPow(q.Subtract(BigInteger.Two), q)).Subtract(BigInteger.Two).Mod(p);
-// }
+ internal static BigInteger CalculateResidue(BigInteger p)
+ {
+ int bitLength = p.BitLength;
+ if (bitLength > 128)
+ {
+ BigInteger firstWord = p.ShiftRight(bitLength - 64);
+ if (firstWord.LongValue == -1L)
+ {
+ return BigInteger.One.ShiftLeft(bitLength).Subtract(p);
+ }
+ }
+ return null;
+ }
- private static BigInteger[] fastLucasSequence(
- BigInteger p,
- BigInteger P,
- BigInteger Q,
- BigInteger k)
- {
- // TODO Research and apply "common-multiplicand multiplication here"
-
- int n = k.BitLength;
- int s = k.GetLowestSetBit();
-
- Debug.Assert(k.TestBit(s));
-
- BigInteger Uh = BigInteger.One;
- BigInteger Vl = BigInteger.Two;
- BigInteger Vh = P;
- BigInteger Ql = BigInteger.One;
- BigInteger Qh = BigInteger.One;
-
- for (int j = n - 1; j >= s + 1; --j)
- {
- Ql = Ql.Multiply(Qh).Mod(p);
-
- if (k.TestBit(j))
- {
- Qh = Ql.Multiply(Q).Mod(p);
- Uh = Uh.Multiply(Vh).Mod(p);
- Vl = Vh.Multiply(Vl).Subtract(P.Multiply(Ql)).Mod(p);
- Vh = Vh.Multiply(Vh).Subtract(Qh.ShiftLeft(1)).Mod(p);
- }
- else
- {
- Qh = Ql;
- Uh = Uh.Multiply(Vl).Subtract(Ql).Mod(p);
- Vh = Vh.Multiply(Vl).Subtract(P.Multiply(Ql)).Mod(p);
- Vl = Vl.Multiply(Vl).Subtract(Ql.ShiftLeft(1)).Mod(p);
- }
- }
-
- Ql = Ql.Multiply(Qh).Mod(p);
- Qh = Ql.Multiply(Q).Mod(p);
- Uh = Uh.Multiply(Vl).Subtract(Ql).Mod(p);
- Vl = Vh.Multiply(Vl).Subtract(P.Multiply(Ql)).Mod(p);
- Ql = Ql.Multiply(Qh).Mod(p);
-
- for (int j = 1; j <= s; ++j)
- {
- Uh = Uh.Multiply(Vl).Mod(p);
- Vl = Vl.Multiply(Vl).Subtract(Ql.ShiftLeft(1)).Mod(p);
- Ql = Ql.Multiply(Ql).Mod(p);
- }
-
- return new BigInteger[]{ Uh, Vl };
- }
-
-// private static BigInteger[] verifyLucasSequence(
-// BigInteger p,
-// BigInteger P,
-// BigInteger Q,
-// BigInteger k)
-// {
-// BigInteger[] actual = fastLucasSequence(p, P, Q, k);
-// BigInteger[] plus1 = fastLucasSequence(p, P, Q, k.Add(BigInteger.One));
-// BigInteger[] plus2 = fastLucasSequence(p, P, Q, k.Add(BigInteger.Two));
-//
-// BigInteger[] check = stepLucasSequence(p, P, Q, actual, plus1);
-//
-// Debug.Assert(check[0].Equals(plus2[0]));
-// Debug.Assert(check[1].Equals(plus2[1]));
-//
-// return actual;
-// }
-//
-// private static BigInteger[] stepLucasSequence(
-// BigInteger p,
-// BigInteger P,
-// BigInteger Q,
-// BigInteger[] backTwo,
-// BigInteger[] backOne)
-// {
-// return new BigInteger[]
-// {
-// P.Multiply(backOne[0]).Subtract(Q.Multiply(backTwo[0])).Mod(p),
-// P.Multiply(backOne[1]).Subtract(Q.Multiply(backTwo[1])).Mod(p)
-// };
-// }
+ [Obsolete("Use ECCurve.FromBigInteger to construct field elements")]
+ public FpFieldElement(BigInteger q, BigInteger x)
+ : this(q, CalculateResidue(q), x)
+ {
+ }
+
+ internal FpFieldElement(BigInteger q, BigInteger r, BigInteger x)
+ {
+ if (x == null || x.SignValue < 0 || x.CompareTo(q) >= 0)
+ throw new ArgumentException("value invalid in Fp field element", "x");
+
+ this.q = q;
+ this.r = r;
+ this.x = x;
+ }
+
+ public override BigInteger ToBigInteger()
+ {
+ return x;
+ }
+
+ /**
+ * return the field name for this field.
+ *
+ * @return the string "Fp".
+ */
+ public override string FieldName
+ {
+ get { return "Fp"; }
+ }
+
+ public override int FieldSize
+ {
+ get { return q.BitLength; }
+ }
+
+ public BigInteger Q
+ {
+ get { return q; }
+ }
- public override bool Equals(
- object obj)
- {
- if (obj == this)
- return true;
+ public override ECFieldElement Add(
+ ECFieldElement b)
+ {
+ return new FpFieldElement(q, r, ModAdd(x, b.ToBigInteger()));
+ }
+
+ public override ECFieldElement Subtract(
+ ECFieldElement b)
+ {
+ BigInteger x2 = b.ToBigInteger();
+ BigInteger x3 = x.Subtract(x2);
+ if (x3.SignValue < 0)
+ {
+ x3 = x3.Add(q);
+ }
+ return new FpFieldElement(q, r, x3);
+ }
+
+ public override ECFieldElement Multiply(
+ ECFieldElement b)
+ {
+ return new FpFieldElement(q, r, ModMult(x, b.ToBigInteger()));
+ }
+
+ public override ECFieldElement Divide(
+ ECFieldElement b)
+ {
+ return new FpFieldElement(q, r, ModMult(x, b.ToBigInteger().ModInverse(q)));
+ }
+
+ public override ECFieldElement Negate()
+ {
+ return x.SignValue == 0 ? this : new FpFieldElement(q, r, q.Subtract(x));
+ }
- FpFieldElement other = obj as FpFieldElement;
+ public override ECFieldElement Square()
+ {
+ return new FpFieldElement(q, r, ModMult(x, x));
+ }
- if (other == null)
- return false;
+ public override ECFieldElement Invert()
+ {
+ // TODO Modular inversion can be faster for a (Generalized) Mersenne Prime.
+ return new FpFieldElement(q, r, x.ModInverse(q));
+ }
- return Equals(other);
- }
+ // D.1.4 91
+ /**
+ * return a sqrt root - the routine verifies that the calculation
+ * returns the right value - if none exists it returns null.
+ */
+ public override ECFieldElement Sqrt()
+ {
+ if (!q.TestBit(0))
+ throw Platform.CreateNotImplementedException("even value of q");
+
+ // p mod 4 == 3
+ if (q.TestBit(1))
+ {
+ // TODO Can this be optimised (inline the Square?)
+ // z = g^(u+1) + p, p = 4u + 3
+ ECFieldElement z = new FpFieldElement(q, r, x.ModPow(q.ShiftRight(2).Add(BigInteger.One), q));
+
+ return z.Square().Equals(this) ? z : null;
+ }
+
+ // p mod 4 == 1
+ BigInteger qMinusOne = q.Subtract(BigInteger.One);
+
+ BigInteger legendreExponent = qMinusOne.ShiftRight(1);
+ if (!(x.ModPow(legendreExponent, q).Equals(BigInteger.One)))
+ return null;
+
+ BigInteger u = qMinusOne.ShiftRight(2);
+ BigInteger k = u.ShiftLeft(1).Add(BigInteger.One);
+
+ BigInteger X = this.x;
+ BigInteger fourX = ModDouble(ModDouble(X)); ;
+
+ BigInteger U, V;
+ Random rand = new Random();
+ do
+ {
+ BigInteger P;
+ do
+ {
+ P = new BigInteger(q.BitLength, rand);
+ }
+ while (P.CompareTo(q) >= 0
+ || !(ModMult(P, P).Subtract(fourX).ModPow(legendreExponent, q).Equals(qMinusOne)));
+
+ BigInteger[] result = LucasSequence(P, X, k);
+ U = result[0];
+ V = result[1];
+
+ if (ModMult(V, V).Equals(fourX))
+ {
+ // Integer division by 2, mod q
+ if (V.TestBit(0))
+ {
+ V = V.Add(q);
+ }
+
+ V = V.ShiftRight(1);
+
+ Debug.Assert(ModMult(V, V).Equals(X));
+
+ return new FpFieldElement(q, r, V);
+ }
+ }
+ while (U.Equals(BigInteger.One) || U.Equals(qMinusOne));
+
+ return null;
+ }
- protected bool Equals(
- FpFieldElement other)
- {
- return q.Equals(other.q) && base.Equals(other);
- }
+ private BigInteger[] LucasSequence(
+ BigInteger P,
+ BigInteger Q,
+ BigInteger k)
+ {
+ // TODO Research and apply "common-multiplicand multiplication here"
+
+ int n = k.BitLength;
+ int s = k.GetLowestSetBit();
+
+ Debug.Assert(k.TestBit(s));
+
+ BigInteger Uh = BigInteger.One;
+ BigInteger Vl = BigInteger.Two;
+ BigInteger Vh = P;
+ BigInteger Ql = BigInteger.One;
+ BigInteger Qh = BigInteger.One;
+
+ for (int j = n - 1; j >= s + 1; --j)
+ {
+ Ql = ModMult(Ql, Qh);
+
+ if (k.TestBit(j))
+ {
+ Qh = ModMult(Ql, Q);
+ Uh = ModMult(Uh, Vh);
+ Vl = ModReduce(Vh.Multiply(Vl).Subtract(P.Multiply(Ql)));
+ Vh = ModReduce(Vh.Multiply(Vh).Subtract(Qh.ShiftLeft(1)));
+ }
+ else
+ {
+ Qh = Ql;
+ Uh = ModReduce(Uh.Multiply(Vl).Subtract(Ql));
+ Vh = ModReduce(Vh.Multiply(Vl).Subtract(P.Multiply(Ql)));
+ Vl = ModReduce(Vl.Multiply(Vl).Subtract(Ql.ShiftLeft(1)));
+ }
+ }
+
+ Ql = ModMult(Ql, Qh);
+ Qh = ModMult(Ql, Q);
+ Uh = ModReduce(Uh.Multiply(Vl).Subtract(Ql));
+ Vl = ModReduce(Vh.Multiply(Vl).Subtract(P.Multiply(Ql)));
+ Ql = ModMult(Ql, Qh);
+
+ for (int j = 1; j <= s; ++j)
+ {
+ Uh = ModMult(Uh, Vl);
+ Vl = ModReduce(Vl.Multiply(Vl).Subtract(Ql.ShiftLeft(1)));
+ Ql = ModMult(Ql, Ql);
+ }
+
+ return new BigInteger[] { Uh, Vl };
+ }
- public override int GetHashCode()
- {
- return q.GetHashCode() ^ base.GetHashCode();
- }
- }
+ protected virtual BigInteger ModAdd(BigInteger x1, BigInteger x2)
+ {
+ BigInteger x3 = x1.Add(x2);
+ if (x3.CompareTo(q) >= 0)
+ {
+ x3 = x3.Subtract(q);
+ }
+ return x3;
+ }
+
+ protected virtual BigInteger ModDouble(BigInteger x)
+ {
+ BigInteger _2x = x.ShiftLeft(1);
+ if (_2x.CompareTo(q) >= 0)
+ {
+ _2x = _2x.Subtract(q);
+ }
+ return _2x;
+ }
+
+ protected virtual BigInteger ModMult(BigInteger x1, BigInteger x2)
+ {
+ return ModReduce(x1.Multiply(x2));
+ }
+
+ protected virtual BigInteger ModReduce(BigInteger x)
+ {
+ if (r != null)
+ {
+ bool negative = x.SignValue < 0;
+ if (negative)
+ {
+ x = x.Abs();
+ }
+ int qLen = q.BitLength;
+ while (x.BitLength > (qLen + 1))
+ {
+ BigInteger u = x.ShiftRight(qLen);
+ BigInteger v = x.Subtract(u.ShiftLeft(qLen));
+ if (!r.Equals(BigInteger.One))
+ {
+ u = u.Multiply(r);
+ }
+ x = u.Add(v);
+ }
+ while (x.CompareTo(q) >= 0)
+ {
+ x = x.Subtract(q);
+ }
+ if (negative && x.SignValue != 0)
+ {
+ x = q.Subtract(x);
+ }
+ }
+ else
+ {
+ x = x.Mod(q);
+ }
+ return x;
+ }
+
+ public override bool Equals(
+ object obj)
+ {
+ if (obj == this)
+ return true;
+
+ FpFieldElement other = obj as FpFieldElement;
+
+ if (other == null)
+ return false;
+
+ return Equals(other);
+ }
+
+ protected bool Equals(
+ FpFieldElement other)
+ {
+ return q.Equals(other.q) && base.Equals(other);
+ }
+
+ public override int GetHashCode()
+ {
+ return q.GetHashCode() ^ base.GetHashCode();
+ }
+ }
// /**
// * Class representing the Elements of the finite field
@@ -820,439 +841,439 @@ namespace Org.BouncyCastle.Math.EC
// }
// }
- /**
- * Class representing the Elements of the finite field
- * <code>F<sub>2<sup>m</sup></sub></code> in polynomial basis (PB)
- * representation. Both trinomial (Tpb) and pentanomial (Ppb) polynomial
- * basis representations are supported. Gaussian normal basis (GNB)
- * representation is not supported.
- */
- public class F2mFieldElement
- : ECFieldElement
- {
- /**
- * Indicates gaussian normal basis representation (GNB). Number chosen
- * according to X9.62. GNB is not implemented at present.
- */
- public const int Gnb = 1;
-
- /**
- * Indicates trinomial basis representation (Tpb). Number chosen
- * according to X9.62.
- */
- public const int Tpb = 2;
-
- /**
- * Indicates pentanomial basis representation (Ppb). Number chosen
- * according to X9.62.
- */
- public const int Ppb = 3;
-
- /**
- * Tpb or Ppb.
- */
- private int representation;
-
- /**
- * The exponent <code>m</code> of <code>F<sub>2<sup>m</sup></sub></code>.
- */
- private int m;
-
- /**
- * Tpb: The integer <code>k</code> where <code>x<sup>m</sup> +
- * x<sup>k</sup> + 1</code> represents the reduction polynomial
- * <code>f(z)</code>.<br/>
- * Ppb: 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>.<br/>
- */
- private int k1;
-
- /**
- * Tpb: Always set to <code>0</code><br/>
- * Ppb: 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>.<br/>
- */
- private int k2;
-
- /**
- * Tpb: Always set to <code>0</code><br/>
- * Ppb: 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>.<br/>
- */
- private int k3;
-
- /**
- * The <code>IntArray</code> holding the bits.
- */
- private IntArray x;
-
- /**
- * The number of <code>int</code>s required to hold <code>m</code> bits.
- */
- private readonly int t;
-
- /**
- * 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.SignValue < 0)
- throw new ArgumentException("x value cannot be negative");
-
- this.m = m;
- this.k1 = k1;
- this.k2 = k2;
- this.k3 = k3;
- }
-
- /**
- * Constructor for Tpb.
- * @param m The exponent <code>m</code> of
- * <code>F<sub>2<sup>m</sup></sub></code>.
- * @param k The integer <code>k</code> where <code>x<sup>m</sup> +
- * x<sup>k</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 k,
- BigInteger x)
- : this(m, k, 0, 0, x)
- {
- // Set k1 to k, and set k2 and k3 to 0
- }
-
- 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;
- }
- }
-
- public override BigInteger ToBigInteger()
- {
- return x.ToBigInteger();
- }
-
- public override string FieldName
- {
- get { return "F2m"; }
- }
-
- public override int FieldSize
- {
- get { return m; }
- }
-
- /**
- * Checks, if the ECFieldElements <code>a</code> and <code>b</code>
- * are elements of the same field <code>F<sub>2<sup>m</sup></sub></code>
- * (having the same representation).
- * @param a field element.
- * @param b field element to be compared.
- * @throws ArgumentException if <code>a</code> and <code>b</code>
- * are not elements of the same field
- * <code>F<sub>2<sup>m</sup></sub></code> (having the same
- * representation).
- */
- public static void CheckFieldElements(
- ECFieldElement a,
- ECFieldElement b)
- {
- if (!(a is F2mFieldElement) || !(b is F2mFieldElement))
- {
- throw new ArgumentException("Field elements are not "
- + "both instances of F2mFieldElement");
- }
-
- F2mFieldElement aF2m = (F2mFieldElement)a;
- F2mFieldElement bF2m = (F2mFieldElement)b;
-
- if ((aF2m.m != bF2m.m) || (aF2m.k1 != bF2m.k1)
- || (aF2m.k2 != bF2m.k2) || (aF2m.k3 != bF2m.k3))
- {
- throw new ArgumentException("Field elements are not "
- + "elements of the same field F2m");
- }
-
- if (aF2m.representation != bF2m.representation)
- {
- // Should never occur
- throw new ArgumentException(
- "One of the field "
- + "elements are not elements has incorrect representation");
- }
- }
-
- public override ECFieldElement Add(
- ECFieldElement b)
- {
- // No check performed here for performance reasons. Instead the
- // elements involved are checked in ECPoint.F2m
- // checkFieldElements(this, b);
- IntArray iarrClone = (IntArray) this.x.Copy();
- F2mFieldElement bF2m = (F2mFieldElement) b;
- iarrClone.AddShifted(bF2m.x, 0);
- return new F2mFieldElement(m, k1, k2, k3, iarrClone);
- }
-
- public override ECFieldElement Subtract(
- ECFieldElement b)
- {
- // Addition and subtraction are the same in F2m
- return Add(b);
- }
-
- public override ECFieldElement Multiply(
- ECFieldElement b)
- {
- // Right-to-left comb multiplication in the IntArray
- // Input: Binary polynomials a(z) and b(z) of degree at most m-1
- // Output: c(z) = a(z) * b(z) mod f(z)
-
- // No check performed here for performance reasons. Instead the
- // elements involved are checked in ECPoint.F2m
- // checkFieldElements(this, b);
- F2mFieldElement bF2m = (F2mFieldElement) b;
- IntArray mult = x.Multiply(bF2m.x, m);
- mult.Reduce(m, new int[]{k1, k2, k3});
- return new F2mFieldElement(m, k1, k2, k3, mult);
- }
-
- public override ECFieldElement Divide(
- ECFieldElement b)
- {
- // There may be more efficient implementations
- ECFieldElement bInv = b.Invert();
- return Multiply(bInv);
- }
-
- public override ECFieldElement Negate()
- {
- // -x == x holds for all x in F2m
- return this;
- }
-
- public override ECFieldElement Square()
- {
- IntArray squared = x.Square(m);
- squared.Reduce(m, new int[]{k1, k2, k3});
- return new F2mFieldElement(m, k1, k2, k3, squared);
- }
-
- 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)
+ /**
+ * Class representing the Elements of the finite field
+ * <code>F<sub>2<sup>m</sup></sub></code> in polynomial basis (PB)
+ * representation. Both trinomial (Tpb) and pentanomial (Ppb) polynomial
+ * basis representations are supported. Gaussian normal basis (GNB)
+ * representation is not supported.
+ */
+ public class F2mFieldElement
+ : ECFieldElement
+ {
+ /**
+ * Indicates gaussian normal basis representation (GNB). Number chosen
+ * according to X9.62. GNB is not implemented at present.
+ */
+ public const int Gnb = 1;
+
+ /**
+ * Indicates trinomial basis representation (Tpb). Number chosen
+ * according to X9.62.
+ */
+ public const int Tpb = 2;
+
+ /**
+ * Indicates pentanomial basis representation (Ppb). Number chosen
+ * according to X9.62.
+ */
+ public const int Ppb = 3;
+
+ /**
+ * Tpb or Ppb.
+ */
+ private int representation;
+
+ /**
+ * The exponent <code>m</code> of <code>F<sub>2<sup>m</sup></sub></code>.
+ */
+ private int m;
+
+ /**
+ * Tpb: The integer <code>k</code> where <code>x<sup>m</sup> +
+ * x<sup>k</sup> + 1</code> represents the reduction polynomial
+ * <code>f(z)</code>.<br/>
+ * Ppb: 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>.<br/>
+ */
+ private int k1;
+
+ /**
+ * Tpb: Always set to <code>0</code><br/>
+ * Ppb: 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>.<br/>
+ */
+ private int k2;
+
+ /**
+ * Tpb: Always set to <code>0</code><br/>
+ * Ppb: 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>.<br/>
+ */
+ private int k3;
+
+ /**
+ * The <code>IntArray</code> holding the bits.
+ */
+ private IntArray x;
+
+ /**
+ * The number of <code>int</code>s required to hold <code>m</code> bits.
+ */
+ private readonly int t;
+
+ /**
+ * 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.SignValue < 0)
+ throw new ArgumentException("x value cannot be negative");
+
+ this.m = m;
+ this.k1 = k1;
+ this.k2 = k2;
+ this.k3 = k3;
+ }
+
+ /**
+ * Constructor for Tpb.
+ * @param m The exponent <code>m</code> of
+ * <code>F<sub>2<sup>m</sup></sub></code>.
+ * @param k The integer <code>k</code> where <code>x<sup>m</sup> +
+ * x<sup>k</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 k,
+ BigInteger x)
+ : this(m, k, 0, 0, x)
+ {
+ // Set k1 to k, and set k2 and k3 to 0
+ }
+
+ 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;
+ }
+ }
+
+ public override BigInteger ToBigInteger()
+ {
+ return x.ToBigInteger();
+ }
+
+ public override string FieldName
+ {
+ get { return "F2m"; }
+ }
+
+ public override int FieldSize
+ {
+ get { return m; }
+ }
+
+ /**
+ * Checks, if the ECFieldElements <code>a</code> and <code>b</code>
+ * are elements of the same field <code>F<sub>2<sup>m</sup></sub></code>
+ * (having the same representation).
+ * @param a field element.
+ * @param b field element to be compared.
+ * @throws ArgumentException if <code>a</code> and <code>b</code>
+ * are not elements of the same field
+ * <code>F<sub>2<sup>m</sup></sub></code> (having the same
+ * representation).
+ */
+ public static void CheckFieldElements(
+ ECFieldElement a,
+ ECFieldElement b)
+ {
+ if (!(a is F2mFieldElement) || !(b is F2mFieldElement))
+ {
+ throw new ArgumentException("Field elements are not "
+ + "both instances of F2mFieldElement");
+ }
+
+ F2mFieldElement aF2m = (F2mFieldElement)a;
+ F2mFieldElement bF2m = (F2mFieldElement)b;
+
+ if ((aF2m.m != bF2m.m) || (aF2m.k1 != bF2m.k1)
+ || (aF2m.k2 != bF2m.k2) || (aF2m.k3 != bF2m.k3))
+ {
+ throw new ArgumentException("Field elements are not "
+ + "elements of the same field F2m");
+ }
+
+ if (aF2m.representation != bF2m.representation)
+ {
+ // Should never occur
+ throw new ArgumentException(
+ "One of the field "
+ + "elements are not elements has incorrect representation");
+ }
+ }
+
+ public override ECFieldElement Add(
+ ECFieldElement b)
+ {
+ // No check performed here for performance reasons. Instead the
+ // elements involved are checked in ECPoint.F2m
+ // checkFieldElements(this, b);
+ IntArray iarrClone = (IntArray) this.x.Copy();
+ F2mFieldElement bF2m = (F2mFieldElement) b;
+ iarrClone.AddShifted(bF2m.x, 0);
+ return new F2mFieldElement(m, k1, k2, k3, iarrClone);
+ }
+
+ public override ECFieldElement Subtract(
+ ECFieldElement b)
+ {
+ // Addition and subtraction are the same in F2m
+ return Add(b);
+ }
+
+ public override ECFieldElement Multiply(
+ ECFieldElement b)
+ {
+ // Right-to-left comb multiplication in the IntArray
+ // Input: Binary polynomials a(z) and b(z) of degree at most m-1
+ // Output: c(z) = a(z) * b(z) mod f(z)
+
+ // No check performed here for performance reasons. Instead the
+ // elements involved are checked in ECPoint.F2m
+ // checkFieldElements(this, b);
+ F2mFieldElement bF2m = (F2mFieldElement) b;
+ IntArray mult = x.Multiply(bF2m.x, m);
+ mult.Reduce(m, new int[]{k1, k2, k3});
+ return new F2mFieldElement(m, k1, k2, k3, mult);
+ }
+
+ public override ECFieldElement Divide(
+ ECFieldElement b)
+ {
+ // There may be more efficient implementations
+ ECFieldElement bInv = b.Invert();
+ return Multiply(bInv);
+ }
+
+ public override ECFieldElement Negate()
+ {
+ // -x == x holds for all x in F2m
+ return this;
+ }
+
+ public override ECFieldElement Square()
+ {
+ IntArray squared = x.Square(m);
+ squared.Reduce(m, new int[]{k1, k2, k3});
+ return new F2mFieldElement(m, k1, k2, k3, squared);
+ }
+
+ 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)
+ // 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;
+ {
+ // 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)
- {
+ // If j < 0 then: u(z) <-> v(z), g1(z) <-> g2(z), j := -j
+ if (j < 0)
+ {
IntArray uzCopy = uz;
- uz = vz;
- vz = uzCopy;
+ 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 = 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 override ECFieldElement Sqrt()
- {
- throw new ArithmeticException("Not implemented");
- }
-
- /**
- * @return the representation of the field
- * <code>F<sub>2<sup>m</sup></sub></code>, either of
- * {@link F2mFieldElement.Tpb} (trinomial
- * basis representation) or
- * {@link F2mFieldElement.Ppb} (pentanomial
- * basis representation).
- */
- public int Representation
- {
- get { return this.representation; }
- }
-
- /**
- * @return the degree <code>m</code> of the reduction polynomial
- * <code>f(z)</code>.
- */
- public int M
- {
- get { return this.m; }
- }
-
- /**
- * @return Tpb: The integer <code>k</code> where <code>x<sup>m</sup> +
- * x<sup>k</sup> + 1</code> represents the reduction polynomial
- * <code>f(z)</code>.<br/>
- * Ppb: 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>.<br/>
- */
- public int K1
- {
- get { return this.k1; }
- }
-
- /**
- * @return Tpb: Always returns <code>0</code><br/>
- * Ppb: 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>.<br/>
- */
- public int K2
- {
- get { return this.k2; }
- }
-
- /**
- * @return Tpb: Always set to <code>0</code><br/>
- * Ppb: 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>.<br/>
- */
- public int K3
- {
- get { return this.k3; }
- }
-
- public override bool Equals(
- object obj)
- {
- if (obj == this)
- return true;
-
- F2mFieldElement other = obj as F2mFieldElement;
-
- if (other == null)
- return false;
-
- return Equals(other);
- }
-
- protected bool Equals(
- F2mFieldElement other)
- {
- return m == other.m
- && k1 == other.k1
- && k2 == other.k2
- && k3 == other.k3
- && representation == other.representation
- && base.Equals(other);
- }
-
- public override int GetHashCode()
- {
- return m.GetHashCode()
- ^ k1.GetHashCode()
- ^ k2.GetHashCode()
- ^ k3.GetHashCode()
- ^ representation.GetHashCode()
- ^ base.GetHashCode();
- }
- }
+ IntArray g2zShift = g2z.ShiftLeft(jBit);
+ g1z.AddShifted(g2zShift, jInt);
+ }
+ return new F2mFieldElement(this.m, this.k1, this.k2, this.k3, g2z);
+ }
+
+ public override ECFieldElement Sqrt()
+ {
+ throw new ArithmeticException("Not implemented");
+ }
+
+ /**
+ * @return the representation of the field
+ * <code>F<sub>2<sup>m</sup></sub></code>, either of
+ * {@link F2mFieldElement.Tpb} (trinomial
+ * basis representation) or
+ * {@link F2mFieldElement.Ppb} (pentanomial
+ * basis representation).
+ */
+ public int Representation
+ {
+ get { return this.representation; }
+ }
+
+ /**
+ * @return the degree <code>m</code> of the reduction polynomial
+ * <code>f(z)</code>.
+ */
+ public int M
+ {
+ get { return this.m; }
+ }
+
+ /**
+ * @return Tpb: The integer <code>k</code> where <code>x<sup>m</sup> +
+ * x<sup>k</sup> + 1</code> represents the reduction polynomial
+ * <code>f(z)</code>.<br/>
+ * Ppb: 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>.<br/>
+ */
+ public int K1
+ {
+ get { return this.k1; }
+ }
+
+ /**
+ * @return Tpb: Always returns <code>0</code><br/>
+ * Ppb: 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>.<br/>
+ */
+ public int K2
+ {
+ get { return this.k2; }
+ }
+
+ /**
+ * @return Tpb: Always set to <code>0</code><br/>
+ * Ppb: 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>.<br/>
+ */
+ public int K3
+ {
+ get { return this.k3; }
+ }
+
+ public override bool Equals(
+ object obj)
+ {
+ if (obj == this)
+ return true;
+
+ F2mFieldElement other = obj as F2mFieldElement;
+
+ if (other == null)
+ return false;
+
+ return Equals(other);
+ }
+
+ protected bool Equals(
+ F2mFieldElement other)
+ {
+ return m == other.m
+ && k1 == other.k1
+ && k2 == other.k2
+ && k3 == other.k3
+ && representation == other.representation
+ && base.Equals(other);
+ }
+
+ public override int GetHashCode()
+ {
+ return m.GetHashCode()
+ ^ k1.GetHashCode()
+ ^ k2.GetHashCode()
+ ^ k3.GetHashCode()
+ ^ representation.GetHashCode()
+ ^ base.GetHashCode();
+ }
+ }
}
diff --git a/crypto/src/util/Arrays.cs b/crypto/src/util/Arrays.cs
index 3c083034e..5eab42bd7 100644
--- a/crypto/src/util/Arrays.cs
+++ b/crypto/src/util/Arrays.cs
@@ -3,26 +3,21 @@ using System.Text;
namespace Org.BouncyCastle.Utilities
{
-
/// <summary> General array utilities.</summary>
- public sealed class Arrays
+ public abstract class Arrays
{
- private Arrays()
+ public static bool AreEqual(
+ bool[] a,
+ bool[] b)
{
- }
-
- public static bool AreEqual(
- bool[] a,
- bool[] b)
- {
- if (a == b)
- return true;
+ if (a == b)
+ return true;
- if (a == null || b == null)
- return false;
+ if (a == null || b == null)
+ return false;
return HaveSameContents(a, b);
- }
+ }
public static bool AreEqual(
char[] a,
@@ -44,61 +39,61 @@ namespace Org.BouncyCastle.Utilities
/// <param name="b">Right side.</param>
/// <returns>True if equal.</returns>
public static bool AreEqual(
- byte[] a,
- byte[] b)
- {
- if (a == b)
- return true;
-
- if (a == null || b == null)
- return false;
-
- return HaveSameContents(a, b);
- }
-
- [Obsolete("Use 'AreEqual' method instead")]
- public static bool AreSame(
- byte[] a,
- byte[] b)
- {
- return AreEqual(a, b);
- }
-
- /// <summary>
- /// A constant time equals comparison - does not terminate early if
- /// test will fail.
- /// </summary>
- /// <param name="a">first array</param>
- /// <param name="b">second array</param>
- /// <returns>true if arrays equal, false otherwise.</returns>
- public static bool ConstantTimeAreEqual(
- byte[] a,
- byte[] b)
- {
- int i = a.Length;
- if (i != b.Length)
- return false;
- int cmp = 0;
- while (i != 0)
- {
- --i;
- cmp |= (a[i] ^ b[i]);
- }
- return cmp == 0;
- }
-
- public static bool AreEqual(
- int[] a,
- int[] b)
- {
- if (a == b)
- return true;
-
- if (a == null || b == null)
- return false;
-
- return HaveSameContents(a, b);
- }
+ byte[] a,
+ byte[] b)
+ {
+ if (a == b)
+ return true;
+
+ if (a == null || b == null)
+ return false;
+
+ return HaveSameContents(a, b);
+ }
+
+ [Obsolete("Use 'AreEqual' method instead")]
+ public static bool AreSame(
+ byte[] a,
+ byte[] b)
+ {
+ return AreEqual(a, b);
+ }
+
+ /// <summary>
+ /// A constant time equals comparison - does not terminate early if
+ /// test will fail.
+ /// </summary>
+ /// <param name="a">first array</param>
+ /// <param name="b">second array</param>
+ /// <returns>true if arrays equal, false otherwise.</returns>
+ public static bool ConstantTimeAreEqual(
+ byte[] a,
+ byte[] b)
+ {
+ int i = a.Length;
+ if (i != b.Length)
+ return false;
+ int cmp = 0;
+ while (i != 0)
+ {
+ --i;
+ cmp |= (a[i] ^ b[i]);
+ }
+ return cmp == 0;
+ }
+
+ public static bool AreEqual(
+ int[] a,
+ int[] b)
+ {
+ if (a == b)
+ return true;
+
+ if (a == null || b == null)
+ return false;
+
+ return HaveSameContents(a, b);
+ }
private static bool HaveSameContents(
bool[] a,
@@ -133,95 +128,113 @@ namespace Org.BouncyCastle.Utilities
}
private static bool HaveSameContents(
- byte[] a,
- byte[] b)
- {
- int i = a.Length;
- if (i != b.Length)
- return false;
- while (i != 0)
- {
- --i;
- if (a[i] != b[i])
- return false;
- }
- return true;
- }
-
- private static bool HaveSameContents(
- int[] a,
- int[] b)
- {
- int i = a.Length;
- if (i != b.Length)
- return false;
- while (i != 0)
- {
- --i;
- if (a[i] != b[i])
- return false;
- }
- return true;
- }
+ byte[] a,
+ byte[] b)
+ {
+ int i = a.Length;
+ if (i != b.Length)
+ return false;
+ while (i != 0)
+ {
+ --i;
+ if (a[i] != b[i])
+ return false;
+ }
+ return true;
+ }
+
+ private static bool HaveSameContents(
+ int[] a,
+ int[] b)
+ {
+ int i = a.Length;
+ if (i != b.Length)
+ return false;
+ while (i != 0)
+ {
+ --i;
+ if (a[i] != b[i])
+ return false;
+ }
+ return true;
+ }
public static string ToString(
- object[] a)
- {
- StringBuilder sb = new StringBuilder('[');
- if (a.Length > 0)
- {
- sb.Append(a[0]);
- for (int index = 1; index < a.Length; ++index)
- {
- sb.Append(", ").Append(a[index]);
- }
- }
- sb.Append(']');
- return sb.ToString();
- }
-
- public static int GetHashCode(
- byte[] data)
- {
- if (data == null)
- {
- return 0;
- }
-
- int i = data.Length;
- int hc = i + 1;
-
- while (--i >= 0)
- {
- hc *= 257;
- hc ^= data[i];
- }
-
- return hc;
- }
-
- public static byte[] Clone(
- byte[] data)
- {
- return data == null ? null : (byte[]) data.Clone();
- }
-
- public static int[] Clone(
- int[] data)
- {
- return data == null ? null : (int[]) data.Clone();
- }
-
- public static void Fill(
- byte[] buf,
- byte b)
- {
- int i = buf.Length;
- while (i > 0)
- {
- buf[--i] = b;
- }
- }
+ object[] a)
+ {
+ StringBuilder sb = new StringBuilder('[');
+ if (a.Length > 0)
+ {
+ sb.Append(a[0]);
+ for (int index = 1; index < a.Length; ++index)
+ {
+ sb.Append(", ").Append(a[index]);
+ }
+ }
+ sb.Append(']');
+ return sb.ToString();
+ }
+
+ public static int GetHashCode(byte[] data)
+ {
+ if (data == null)
+ {
+ return 0;
+ }
+
+ int i = data.Length;
+ int hc = i + 1;
+
+ while (--i >= 0)
+ {
+ hc *= 257;
+ hc ^= data[i];
+ }
+
+ return hc;
+ }
+
+ public static int GetHashCode(int[] data)
+ {
+ if (data == null)
+ {
+ return 0;
+ }
+
+ int i = data.Length;
+ int hc = i + 1;
+
+ while (--i >= 0)
+ {
+ hc *= 257;
+ hc ^= data[i];
+ }
+
+ return hc;
+ }
+
+ public static byte[] Clone(
+ byte[] data)
+ {
+ return data == null ? null : (byte[]) data.Clone();
+ }
+
+ public static int[] Clone(
+ int[] data)
+ {
+ return data == null ? null : (int[]) data.Clone();
+ }
+
+ public static void Fill(
+ byte[] buf,
+ byte b)
+ {
+ int i = buf.Length;
+ while (i > 0)
+ {
+ buf[--i] = b;
+ }
+ }
public static byte[] Copy(byte[] data, int off, int len)
{
@@ -229,5 +242,5 @@ namespace Org.BouncyCastle.Utilities
Array.Copy(data, off, result, 0, len);
return result;
}
- }
+ }
}
diff --git a/crypto/src/util/BigIntegers.cs b/crypto/src/util/BigIntegers.cs
index 9e15d2559..f2d0425cc 100644
--- a/crypto/src/util/BigIntegers.cs
+++ b/crypto/src/util/BigIntegers.cs
@@ -8,14 +8,10 @@ namespace Org.BouncyCastle.Utilities
/**
* BigInteger utilities.
*/
- public sealed class BigIntegers
+ public abstract class BigIntegers
{
private const int MaxIterations = 1000;
- private BigIntegers()
- {
- }
-
/**
* Return the passed in value as an unsigned byte array.
*
diff --git a/crypto/src/util/Enums.cs b/crypto/src/util/Enums.cs
index eaf49e1b3..8bd9c4053 100644
--- a/crypto/src/util/Enums.cs
+++ b/crypto/src/util/Enums.cs
@@ -10,12 +10,8 @@ using Org.BouncyCastle.Utilities.Date;
namespace Org.BouncyCastle.Utilities
{
- internal sealed class Enums
+ internal abstract class Enums
{
- private Enums()
- {
- }
-
internal static Enum GetEnumValue(System.Type enumType, string s)
{
if (!enumType.IsEnum)
diff --git a/crypto/src/util/Platform.cs b/crypto/src/util/Platform.cs
index cdfba789e..99d3982ea 100644
--- a/crypto/src/util/Platform.cs
+++ b/crypto/src/util/Platform.cs
@@ -11,22 +11,18 @@ using System.Collections;
namespace Org.BouncyCastle.Utilities
{
- internal sealed class Platform
- {
- private Platform()
- {
- }
-
+ internal abstract class Platform
+ {
#if NETCF_1_0 || NETCF_2_0
- private static string GetNewLine()
- {
- MemoryStream buf = new MemoryStream();
- StreamWriter w = new StreamWriter(buf, Encoding.UTF8);
- w.WriteLine();
- w.Close();
- byte[] bs = buf.ToArray();
+ private static string GetNewLine()
+ {
+ MemoryStream buf = new MemoryStream();
+ StreamWriter w = new StreamWriter(buf, Encoding.UTF8);
+ w.WriteLine();
+ w.Close();
+ byte[] bs = buf.ToArray();
return Encoding.UTF8.GetString(bs, 0, bs.Length);
- }
+ }
#else
private static string GetNewLine()
{
@@ -44,47 +40,47 @@ namespace Org.BouncyCastle.Utilities
}
#if NETCF_1_0 || NETCF_2_0 || SILVERLIGHT
- internal static string GetEnvironmentVariable(
- string variable)
- {
- return null;
- }
+ internal static string GetEnvironmentVariable(
+ string variable)
+ {
+ return null;
+ }
#else
- internal static string GetEnvironmentVariable(
- string variable)
- {
- try
- {
- return Environment.GetEnvironmentVariable(variable);
- }
- catch (System.Security.SecurityException)
- {
- // We don't have the required permission to read this environment variable,
- // which is fine, just act as if it's not set
- return null;
- }
- }
+ internal static string GetEnvironmentVariable(
+ string variable)
+ {
+ try
+ {
+ return Environment.GetEnvironmentVariable(variable);
+ }
+ catch (System.Security.SecurityException)
+ {
+ // We don't have the required permission to read this environment variable,
+ // which is fine, just act as if it's not set
+ return null;
+ }
+ }
#endif
#if NETCF_1_0
- internal static Exception CreateNotImplementedException(
- string message)
- {
- return new Exception("Not implemented: " + message);
- }
+ internal static Exception CreateNotImplementedException(
+ string message)
+ {
+ return new Exception("Not implemented: " + message);
+ }
- internal static bool Equals(
- object a,
- object b)
- {
- return a == b || (a != null && b != null && a.Equals(b));
- }
+ internal static bool Equals(
+ object a,
+ object b)
+ {
+ return a == b || (a != null && b != null && a.Equals(b));
+ }
#else
- internal static Exception CreateNotImplementedException(
- string message)
- {
- return new NotImplementedException(message);
- }
+ internal static Exception CreateNotImplementedException(
+ string message)
+ {
+ return new NotImplementedException(message);
+ }
#endif
#if SILVERLIGHT
@@ -178,5 +174,5 @@ namespace Org.BouncyCastle.Utilities
}
internal static readonly string NewLine = GetNewLine();
- }
+ }
}
diff --git a/crypto/src/util/Strings.cs b/crypto/src/util/Strings.cs
index 96032bdc5..a6080f427 100644
--- a/crypto/src/util/Strings.cs
+++ b/crypto/src/util/Strings.cs
@@ -3,33 +3,29 @@ using System.Text;
namespace Org.BouncyCastle.Utilities
{
- /// <summary> General string utilities.</summary>
- public sealed class Strings
- {
- private Strings()
- {
- }
-
- internal static bool IsOneOf(string s, params string[] candidates)
- {
- foreach (string candidate in candidates)
- {
- if (s == candidate)
- return true;
- }
- return false;
- }
+ /// <summary> General string utilities.</summary>
+ public abstract class Strings
+ {
+ internal static bool IsOneOf(string s, params string[] candidates)
+ {
+ foreach (string candidate in candidates)
+ {
+ if (s == candidate)
+ return true;
+ }
+ return false;
+ }
- public static string FromByteArray(
- byte[] bs)
- {
- char[] cs = new char[bs.Length];
- for (int i = 0; i < cs.Length; ++i)
- {
- cs[i] = Convert.ToChar(bs[i]);
- }
- return new string(cs);
- }
+ public static string FromByteArray(
+ byte[] bs)
+ {
+ char[] cs = new char[bs.Length];
+ for (int i = 0; i < cs.Length; ++i)
+ {
+ cs[i] = Convert.ToChar(bs[i]);
+ }
+ return new string(cs);
+ }
public static byte[] ToByteArray(
char[] cs)
@@ -43,15 +39,15 @@ namespace Org.BouncyCastle.Utilities
}
public static byte[] ToByteArray(
- string s)
- {
- byte[] bs = new byte[s.Length];
- for (int i = 0; i < bs.Length; ++i)
- {
- bs[i] = Convert.ToByte(s[i]);
- }
- return bs;
- }
+ string s)
+ {
+ byte[] bs = new byte[s.Length];
+ for (int i = 0; i < bs.Length; ++i)
+ {
+ bs[i] = Convert.ToByte(s[i]);
+ }
+ return bs;
+ }
public static string FromAsciiByteArray(
byte[] bytes)
@@ -87,10 +83,10 @@ namespace Org.BouncyCastle.Utilities
}
public static string FromUtf8ByteArray(
- byte[] bytes)
- {
- return Encoding.UTF8.GetString(bytes, 0, bytes.Length);
- }
+ byte[] bytes)
+ {
+ return Encoding.UTF8.GetString(bytes, 0, bytes.Length);
+ }
public static byte[] ToUtf8ByteArray(
char[] cs)
@@ -98,10 +94,10 @@ namespace Org.BouncyCastle.Utilities
return Encoding.UTF8.GetBytes(cs);
}
- public static byte[] ToUtf8ByteArray(
- string s)
- {
- return Encoding.UTF8.GetBytes(s);
- }
- }
+ public static byte[] ToUtf8ByteArray(
+ string s)
+ {
+ return Encoding.UTF8.GetBytes(s);
+ }
+ }
}
diff --git a/crypto/src/util/collections/CollectionUtilities.cs b/crypto/src/util/collections/CollectionUtilities.cs
index fd0bdcc7a..18fcb6774 100644
--- a/crypto/src/util/collections/CollectionUtilities.cs
+++ b/crypto/src/util/collections/CollectionUtilities.cs
@@ -4,13 +4,9 @@ using System.Text;
namespace Org.BouncyCastle.Utilities.Collections
{
- public sealed class CollectionUtilities
- {
- private CollectionUtilities()
- {
- }
-
- public static void AddRange(IList to, ICollection range)
+ public abstract class CollectionUtilities
+ {
+ public static void AddRange(IList to, IEnumerable range)
{
foreach (object o in range)
{
@@ -18,17 +14,15 @@ namespace Org.BouncyCastle.Utilities.Collections
}
}
- public static bool CheckElementsAreOfType(
- IEnumerable e,
- Type t)
- {
- foreach (object o in e)
- {
- if (!t.IsInstanceOfType(o))
- return false;
- }
- return true;
- }
+ public static bool CheckElementsAreOfType(IEnumerable e, Type t)
+ {
+ foreach (object o in e)
+ {
+ if (!t.IsInstanceOfType(o))
+ return false;
+ }
+ return true;
+ }
public static IDictionary ReadOnly(IDictionary d)
{
@@ -45,27 +39,26 @@ namespace Org.BouncyCastle.Utilities.Collections
return new UnmodifiableSetProxy(s);
}
- public static string ToString(
- IEnumerable c)
- {
- StringBuilder sb = new StringBuilder("[");
+ public static string ToString(IEnumerable c)
+ {
+ StringBuilder sb = new StringBuilder("[");
- IEnumerator e = c.GetEnumerator();
+ IEnumerator e = c.GetEnumerator();
- if (e.MoveNext())
- {
- sb.Append(e.Current.ToString());
+ if (e.MoveNext())
+ {
+ sb.Append(e.Current.ToString());
- while (e.MoveNext())
- {
- sb.Append(", ");
- sb.Append(e.Current.ToString());
- }
- }
+ while (e.MoveNext())
+ {
+ sb.Append(", ");
+ sb.Append(e.Current.ToString());
+ }
+ }
- sb.Append(']');
+ sb.Append(']');
- return sb.ToString();
- }
- }
+ return sb.ToString();
+ }
+ }
}
|