ECCurve.cs :  » PDF » iTextSharp » Org » BouncyCastle » Math » EC » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » PDF » iTextSharp 
iTextSharp » Org » BouncyCastle » Math » EC » ECCurve.cs
using System;
using System.Collections;

using Org.BouncyCastle.Math.EC.Abc;

namespace Org.BouncyCastle.Math.EC{
  /// <remarks>Base class for an elliptic curve.</remarks>
  public abstract class ECCurve
  {
    internal ECFieldElement a, b;

    public abstract int FieldSize { get; }
    public abstract ECFieldElement FromBigInteger(BigInteger x);
    public abstract ECPoint CreatePoint(BigInteger x, BigInteger y, bool withCompression);
    public abstract ECPoint DecodePoint(byte[] encoded);
    public abstract ECPoint Infinity { get; }

    public ECFieldElement A
    {
      get { return a; }
    }

    public ECFieldElement B
    {
      get { return b; }
    }

    public override bool Equals(
      object obj)
    {
      if (obj == this)
        return true;

      ECCurve other = obj as ECCurve;

      if (other == null)
        return false;

      return Equals(other);
    }

    protected bool Equals(
      ECCurve other)
    {
      return a.Equals(other.a) && b.Equals(other.b);
    }

    public override int GetHashCode()
    {
      return a.GetHashCode() ^ b.GetHashCode();
    }
  }

  public abstract class ECCurveBase : ECCurve
  {
    protected internal ECCurveBase()
    {
    }

    protected internal abstract ECPoint DecompressPoint(int yTilde, BigInteger X1);

    /**
     * Decode a point on this curve from its ASN.1 encoding. The different
     * encodings are taken account of, including point compression for
     * <code>F<sub>p</sub></code> (X9.62 s 4.2.1 pg 17).
     * @return The decoded point.
     */
    public override ECPoint DecodePoint(
      byte[] encoded)
    {
      ECPoint p = null;
      int expectedLength = (FieldSize + 7) / 8;

      switch (encoded[0])
      {
        case 0x00: // infinity
        {
          if (encoded.Length != 1)
            throw new ArgumentException("Incorrect length for infinity encoding", "encoded");

          p = Infinity;
          break;
        }

        case 0x02: // compressed
        case 0x03: // compressed
        {
          if (encoded.Length != (expectedLength + 1))
            throw new ArgumentException("Incorrect length for compressed encoding", "encoded");

          int yTilde = encoded[0] & 1;
          BigInteger X1 = new BigInteger(1, encoded, 1, encoded.Length - 1);

          p = DecompressPoint(yTilde, X1);
          break;
        }

        case 0x04: // uncompressed
        case 0x06: // hybrid
        case 0x07: // hybrid
        {
          if (encoded.Length != (2 * expectedLength + 1))
            throw new ArgumentException("Incorrect length for uncompressed/hybrid encoding", "encoded");

          BigInteger X1 = new BigInteger(1, encoded, 1, expectedLength);
          BigInteger Y1 = new BigInteger(1, encoded, 1 + expectedLength, expectedLength);

          p = CreatePoint(X1, Y1, false);
          break;
        }

        default:
          throw new FormatException("Invalid point encoding " + encoded[0]);
      }

      return p;
    }
  }

  /**
     * Elliptic curve over Fp
     */
    public class FpCurve : ECCurveBase
    {
        private readonly BigInteger q;
    private readonly FpPoint infinity;

    public FpCurve(BigInteger q, BigInteger a, BigInteger b)
        {
            this.q = q;
            this.a = FromBigInteger(a);
            this.b = FromBigInteger(b);
      this.infinity = new FpPoint(this, null, null);
        }

    public BigInteger Q
        {
      get { return q; }
        }

    public override ECPoint Infinity
    {
      get { return infinity; }
    }

    public override int FieldSize
    {
      get { return q.BitLength; }
    }

