Public key compression
authorCryptoManiac <balthazar@yandex.ru>
Tue, 18 Aug 2015 17:05:36 +0000 (20:05 +0300)
committerCryptoManiac <balthazar@yandex.ru>
Tue, 18 Aug 2015 17:05:36 +0000 (20:05 +0300)
Novacoin/CKey.cs
Novacoin/CKeyPair.cs

index e06086c..6f9ce35 100644 (file)
@@ -8,6 +8,9 @@ using Org.BouncyCastle.Asn1.X9;
 using Org.BouncyCastle.Security;
 using Org.BouncyCastle.Asn1.Sec;
 
+using Org.BouncyCastle.Math.EC;
+
+
 namespace Novacoin
 {
     /// <summary>
@@ -22,6 +25,42 @@ namespace Novacoin
         protected static ECDomainParameters domain = new ECDomainParameters(curve.Curve, curve.G, curve.N, curve.H, curve.GetSeed());
 
         /// <summary>
+        /// Regenerate public key parameters (ECPoint compression)
+        /// </summary>
+        /// <param name="pubKeyParams">Non-compressed key parameters</param>
+        /// <returns>Parameters for compressed key</returns>
+        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);
+        }
+
+        /// <summary>
+        /// Regenerate public key parameters (ECPoint decompression)
+        /// </summary>
+        /// <param name="pubKeyParams">Compressed key parameters</param>
+        /// <returns>Parameters for non-compressed key</returns>
+        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);
+        }
+
+        /// <summary>
         /// Does the signature matches our public key?
         /// </summary>
         /// <param name="data">Data bytes</param>
index f5b778f..3230344 100644 (file)
@@ -20,22 +20,27 @@ namespace Novacoin
         /// <summary>
         /// Initialize new CKeyPair instance with random secret.
         /// </summary>
-        public CKeyPair()
+        public CKeyPair(bool Compressed=true)
         {
             ECKeyGenerationParameters genParams = new ECKeyGenerationParameters(domain, new SecureRandom());
             ECKeyPairGenerator generator = new ECKeyPairGenerator("ECDSA");
             generator.Init(genParams);
             AsymmetricCipherKeyPair ecKeyPair = generator.GenerateKeyPair();
 
-            _Public = (ECPublicKeyParameters)ecKeyPair.Public;
             _Private = (ECPrivateKeyParameters)ecKeyPair.Private;
+            _Public = (ECPublicKeyParameters)ecKeyPair.Public;
+
+            if (Compressed)
+            {
+                _Public = Compress(_Public);
+            }
         }
 
         /// <summary>
         /// Init key pair using secret sequence of bytes
         /// </summary>
         /// <param name="secretBytes">Byte sequence</param>
-        public CKeyPair(IEnumerable<byte> secretBytes)
+        public CKeyPair(IEnumerable<byte> secretBytes, bool Compressed=true)
         {
             // Deserialize secret value
             BigInteger D = new BigInteger(secretBytes.ToArray());
@@ -43,8 +48,13 @@ namespace Novacoin
             // Calculate public key
             ECPoint Q = curve.G.Multiply(D);
 
-            _Public = new ECPublicKeyParameters(Q, domain);
             _Private = new ECPrivateKeyParameters(D, domain);
+            _Public = new ECPublicKeyParameters(Q, domain);
+
+            if (Compressed)
+            {
+                _Public = Compress(_Public);
+            }
         }
 
         /// <summary>