/// <summary> /// Check that this is correct public key. /// </summary> /// <remarks> /// This method can be used to verify that public and private key are on the curve. /// </remarks> public static void Validate(GXPublicKey publicKey) { if (publicKey == null) { throw new ArgumentNullException("Invalid public key."); } GXByteBuffer bb = new GXByteBuffer(); bb.Set(publicKey.RawValue); int size = SchemeSize(publicKey.Scheme); GXBigInteger x = new GXBigInteger(bb.SubArray(1, size)); GXBigInteger y = new GXBigInteger(bb.SubArray(1 + size, size)); GXCurve curve = new GXCurve(publicKey.Scheme); y.Multiply(y); y.Mod(curve.P); GXBigInteger tmpX = new GXBigInteger(x); tmpX.Multiply(x); tmpX.Mod(curve.P); tmpX.Add(curve.A); tmpX.Multiply(x); tmpX.Add(curve.B); tmpX.Mod(curve.P); if (y.Compare(tmpX) != 0) { throw new ArgumentException("Public key validate failed. Public key is not valid ECDSA public key."); } }
/// <summary> /// Get public key from private key. /// </summary> /// <param name="scheme">Used scheme.</param> /// <param name="privateKey">Private key bytes.</param> /// <returns>Public key.</returns> public GXPublicKey GetPublicKey() { GXBigInteger secret = new GXBigInteger(RawValue); GXCurve curve = new GXCurve(Scheme); GXEccPoint p = new GXEccPoint(curve.G.x, curve.G.y, new GXBigInteger(1)); p = GXEcdsa.JacobianMultiply(p, secret, curve.N, curve.A, curve.P); GXEcdsa.FromJacobian(p, curve.P); GXByteBuffer key = new GXByteBuffer(65); //Public key is un-compressed format. key.SetUInt8(4); byte[] tmp = p.x.ToArray(); key.Set(tmp, tmp.Length % 32, 32); tmp = p.y.ToArray(); key.Set(tmp, tmp.Length % 32, 32); return(GXPublicKey.FromRawBytes(key.Array())); }
/// <summary> /// Get public key from private key. /// </summary> /// <param name="scheme">Used scheme.</param> /// <param name="privateKey">Private key bytes.</param> /// <returns>Public key.</returns> public GXPublicKey GetPublicKey() { if (publicKey == null) { GXBigInteger pk = new GXBigInteger(RawValue); GXCurve curve = new GXCurve(Scheme); GXEccPoint p = new GXEccPoint(curve.G.x, curve.G.y, new GXBigInteger(1)); p = GXEcdsa.JacobianMultiply(p, pk, curve.N, curve.A, curve.P); GXEcdsa.FromJacobian(p, curve.P); GXByteBuffer key = new GXByteBuffer(65); //Public key is un-compressed format. key.SetUInt8(4); byte[] tmp = p.x.ToArray(); int size = Scheme == Ecc.P256 ? 32 : 48; key.Set(tmp, tmp.Length % size, size); tmp = p.y.ToArray(); key.Set(tmp, tmp.Length % size, size); publicKey = GXPublicKey.FromRawBytes(key.Array()); } return(publicKey); }
/// <summary> /// Generate shared secret from public and private key. /// </summary> /// <param name="publicKey">Public key.</param> /// <returns>Generated secret.</returns> public byte[] GenerateSecret(GXPublicKey publicKey) { if (PrivateKey == null) { throw new ArgumentNullException("Invalid private key."); } if (PrivateKey.Scheme != publicKey.Scheme) { throw new ArgumentNullException("Private key scheme is different than public key."); } GXByteBuffer bb = new GXByteBuffer(); bb.Set(publicKey.RawValue); int size = SchemeSize(PrivateKey.Scheme); GXBigInteger x = new GXBigInteger(bb.SubArray(1, size)); GXBigInteger y = new GXBigInteger(bb.SubArray(1 + size, size)); GXBigInteger pk = new GXBigInteger(PrivateKey.RawValue); GXCurve curve = new GXCurve(PrivateKey.Scheme); GXEccPoint p = new GXEccPoint(x, y, new GXBigInteger(1)); p = JacobianMultiply(p, pk, curve.N, curve.A, curve.P); FromJacobian(p, curve.P); return(p.x.ToArray()); }
private GXEcdsa(Ecc scheme) { curve = new GXCurve(scheme); }