Skip to content

Commit 778feed

Browse files
doubiliushargonJim8yerikzhangnicolegys
authoredSep 15, 2021
add ecc encrypt&decrypt (#2597)
* add ecc encrypt&dencrypt * change to keypair * check IsInfinity * Clean format * format * Revert "format" This reverts commit 80d26ca. * change to GCM * format * Update src/neo/Cryptography/Helper.cs Co-authored-by: Jinghui Liao <jinghui@wayne.edu> * improve * Update src/neo/Cryptography/Helper.cs Co-authored-by: Jinghui Liao <jinghui@wayne.edu> * Update src/neo/Cryptography/Helper.cs Co-authored-by: Jinghui Liao <jinghui@wayne.edu> * change to ecdh * improve * Update tests/neo.UnitTests/Cryptography/UT_Cryptography_Helper.cs Co-authored-by: Nicole <43694095+nicolegys@users.noreply.github.com> * Add using * Optimize * Optimize Co-authored-by: Shargon <shargon@gmail.com> Co-authored-by: Jinghui Liao <jinghui@wayne.edu> Co-authored-by: Erik Zhang <erik@neo.org> Co-authored-by: Nicole <43694095+nicolegys@users.noreply.github.com>
1 parent c8604f4 commit 778feed

File tree

2 files changed

+96
-0
lines changed

2 files changed

+96
-0
lines changed
 

‎src/neo/Cryptography/Helper.cs

+51
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
using Neo.IO;
1212
using Neo.Network.P2P.Payloads;
13+
using Neo.Wallets;
1314
using System;
1415
using System.Buffers.Binary;
1516
using System.Collections.Generic;
@@ -18,6 +19,8 @@
1819
using System.Security;
1920
using System.Security.Cryptography;
2021
using System.Text;
22+
using static Neo.Helper;
23+
using ECPoint = Neo.Cryptography.ECC.ECPoint;
2124

2225
namespace Neo.Cryptography
2326
{
@@ -119,6 +122,54 @@ public static byte[] Sha256(this Span<byte> value)
119122
return Sha256((ReadOnlySpan<byte>)value);
120123
}
121124

125+
public static byte[] AES256Encrypt(this byte[] plainData, byte[] key, byte[] nonce, byte[] associatedData = null)
126+
{
127+
if (nonce.Length != 12) throw new ArgumentOutOfRangeException(nameof(nonce));
128+
var cipherBytes = new byte[plainData.Length];
129+
var tag = new byte[16];
130+
using var cipher = new AesGcm(key);
131+
cipher.Encrypt(nonce, plainData, cipherBytes, tag, associatedData);
132+
return Concat(nonce, cipherBytes, tag);
133+
}
134+
135+
public static byte[] AES256Decrypt(this byte[] encryptedData, byte[] key, byte[] associatedData = null)
136+
{
137+
ReadOnlySpan<byte> encrypted = encryptedData;
138+
var nonce = encrypted[..12];
139+
var cipherBytes = encrypted[12..^16];
140+
var tag = encrypted[^16..];
141+
var decryptedData = new byte[cipherBytes.Length];
142+
using var cipher = new AesGcm(key);
143+
cipher.Decrypt(nonce, cipherBytes, tag, decryptedData, associatedData);
144+
return decryptedData;
145+
}
146+
147+
public static byte[] ECDHDeriveKey(KeyPair local, ECPoint remote)
148+
{
149+
ReadOnlySpan<byte> pubkey_local = local.PublicKey.EncodePoint(false);
150+
ReadOnlySpan<byte> pubkey_remote = remote.EncodePoint(false);
151+
using ECDiffieHellman ecdh1 = ECDiffieHellman.Create(new ECParameters
152+
{
153+
Curve = ECCurve.NamedCurves.nistP256,
154+
D = local.PrivateKey,
155+
Q = new System.Security.Cryptography.ECPoint
156+
{
157+
X = pubkey_local[1..][..32].ToArray(),
158+
Y = pubkey_local[1..][32..].ToArray()
159+
}
160+
});
161+
using ECDiffieHellman ecdh2 = ECDiffieHellman.Create(new ECParameters
162+
{
163+
Curve = ECCurve.NamedCurves.nistP256,
164+
Q = new System.Security.Cryptography.ECPoint
165+
{
166+
X = pubkey_remote[1..][..32].ToArray(),
167+
Y = pubkey_remote[1..][32..].ToArray()
168+
}
169+
});
170+
return ecdh1.DeriveKeyMaterial(ecdh2.PublicKey).Sha256();//z = r * P = r* k * G
171+
}
172+
122173
internal static bool Test(this BloomFilter filter, Transaction tx)
123174
{
124175
if (filter.Check(tx.Hash.ToArray())) return true;

‎tests/neo.UnitTests/Cryptography/UT_Cryptography_Helper.cs

+45
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
using Neo.IO;
55
using Neo.Network.P2P.Payloads;
66
using Neo.SmartContract;
7+
using Neo.Wallets;
8+
using Neo.Wallets.NEP6;
79
using System;
10+
using System.Linq;
811
using System.Security;
912
using System.Text;
1013

@@ -48,6 +51,48 @@ public void TestRIPEMD160()
4851
resultStr.Should().Be("98c615784ccb5fe5936fbc0cbe9dfdb408d92f0f");
4952
}
5053

54+
[TestMethod]
55+
public void TestAESEncryptAndDecrypt()
56+
{
57+
NEP6Wallet wallet = new NEP6Wallet("", ProtocolSettings.Default);
58+
wallet.Unlock("1");
59+
wallet.CreateAccount();
60+
WalletAccount account = wallet.GetAccounts().ToArray()[0];
61+
KeyPair key = account.GetKey();
62+
Random random = new Random();
63+
byte[] nonce = new byte[12];
64+
random.NextBytes(nonce);
65+
var cypher = Neo.Cryptography.Helper.AES256Encrypt(Encoding.UTF8.GetBytes("hello world"), key.PrivateKey, nonce);
66+
var m = Neo.Cryptography.Helper.AES256Decrypt(cypher, key.PrivateKey);
67+
var message2 = Encoding.UTF8.GetString(m);
68+
Assert.AreEqual("hello world", message2);
69+
}
70+
71+
[TestMethod]
72+
public void TestEcdhEncryptAndDecrypt()
73+
{
74+
NEP6Wallet wallet = new NEP6Wallet("", ProtocolSettings.Default);
75+
wallet.Unlock("1");
76+
wallet.CreateAccount();
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()}");
84+
var secret1 = Neo.Cryptography.Helper.ECDHDeriveKey(key1, key2.PublicKey);
85+
var secret2 = Neo.Cryptography.Helper.ECDHDeriveKey(key2, key1.PublicKey);
86+
Assert.AreEqual(secret1.ToHexString(), secret2.ToHexString());
87+
var message = Encoding.ASCII.GetBytes("hello world");
88+
Random random = new Random();
89+
byte[] nonce = new byte[12];
90+
random.NextBytes(nonce);
91+
var cypher = message.AES256Encrypt(secret1, nonce);
92+
cypher.AES256Decrypt(secret2);
93+
Assert.AreEqual("hello world", Encoding.ASCII.GetString(cypher.AES256Decrypt(secret2)));
94+
}
95+
5196
[TestMethod]
5297
public void TestTest()
5398
{

0 commit comments

Comments
 (0)
Please sign in to comment.