    public override ECFieldElement FromBigInteger(BigInteger x)
        {
            return new FpFieldElement(this.q, x);
        }

    public override ECPoint CreatePoint(
      BigInteger  X1,
      BigInteger  Y1,
      bool    withCompression)
    {
      // TODO Validation of X1, Y1?
      return new FpPoint(
        this,
        FromBigInteger(X1),
        FromBigInteger(Y1),
        withCompression);
    }

    protected internal override ECPoint DecompressPoint(
      int      yTilde,
      BigInteger  X1)
    {
      ECFieldElement x = FromBigInteger(X1);
      ECFieldElement alpha = x.Multiply(x.Square().Add(a)).Add(b);
      ECFieldElement beta = alpha.Sqrt();

      //
      // if we can't find a sqrt we haven't got a point on the
      // curve - run!
      //
      if (beta == null)
        throw new ArithmeticException("Invalid point compression");

      BigInteger betaValue = beta.ToBigInteger();
      int bit0 = betaValue.TestBit(0) ? 1 : 0;

      if (bit0 != yTilde)
      {
        // Use the other root
        beta = FromBigInteger(q.Subtract(betaValue));
      }

      return new FpPoint(this, x, beta, true);
    }

    public override bool Equals(
            object obj)
        {
            if (obj == this)
                return true;

      FpCurve other = obj as FpCurve;

      if (other == null)
                return false;

      return Equals(other);
        }

    protected bool Equals(
      FpCurve other)
    {
      return base.Equals(other) && q.Equals(other.q);
    }

    public override int GetHashCode()
        {
            return base.GetHashCode() ^ q.GetHashCode();
        }
    }

  /**
     * Elliptic curves over F2m. The Weierstrass equation is given by
     * <code>y<sup>2</sup> + xy = x<sup>3</sup> + ax<sup>2</sup> + b</code>.
     */
    public class F2mCurve : ECCurveBase
    {
        /**
         * The exponent <code>m</code> of <code>F<sub>2<sup>m</sup></sub></code>.
         */
        private readonly 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 readonly 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 readonly 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 readonly int k3;

    /**
     * The order of the base point of the curve.
     */
    private readonly BigInteger n;

    /**
     * The cofactor of the curve.
     */
    private readonly BigInteger h;

    /**
     * The point at infinity on this curve.
     */
    private readonly F2mPoint infinity;

    /**
     * The parameter <code>&#956;</code> of the elliptic curve if this is
     * a Koblitz curve.
     */
    private sbyte mu = 0;

    /**
     * The auxiliary values <code>s<sub>0</sub></code> and
     * <code>s<sub>1</sub></code> used for partial modular reduction for
     * Koblitz curves.
     */
    private BigInteger[] si = null;

    /**
     * Constructor for Trinomial Polynomial Basis (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 a The coefficient <code>a</code> in the Weierstrass equation
     * for non-supersingular elliptic curves over
     * <code>F<sub>2<sup>m</sup></sub></code>.
     * @param b The coefficient <code>b</code> in the Weierstrass equation
     * for non-supersingular elliptic curves over
     * <code>F<sub>2<sup>m</sup></sub></code>.
     */
    public F2mCurve(
      int      m,
      int      k,
      BigInteger  a,
      BigInteger  b)
      : this(m, k, 0, 0, a, b, null, null)
    {
    }

    /**
     * Constructor for Trinomial Polynomial Basis (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 a The coefficient <code>a</code> in the Weierstrass equation
     * for non-supersingular elliptic curves over
     * <code>F<sub>2<sup>m</sup></sub></code>.
     * @param b The coefficient <code>b</code> in the Weierstrass equation
     * for non-supersingular elliptic curves over
     * <code>F<sub>2<sup>m</sup></sub></code>.
     * @param n The order of the main subgroup of the elliptic curve.
     * @param h The cofactor of the elliptic curve, i.e.
     * <code>#E<sub>a</sub>(F<sub>2<sup>m</sup></sub>) = h * n</code>.
     */
    public F2mCurve(
      int      m, 
      int      k, 
      BigInteger  a, 
      BigInteger  b,
      BigInteger  n,
      BigInteger  h)
      : this(m, k, 0, 0, a, b, n, h)
    {
    }

