Skip to content

Commit 0ce2977

Browse files
committed
change to ecdh
1 parent 33ac64d commit 0ce2977

File tree

2 files changed

+55
-58
lines changed

2 files changed

+55
-58
lines changed

src/neo/Cryptography/Helper.cs

+44-51
Original file line numberDiff line numberDiff line change
@@ -129,10 +129,8 @@ public static byte[] AES256Encrypt(this byte[] plainData, byte[] key, byte[] non
129129

130130
if (keyLen != 32) throw new ArgumentException();
131131
if (nonceLen != 12) throw new ArgumentException();
132-
133132
var msgLen = plainData is null ? 0 : plainData.Length;
134133
var tagLen = 16;
135-
136134
var cipherBytes = new byte[msgLen];
137135
var tag = new byte[tagLen];
138136
using var cipher = new AesGcm(key);
@@ -156,62 +154,57 @@ public static byte[] AES256Decrypt(this byte[] encryptedData, byte[] key, byte[]
156154
return decryptedData;
157155
}
158156

159-
public static byte[] ECEncrypt(byte[] message, ECPoint pubKey)
157+
public static byte[] EcdhEncrypt(byte[] message, KeyPair local, ECPoint remote)
160158
{
161-
// P=kG,R=rG =>{R,M+rP}
162-
if (pubKey.IsInfinity) throw new ArgumentException();
163-
BigInteger r, rx;
164-
ECPoint R;
165-
var curve = pubKey.Curve;
166-
//r > N
167-
using (RandomNumberGenerator rng = RandomNumberGenerator.Create())
159+
ECDiffieHellman ecdh1 = ECDiffieHellmanCng.Create(new ECParameters
168160
{
169-
do
161+
Curve = ECCurve.NamedCurves.nistP256,
162+
D = local.PrivateKey,
163+
Q = new System.Security.Cryptography.ECPoint
170164
{
171-
do
172-
{
173-
r = rng.NextBigInteger((int)curve.N.GetBitLength());
174-
} while (r.Sign == 0 || r.CompareTo(curve.N) >= 0);
175-
R = ECPoint.Multiply(curve.G, r);
176-
BigInteger x = R.X.Value;
177-
rx = x.Mod(curve.N);
178-
} while (rx.Sign == 0);
179-
}
180-
byte[] RBar = R.EncodePoint(true);
181-
var EK = ECPoint.Multiply(pubKey, r).X.ToByteArray().Sha256(); // z = r * P = r* k * G
165+
X = local.PublicKey.EncodePoint(false)[1..][..32],
166+
Y = local.PublicKey.EncodePoint(false)[1..][32..]
167+
}
168+
});
169+
ECDiffieHellman ecdh2 = ECDiffieHellmanCng.Create(new ECParameters
170+
{
171+
Curve = ECCurve.NamedCurves.nistP256,
172+
Q = new System.Security.Cryptography.ECPoint
173+
{
174+
X = remote.EncodePoint(false)[1..][..32],
175+
Y = remote.EncodePoint(false)[1..][32..]
176+
}
177+
});
178+
byte[] secret = ecdh1.DeriveKeyMaterial(ecdh2.PublicKey).Sha256();//z = r * P = r* k * G
182179
Random random = new Random();
183-
byte[] Nonce = new byte[12];
184-
random.NextBytes(Nonce);
185-
return RBar.Concat(message.AES256Encrypt(EK, Nonce)).ToArray();
180+
byte[] nonce = new byte[12];
181+
random.NextBytes(nonce);
182+
return message.AES256Encrypt(secret, nonce);
186183
}
187184

