From 7a59f739f5c56258595956bc5c48bf313a5b50b4 Mon Sep 17 00:00:00 2001 From: CryptoManiac Date: Tue, 18 Aug 2015 20:05:36 +0300 Subject: [PATCH] Public key compression --- Novacoin/CKey.cs | 39 +++++++++++++++++++++++++++++++++++++++ Novacoin/CKeyPair.cs | 18 ++++++++++++++---- 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/Novacoin/CKey.cs b/Novacoin/CKey.cs index e06086c..6f9ce35 100644 --- a/Novacoin/CKey.cs +++ b/Novacoin/CKey.cs @@ -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 { /// @@ -22,6 +25,42 @@ namespace Novacoin 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 diff --git a/Novacoin/CKeyPair.cs b/Novacoin/CKeyPair.cs index f5b778f..3230344 100644 --- a/Novacoin/CKeyPair.cs +++ b/Novacoin/CKeyPair.cs @@ -20,22 +20,27 @@ namespace Novacoin /// /// Initialize new CKeyPair instance with random secret. /// - 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); + } } /// /// Init key pair using secret sequence of bytes /// /// Byte sequence - public CKeyPair(IEnumerable secretBytes) + public CKeyPair(IEnumerable 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); + } } /// -- 1.7.1