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.SatisfiesCofactor())
                {
                    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);
        }
Example #2
0
    public virtual ECPoint DecodePoint(byte[] encoded)
    {
        ECPoint eCPoint = null;
        int     num     = (FieldSize + 7) / 8;
        byte    b       = encoded[0];

        switch (b)
        {
        case 0:
            if (encoded.Length != 1)
            {
                throw new ArgumentException("Incorrect length for infinity encoding", "encoded");
            }
            eCPoint = Infinity;
            break;

        case 2:
        case 3:
        {
            if (encoded.Length != num + 1)
            {
                throw new ArgumentException("Incorrect length for compressed encoding", "encoded");
            }
            int        yTilde = b & 1;
            BigInteger x3     = new BigInteger(1, encoded, 1, num);
            eCPoint = DecompressPoint(yTilde, x3);
            if (!eCPoint.SatisfiesCofactor())
            {
                throw new ArgumentException("Invalid point");
            }
            break;
        }

        case 4:
        {
            if (encoded.Length != 2 * num + 1)
            {
                throw new ArgumentException("Incorrect length for uncompressed encoding", "encoded");
            }
            BigInteger x2 = new BigInteger(1, encoded, 1, num);
            BigInteger y  = new BigInteger(1, encoded, 1 + num, num);
            eCPoint = ValidatePoint(x2, y);
            break;
        }

        case 6:
        case 7:
        {
            if (encoded.Length != 2 * num + 1)
            {
                throw new ArgumentException("Incorrect length for hybrid encoding", "encoded");
            }
            BigInteger x          = new BigInteger(1, encoded, 1, num);
            BigInteger bigInteger = new BigInteger(1, encoded, 1 + num, num);
            if (bigInteger.TestBit(0) != (b == 7))
            {
                throw new ArgumentException("Inconsistent Y coordinate in hybrid encoding", "encoded");
            }
            eCPoint = ValidatePoint(x, bigInteger);
            break;
        }

        default:
            throw new FormatException("Invalid point encoding " + b);
        }
        if (b != 0 && eCPoint.IsInfinity)
        {
            throw new ArgumentException("Invalid infinity encoding", "encoded");
        }
        return(eCPoint);
    }