188-
public static byte[] ECDecrypt(byte[] cypher, KeyPair key)
185+
public static byte[] EcdhDecrypt(byte[] cypher, KeyPair local, ECPoint remote)
189186
{
190-
// {R,M+rP}={rG, M+rP}=> M + rP - kR = M + r(kG) - k(rG) = M
191-
if (cypher is null || cypher.Length < 33) throw new ArgumentException();
192-
if (cypher[0] != 0x02 && cypher[0] != 0x03) throw new ArgumentException();
193-
if (key.PublicKey.IsInfinity) throw new ArgumentException();
194-
var RBar = cypher.Take(33).ToArray();
195-
var EM = cypher.Skip(33).ToArray();
196-
var R = ECPoint.FromBytes(RBar, key.PublicKey.Curve);
197-
var k = new BigInteger(key.PrivateKey.Reverse().Concat(new byte[1]).ToArray());
198-
var EK = ECPoint.Multiply(R, k).X.ToByteArray().Sha256(); // z = k * R = k * r * G
199-
return EM.AES256Decrypt(EK);
200-
}
201-
202-
internal static BigInteger NextBigInteger(this RandomNumberGenerator rng, int sizeInBits)
203-
{
204-
if (sizeInBits < 0)
205-
throw new ArgumentException("sizeInBits must be non-negative");
206-
if (sizeInBits == 0)
207-
return 0;
208-
byte[] b = new byte[sizeInBits / 8 + 1];
209-
rng.GetBytes(b);
210-
if (sizeInBits % 8 == 0)
211-
b[b.Length - 1] = 0;
212-
else
213-
b[b.Length - 1] &= (byte)((1 << sizeInBits % 8) - 1);
214-
return new BigInteger(b);
187+
ECDiffieHellman ecdh1 = ECDiffieHellmanCng.Create(new ECParameters
188+
{
189+
Curve = ECCurve.NamedCurves.nistP256,
190+
D = local.PrivateKey,
191+
Q = new System.Security.Cryptography.ECPoint
192+
{
193+
X = local.PublicKey.EncodePoint(false)[1..][..32],
194+
Y = local.PublicKey.EncodePoint(false)[1..][32..]
195+
}
196+
});
197+
ECDiffieHellman ecdh2 = ECDiffieHellmanCng.Create(new ECParameters
198+
{
199+
Curve = ECCurve.NamedCurves.nistP256,
200+
Q = new System.Security.Cryptography.ECPoint
201+
{
202+
X = remote.EncodePoint(false)[1..][..32],
203+
Y = remote.EncodePoint(false)[1..][32..]
204+
}
205+
});
206+
byte[] secret = ecdh1.DeriveKeyMaterial(ecdh2.PublicKey).Sha256();//z = r * P = r* k * G
207+
return cypher.AES256Decrypt(secret);
215208
}
216209

217210
internal static bool Test(this BloomFilter filter, Transaction tx)

tests/neo.UnitTests/Cryptography/UT_Cryptography_Helper.cs

+11-7
Original file line numberDiff line numberDiff line change
@@ -69,18 +69,22 @@ public void TestAESEncryptAndDecrypt()
6969
}
7070

7171
[TestMethod]
72-
public void TestECEncryptAndDecrypt()
72+
public void TestEcdhEncryptAndDecrypt()
7373
{
7474
NEP6Wallet wallet = new NEP6Wallet("", ProtocolSettings.Default);
7575
wallet.Unlock("1");
7676
wallet.CreateAccount();
77-
WalletAccount account = wallet.GetAccounts().ToArray()[0];
78-
KeyPair key = account.GetKey();
77+
wallet.CreateAccount();
78+
WalletAccount account1 = wallet.GetAccounts().ToArray()[0];
79+
KeyPair key1 = account1.GetKey();
80+
WalletAccount account2 = wallet.GetAccounts().ToArray()[1];
81+
KeyPair key2 = account2.GetKey();
82+
Console.WriteLine($"Account:{1},privatekey:{key1.PrivateKey.ToHexString()},publicKey:{key1.PublicKey.ToArray().ToHexString()}");
83+
Console.WriteLine($"Account:{2},privatekey:{key2.PrivateKey.ToHexString()},publicKey:{key2.PublicKey.ToArray().ToHexString()}");
7984
var message = Encoding.ASCII.GetBytes("hello world");
80-
var cypher = Neo.Cryptography.Helper.ECEncrypt(message, key.PublicKey);
81-
var m = Neo.Cryptography.Helper.ECDecrypt(cypher, key);
82-
var message2 = Encoding.ASCII.GetString(m);
83-
Assert.AreEqual("hello world", message2);
85+
var cypher1 = Neo.Cryptography.Helper.EcdhEncrypt(message, key1, key2.PublicKey);
86+
var cypher2 = Neo.Cryptography.Helper.EcdhDecrypt(cypher1, key2, key1.PublicKey);
87+
Assert.AreEqual("hello world", Encoding.ASCII.GetString(cypher2));
8488
}
8589

8690
[TestMethod]

0 commit comments

Comments
 (0)