/// <summary> /// Calculates y from y^2 = x^3 + ax + b (mod p) by having x and the first byte indicating whether y is odd or even. /// Return value indicates success. /// </summary> /// <param name="x">X coordinate</param> /// <param name="firstByte">The first byte indicating whether y is odd or even (must be 2 or 3)</param> /// <param name="y">Calculated y (0 if fails to calculate)</param> /// <returns>True if y was found, otherwise false.</returns> public bool TryFindY(BigInteger x, byte firstByte, out BigInteger y) { if (firstByte != 2 && firstByte != 3) { return(false); } if (x.Sign < 1) { return(false); } // Curve.A is zero BigInteger right = (BigInteger.Pow(x, 3) + curve.B) % curve.P; if (SquareRoot.TryFind(right, curve.P, out y)) { if (firstByte == 2 && !y.IsEven) { // We know point is already on curve y = PointNegChecked(new EllipticCurvePoint(x, y)).Y; } else if (firstByte == 3 && y.IsEven) { y = PointNegChecked(new EllipticCurvePoint(x, y)).Y; } return(true); } else { return(false); } }
/// <summary> /// Calculates y from y^2 = x^3 + ax + b (mod p) by having x for Schnorr encoding. /// Return value indicates success. /// </summary> /// <param name="x">X coordinate</param> /// <param name="y">Calculated y (0 if fails to calculate)</param> /// <returns>True if y was found, otherwise false.</returns> public bool TryFindYSchnorr(BigInteger x, out BigInteger y) { if (x.Sign < 1 || x > curve.P) { return(false); } // Curve.A is zero BigInteger right = (BigInteger.Pow(x, 3) + curve.B) % curve.P; return(SquareRoot.TryFind(right, curve.P, out y)); }