+++ /dev/null
-\feffusing System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Novacoin
-{
- /// <summary>
- /// Representation of ECDSA private key
- /// </summary>
- public class CKey
- {
- /// <summary>
- /// Private key bytes
- /// </summary>
- private List<byte> privKeyBytes;
-
- /// <summary>
- /// Initialize new instance of CKey as copy of another instance.
- /// </summary>
- /// <param name="key">New CKey instance.</param>
- public CKey(CKey key)
- {
- privKeyBytes = key.privKeyBytes;
- }
-
- /// <summary>
- /// Initialize new instance of CKey using supplied byte sequence.
- /// </summary>
- /// <param name="bytes">New CKey instance.</param>
- public CKey(IEnumerable<byte> bytes)
- {
- privKeyBytes = new List<byte>(bytes);
- }
-
- /// <summary>
- /// Calculate public key for this private key.
- /// </summary>
- /// <returns>New CPubKey instance.</returns>
- public CPubKey GetPubKey()
- {
- // stub
-
- return new CPubKey((CPubKey)null);
- }
- }
-}
using System.Text;
using System.Threading.Tasks;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Math.EC;
+
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Generators;
+using Org.BouncyCastle.Crypto.Parameters;
+
+using Org.BouncyCastle.Asn1.X9;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Asn1.Sec;
+
namespace Novacoin
{
/// <summary>
/// </summary>
public class CPubKey
{
- /// <summary>
- /// Public key bytes
- /// </summary>
- private List<byte> pubKeyBytes;
+ private ECPoint Q;
+ private static X9ECParameters curve = SecNamedCurves.GetByName("secp256k1");
+ private static ECDomainParameters domain = new ECDomainParameters(curve.Curve, curve.G, curve.N, curve.H, curve.GetSeed());
/// <summary>
/// Initializes a new instance of CPubKey class as the copy of another instance
/// <param name="pubKey">Another CPubKey instance</param>
public CPubKey(CPubKey pubKey)
{
- pubKeyBytes = pubKey.pubKeyBytes;
+ Q = pubKey.Q;
}
/// <summary>
/// Initializes a new instance of CPubKey class using supplied sequence of bytes
/// </summary>
- /// <param name="bytesList"></param>
- public CPubKey(IEnumerable<byte> bytesList)
+ /// <param name="bytes">Byte sequence</param>
+ public CPubKey(IEnumerable<byte> bytes)
+ {
+ Q = ((ECPublicKeyParameters)PublicKeyFactory.CreateKey(bytes.ToArray())).Q;
+ }
+
+ public CPubKey(ECPoint pQ)
{
- pubKeyBytes = new List<byte>(bytesList);
+ Q = pQ;
}
/// <summary>
/// Quick validity test
/// </summary>
/// <returns>Validation result</returns>
- public bool IsValid()
+ public bool IsValid
{
- return pubKeyBytes.Count == 33 || pubKeyBytes.Count == 65;
+ get { return !Q.IsInfinity; }
}
/// <summary>
/// Is this a compressed public key?
/// </summary>
/// <returns></returns>
- public bool IsCompressed()
+ public bool IsCompressed
{
- // Compressed public keys are 33 bytes long
- return pubKeyBytes.Count == 33;
+ get { return Q.IsCompressed; }
}
/// <summary>
/// <returns>New key ID</returns>
public CKeyID GetKeyID()
{
- return new CKeyID(Hash160.Compute160(this.Raw));
+ return new CKeyID(Hash160.Compute160(Raw));
+ }
+
+ public bool Verify(IEnumerable<byte> data, IEnumerable<byte> signature)
+ {
+ byte[] dataBytes = data.ToArray();
+
+ ISigner signer = SignerUtilities.GetSigner("SHA-256withECDSA");
+ ECPublicKeyParameters keyParameters = new ECPublicKeyParameters(Q, domain);
+ signer.Init(false, keyParameters);
+ signer.BlockUpdate(dataBytes, 0, dataBytes.Length);
+
+ return signer.VerifySignature(signature.ToArray());
}
/// <summary>
/// Accessor for internal representation
/// </summary>
- public IList<byte> Raw
+ public IEnumerable<byte> Raw
+ {
+ get { return Q.GetEncoded(); }
+ }
+
+ public override string ToString()
{
- get { return pubKeyBytes; }
+ return Interop.ToHex(Raw);
}
}
}
AddOp(opcodetype.OP_EQUAL);
}
- public void SetMultiSig(int nRequired, IEnumerable<CKey> keys)
+ public void SetMultiSig(int nRequired, IEnumerable<CPubKey> keys)
{
codeBytes.Clear();
AddOp(ScriptOpcode.EncodeOP_N(nRequired));
- foreach (CKey key in keys)
+ foreach (CPubKey key in keys)
{
- PushData(key.GetPubKey().Raw);
+ PushData(key.Raw.ToList());
}
AddOp(ScriptOpcode.EncodeOP_N(keys.Count()));
AddOp(opcodetype.OP_CHECKMULTISIG);
CKeyPair keyPair1 = new CKeyPair();
CKeyPair keyPair2 = new CKeyPair(keyPair1.Secret);
+ CPubKey pubKey = keyPair2.GetPubKey();
Console.WriteLine(keyPair1.ToString());
+ Console.WriteLine("PubKey: {0}", pubKey.ToString());
Console.WriteLine("OK: {0}\n", keyPair1.ToString() == keyPair2.ToString());
/// ECDSA keypair signing test
byte[] signature = keyPair1.Sign(dataBytes).ToArray();
Console.WriteLine("Signature: {0}", Interop.ToHex(signature));
- Console.WriteLine("Signature is OK: {0}", keyPair1.Verify(dataBytes, signature));
+ Console.WriteLine("Signature is OK: {0} (CKeyPair)", keyPair1.Verify(dataBytes, signature));
+ Console.WriteLine("Signature is OK: {0} (CPubKey)", pubKey.Verify(dataBytes, signature));
Console.ReadLine();
}