    /**
     * Constructor for Pentanomial Polynomial Basis (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 a The coefficient <code>a</code> in the Weierstrass equation
     * for non-supersingular elliptic curves over
     * <code>F<sub>2<sup>m</sup></sub></code>.
     * @param b The coefficient <code>b</code> in the Weierstrass equation
     * for non-supersingular elliptic curves over
     * <code>F<sub>2<sup>m</sup></sub></code>.
     */
    public F2mCurve(
      int      m,
      int      k1,
      int      k2,
      int      k3,
      BigInteger  a,
      BigInteger  b)
      : this(m, k1, k2, k3, a, b, null, null)
    {
    }

    /**
     * Constructor for Pentanomial Polynomial Basis (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 a The coefficient <code>a</code> in the Weierstrass equation
     * for non-supersingular elliptic curves over
     * <code>F<sub>2<sup>m</sup></sub></code>.
     * @param b The coefficient <code>b</code> in the Weierstrass equation
     * for non-supersingular elliptic curves over
     * <code>F<sub>2<sup>m</sup></sub></code>.
     * @param n The order of the main subgroup of the elliptic curve.
     * @param h The cofactor of the elliptic curve, i.e.
     * <code>#E<sub>a</sub>(F<sub>2<sup>m</sup></sub>) = h * n</code>.
     */
    public F2mCurve(
      int      m, 
      int      k1, 
      int      k2, 
      int      k3,
      BigInteger  a, 
      BigInteger  b,
      BigInteger  n,
      BigInteger  h)
    {
      this.m = m;
      this.k1 = k1;
      this.k2 = k2;
      this.k3 = k3;
      this.n = n;
      this.h = h;
      this.infinity = new F2mPoint(this, null, null);

      if (k1 == 0)
                throw new ArgumentException("k1 must be > 0");

      if (k2 == 0)
            {
                if (k3 != 0)
                    throw new ArgumentException("k3 must be 0 if k2 == 0");
            }
            else
            {
                if (k2 <= k1)
                    throw new ArgumentException("k2 must be > k1");

        if (k3 <= k2)
                    throw new ArgumentException("k3 must be > k2");
            }

      this.a = FromBigInteger(a);
            this.b = FromBigInteger(b);
        }

    public override ECPoint Infinity
    {
      get { return infinity; }
    }

    public override int FieldSize
    {
      get { return m; }
    }

    public override ECFieldElement FromBigInteger(BigInteger x)
        {
            return new F2mFieldElement(this.m, this.k1, this.k2, this.k3, x);
        }

    /**
     * Returns true if this is a Koblitz curve (ABC curve).
     * @return true if this is a Koblitz curve (ABC curve), false otherwise
     */
    public bool IsKoblitz
    {
      get
      {
        return n != null && h != null
          && (a.ToBigInteger().Equals(BigInteger.Zero)
            || a.ToBigInteger().Equals(BigInteger.One))
          && b.ToBigInteger().Equals(BigInteger.One);
      }
    }

    /**
     * Returns the parameter <code>&#956;</code> of the elliptic curve.
     * @return <code>&#956;</code> of the elliptic curve.
     * @throws ArgumentException if the given ECCurve is not a
     * Koblitz curve.
     */
    internal sbyte GetMu()
    {
      if (mu == 0)
      {
        lock (this)
        {
          if (mu == 0)
          {
            mu = Tnaf.GetMu(this);
          }
        }
      }

      return mu;
    }

