using System.Collections.Generic; using System.Linq; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Asn1.X9; using Org.BouncyCastle.Security; using Org.BouncyCastle.Asn1.Sec; using Org.BouncyCastle.Math.EC; namespace Novacoin { /// /// Basic pubkey functionality /// public abstract class CKey { // These fields are inherited by CPubKey and CKeyPair protected ECPublicKeyParameters _Public; protected static X9ECParameters curve = SecNamedCurves.GetByName("secp256k1"); protected static ECDomainParameters domain = new ECDomainParameters(curve.Curve, curve.G, curve.N, curve.H, curve.GetSeed()); /// /// Regenerate public key parameters (ECPoint compression) /// /// Non-compressed key parameters /// Parameters for compressed key protected ECPublicKeyParameters Compress(ECPublicKeyParameters pubKeyParams) { if (pubKeyParams.Q.IsCompressed) { // Already compressed return pubKeyParams; } ECPoint q = new FpPoint(curve.Curve, pubKeyParams.Q.X, pubKeyParams.Q.Y, true); return new ECPublicKeyParameters(q, domain); } /// /// Regenerate public key parameters (ECPoint decompression) /// /// Compressed key parameters /// Parameters for non-compressed key protected ECPublicKeyParameters Decompress(ECPublicKeyParameters pubKeyParams) { if (!pubKeyParams.Q.IsCompressed) { // Isn't compressed return pubKeyParams; } ECPoint q = new FpPoint(curve.Curve, pubKeyParams.Q.X, pubKeyParams.Q.Y, false); return new ECPublicKeyParameters(q, domain); } /// /// Does the signature matches our public key? /// /// Data bytes /// Signature bytes /// Checking result public bool VerifySignature(IEnumerable data, IEnumerable signature) { byte[] dataBytes = data.ToArray(); ISigner signer = SignerUtilities.GetSigner("SHA-256withECDSA"); signer.Init(false, _Public); signer.BlockUpdate(dataBytes, 0, dataBytes.Length); return signer.VerifySignature(signature.ToArray()); } /// /// Calculate Hash160 and create new CKeyID instance. /// /// New key ID public CKeyID GetKeyID() { return new CKeyID(Hash160.Compute160(Public)); } /// /// Public part of key pair /// public IEnumerable Public { get { return _Public.Q.GetEncoded(); } } /// /// Is this a compressed public key? /// /// public bool IsCompressed { get { return _Public.Q.IsCompressed; } } } }