Example #1
0
        /**
         * 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 virtual ECPoint DecodePoint(byte[] encoded)
        {
            ECPoint p = null;
            int     expectedLength = (FieldSize + 7) / 8;

            byte type = encoded[0];

            switch (type)
            {
            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 = type & 1;
                BigInteger X      = new BigInteger(1, encoded, 1, expectedLength);

                p = DecompressPoint(yTilde, X);
                if (!p.ImplIsValid(true, true))
                {
                    throw new ArgumentException("Invalid point");
                }

                break;
            }

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

                BigInteger X = new BigInteger(1, encoded, 1, expectedLength);
                BigInteger Y = new BigInteger(1, encoded, 1 + expectedLength, expectedLength);

                p = ValidatePoint(X, Y);
                break;
            }

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

                BigInteger X = new BigInteger(1, encoded, 1, expectedLength);
                BigInteger Y = new BigInteger(1, encoded, 1 + expectedLength, expectedLength);

                if (Y.TestBit(0) != (type == 0x07))
                {
                    throw new ArgumentException("Inconsistent Y coordinate in hybrid encoding", "encoded");
                }

                p = ValidatePoint(X, Y);
                break;
            }

            default:
                throw new FormatException("Invalid point encoding " + type);
            }

            if (type != 0x00 && p.IsInfinity)
            {
                throw new ArgumentException("Invalid infinity encoding", "encoded");
            }

            return(p);
        }