    /**
     * @return the auxiliary values <code>s<sub>0</sub></code> and
     * <code>s<sub>1</sub></code> used for partial modular reduction for
     * Koblitz curves.
     */
    internal BigInteger[] GetSi()
    {
      if (si == null)
      {
        lock (this)
        {
          if (si == null)
          {
            si = Tnaf.GetSi(this);
          }
        }
      }
      return si;
    }

    public override ECPoint CreatePoint(
      BigInteger  X1,
      BigInteger  Y1,
      bool    withCompression)
    {
      // TODO Validation of X1, Y1?
      return new F2mPoint(
        this,
        FromBigInteger(X1),
        FromBigInteger(Y1),
        withCompression);
    }

    protected internal override ECPoint DecompressPoint(
      int      yTilde,
      BigInteger  X1)
    {
      ECFieldElement xp = FromBigInteger(X1);
      ECFieldElement yp = null;
      if (xp.ToBigInteger().SignValue == 0)
      {
        yp = (F2mFieldElement)b;
        for (int i = 0; i < m - 1; i++)
        {
          yp = yp.Square();
        }
      }
      else
      {
        ECFieldElement beta = xp.Add(a).Add(
          b.Multiply(xp.Square().Invert()));
        ECFieldElement z = solveQuadradicEquation(beta);

        if (z == null)
          throw new ArithmeticException("Invalid point compression");

        int zBit = z.ToBigInteger().TestBit(0) ? 1 : 0;
        if (zBit != yTilde)
        {
          z = z.Add(FromBigInteger(BigInteger.One));
        }

        yp = xp.Multiply(z);
      }

      return new F2mPoint(this, xp, yp, true);
    }

    /**
         * Solves a quadratic equation <code>z<sup>2</sup> + z = beta</code>(X9.62
         * D.1.6) The other solution is <code>z + 1</code>.
         *
         * @param beta
         *            The value to solve the qradratic equation for.
         * @return the solution for <code>z<sup>2</sup> + z = beta</code> or
         *         <code>null</code> if no solution exists.
         */
        private ECFieldElement solveQuadradicEquation(ECFieldElement beta)
        {
            if (beta.ToBigInteger().SignValue == 0)
            {
                return FromBigInteger(BigInteger.Zero);
            }

      ECFieldElement z = null;
            ECFieldElement gamma = FromBigInteger(BigInteger.Zero);

      while (gamma.ToBigInteger().SignValue == 0)
            {
                ECFieldElement t = FromBigInteger(new BigInteger(m, new Random()));
        z = FromBigInteger(BigInteger.Zero);

        ECFieldElement w = beta;
                for (int i = 1; i <= m - 1; i++)
                {
          ECFieldElement w2 = w.Square();
                    z = z.Square().Add(w2.Multiply(t));
                    w = w2.Add(beta);
                }
                if (w.ToBigInteger().SignValue != 0)
                {
                    return null;
                }
                gamma = z.Square().Add(z);
            }
            return z;
        }

    public override bool Equals(
            object obj)
        {
            if (obj == this)
                return true;

      F2mCurve other = obj as F2mCurve;

      if (other == null)
                return false;

      return Equals(other);
        }

    protected bool Equals(
      F2mCurve other)
    {
      return m == other.m
        && k1 == other.k1
        && k2 == other.k2
        && k3 == other.k3
        && base.Equals(other);
    }

    public override int GetHashCode()
        {
            return base.GetHashCode() ^ m ^ k1 ^ k2 ^ k3;
        }

    public int M
        {
      get { return m; }
        }

    /**
         * Return true if curve uses a Trinomial basis.
         *
         * @return true if curve Trinomial, false otherwise.
         */
        public bool IsTrinomial()
        {
            return k2 == 0 && k3 == 0;
        }

    public int K1
        {
      get { return k1; }
        }

    public int K2
        {
      get { return k2; }
        }

    public int K3
        {
      get { return k3; }
        }

    public BigInteger N
    {
      get { return n; }
    }

    public BigInteger H
    {
      get { return h; }
    }
  }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.