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;
}
}