From 72a4d16090f35397bcc68677a19cbcb3715e6ed8 Mon Sep 17 00:00:00 2001 From: CryptoManiac Date: Wed, 19 Aug 2015 10:51:23 +0300 Subject: [PATCH] Correct sign byte handling --- Novacoin/CKeyPair.cs | 55 ++++++++++++++++++++++++++++++---------------- NovacoinTest/Program.cs | 7 ++++++ 2 files changed, 43 insertions(+), 19 deletions(-) diff --git a/Novacoin/CKeyPair.cs b/Novacoin/CKeyPair.cs index 885529b..90bcae2 100644 --- a/Novacoin/CKeyPair.cs +++ b/Novacoin/CKeyPair.cs @@ -43,7 +43,15 @@ namespace Novacoin public CKeyPair(IEnumerable secretBytes, bool Compressed=true) { // Deserialize secret value - BigInteger D = new BigInteger(secretBytes.ToArray()); + BigInteger D = new BigInteger(secretBytes.Take(32).ToArray()); + + if (D.SignValue == -1) + { + List fixedKeyBytes = secretBytes.Take(32).ToList(); + fixedKeyBytes.Insert(0, 0x00); // prepend with sign byte + + D = new BigInteger(fixedKeyBytes.ToArray()); + } // Calculate public key ECPoint Q = curve.G.Multiply(D); @@ -62,16 +70,16 @@ namespace Novacoin List rawBytes = AddressTools.Base58DecodeCheck(strBase58).ToList(); rawBytes.RemoveAt(0); // Remove key version byte - int nSecretLen = rawBytes[0] == 0x00 ? 33 : 32; - int nTaggedSecretLen = nSecretLen + 1; + // Deserialize secret value + BigInteger D = new BigInteger(rawBytes.Take(32).ToArray()); - if (rawBytes.Count > nTaggedSecretLen || rawBytes.Count < nSecretLen) + if (D.SignValue == -1) { - throw new FormatException("Invalid private key"); - } + List secretbytes = rawBytes.Take(32).ToList(); // Copy secret + secretbytes.Insert(0, 0x00); // Prepend with sign byte - // Deserialize secret value - BigInteger D = new BigInteger(rawBytes.Take(nSecretLen).ToArray()); + D = new BigInteger(secretbytes.ToArray()); // Try decoding again + } // Calculate public key ECPoint Q = curve.G.Multiply(D); @@ -79,13 +87,23 @@ namespace Novacoin _Private = new ECPrivateKeyParameters(D, domain); _Public = new ECPublicKeyParameters(Q, domain); - if (rawBytes.Count == nTaggedSecretLen && rawBytes.Last() == 0x01) // Check compression tag + if (rawBytes.Count == 33 && rawBytes.Last() == 0x01) // Check compression tag { _Public = Compress(_Public); } } /// + /// Initialize a copy of CKeyPair instance + /// + /// CKyPair instance + public CKeyPair(CKeyPair pair) + { + _Public = pair._Public; + _Private = pair._Private; + } + + /// /// Create signature for supplied data /// /// Data bytes sequence @@ -116,26 +134,25 @@ namespace Novacoin public string ToHex() { - List r = new List(Secret); - - if (IsCompressed) - { - r.Add(0x01); - } - - return Interop.ToHex(r); + return Interop.ToHex(Secret); } public override string ToString() { List r = new List(); - r.Add((byte)(128 + AddrType.PUBKEY_ADDRESS)); + r.Add((byte)(128 + AddrType.PUBKEY_ADDRESS)); // Key version + r.AddRange(Secret); // Key data - r.AddRange(Secret); + if (r[1] == 0x00) + { + // Remove sign + r.RemoveAt(1); + } if (IsCompressed) { + // Set compression flag r.Add(0x01); } diff --git a/NovacoinTest/Program.cs b/NovacoinTest/Program.cs index a6686e2..f354961 100644 --- a/NovacoinTest/Program.cs +++ b/NovacoinTest/Program.cs @@ -64,6 +64,13 @@ namespace NovacoinTest Console.WriteLine("Key ID: {0}", Interop.ToHex(keyID.hashBytes)); Console.WriteLine("Novacoin address: {0}\n", keyID.ToString()); + /// Privkey deserialization test + CKeyPair keyPair4 = new CKeyPair("MEP3qCtFGmWo3Gurf8fMnUNaDHGNf637DqjoeG8rKium2jSj51sf"); + Console.WriteLine("\nHard-coded privkey in Hex: {0}", keyPair4.ToHex()); + Console.WriteLine("Hard-Coded privkey address: {0}", keyPair4.GetKeyID().ToString()); + Console.WriteLine("Hard-Coded privkey: {0}\n", keyPair4.ToString()); + + /// ECDSA keypair signing test string data = "Превед!"; -- 1.7.1