Skip to content

Commit

Permalink
Adding keccak256 (#2925)
Browse files Browse the repository at this point in the history
* Create codeql.yml

* Keccak256

* Delete .github/workflows/codeql.yml

* Update src/Neo/SmartContract/Native/CryptoLib.cs

* add more keccak256 test cases as required

* Create codeql.yml

* Keccak256

* Delete .github/workflows/codeql.yml

* Update src/Neo/SmartContract/Native/CryptoLib.cs

* add more keccak256 test cases as required

* HF_Manticore

* Fix copyright

* Create codeql.yml

* Keccak256

* Delete .github/workflows/codeql.yml

* Update src/Neo/SmartContract/Native/CryptoLib.cs

* add more keccak256 test cases as required

* Create codeql.yml

* Keccak256

* Delete .github/workflows/codeql.yml

* Update src/Neo/SmartContract/Native/CryptoLib.cs

* add more keccak256 test cases as required

* HF_Manticore

* Fix copyright

* HF_Manticore

* Update CryptoLib.cs

* Update CryptoLib.cs

* Update UT_CryptoLib.cs

* Apply suggestions from code review

* clean usings

---------

Co-authored-by: Shargon <shargon@gmail.com>
  • Loading branch information
Jim8y and shargon committed Jan 11, 2024
1 parent 963c557 commit 8c9e0c6
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/Neo/Hardfork.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ namespace Neo
public enum Hardfork : byte
{
HF_Aspidochelone,
HF_Basilisk
HF_Basilisk,
HF_Cockatrice
}
}
16 changes: 16 additions & 0 deletions src/Neo/SmartContract/Native/CryptoLib.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

using Neo.Cryptography;
using Neo.Cryptography.ECC;
using Org.BouncyCastle.Crypto.Digests;
using System;
using System.Collections.Generic;

Expand Down Expand Up @@ -64,6 +65,21 @@ public static byte[] Murmur32(byte[] data, uint seed)
return murmur.ComputeHash(data);
}

/// <summary>
/// Computes the hash value for the specified byte array using the keccak256 algorithm.
/// </summary>
/// <param name="data">The input to compute the hash code for.</param>
/// <returns>Computed hash</returns>
[ContractMethod(Hardfork.HF_Cockatrice, CpuFee = 1 << 15)]
public static byte[] Keccak256(byte[] data)
{
KeccakDigest keccak = new(256);
keccak.BlockUpdate(data, 0, data.Length);
byte[] result = new byte[keccak.GetDigestSize()];
keccak.DoFinal(result, 0);
return result;
}

/// <summary>
/// Verifies that a digital signature is appropriate for the provided key and message using the ECDSA algorithm.
/// </summary>
Expand Down
93 changes: 93 additions & 0 deletions tests/Neo.UnitTests/SmartContract/Native/UT_CryptoLib.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using Neo.SmartContract;
using Neo.SmartContract.Native;
using Neo.VM;
using Org.BouncyCastle.Utilities.Encoders;

namespace Neo.UnitTests.SmartContract.Native
{
Expand Down Expand Up @@ -334,5 +335,97 @@ public void TestBls12381ScalarMul_Compat()
BLS12381PointType.G2Proj
);
}

/// <summary>
/// Keccak256 cases are verified in https://emn178.github.io/online-tools/keccak_256.html
/// </summary>
[TestMethod]
public void TestKeccak256_HelloWorld()
{
// Arrange
byte[] inputData = "Hello, World!"u8.ToArray();
string expectedHashHex = "acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f";

// Act
byte[] outputData = CryptoLib.Keccak256(inputData);
string outputHashHex = Hex.ToHexString(outputData);

// Assert
Assert.AreEqual(expectedHashHex, outputHashHex, "Keccak256 hash did not match expected value for 'Hello, World!'.");
}
[TestMethod]
public void TestKeccak256_Keccak()
{
// Arrange
byte[] inputData = "Keccak"u8.ToArray();
string expectedHashHex = "868c016b666c7d3698636ee1bd023f3f065621514ab61bf26f062c175fdbe7f2";

// Act
byte[] outputData = CryptoLib.Keccak256(inputData);
string outputHashHex = Hex.ToHexString(outputData);

// Assert
Assert.AreEqual(expectedHashHex, outputHashHex, "Keccak256 hash did not match expected value for 'Keccak'.");
}

[TestMethod]
public void TestKeccak256_Cryptography()
{
// Arrange
byte[] inputData = "Cryptography"u8.ToArray();
string expectedHashHex = "53d49d225dd2cfe77d8c5e2112bcc9efe77bea1c7aa5e5ede5798a36e99e2d29";

// Act
byte[] outputData = CryptoLib.Keccak256(inputData);
string outputHashHex = Hex.ToHexString(outputData);

// Assert
Assert.AreEqual(expectedHashHex, outputHashHex, "Keccak256 hash did not match expected value for 'Cryptography'.");
}

[TestMethod]
public void TestKeccak256_Testing123()
{
// Arrange
byte[] inputData = "Testing123"u8.ToArray();
string expectedHashHex = "3f82db7b16b0818a1c6b2c6152e265f682d5ebcf497c9aad776ad38bc39cb6ca";

// Act
byte[] outputData = CryptoLib.Keccak256(inputData);
string outputHashHex = Hex.ToHexString(outputData);

// Assert
Assert.AreEqual(expectedHashHex, outputHashHex, "Keccak256 hash did not match expected value for 'Testing123'.");
}

[TestMethod]
public void TestKeccak256_LongString()
{
// Arrange
byte[] inputData = "This is a longer string for Keccak256 testing purposes."u8.ToArray();
string expectedHashHex = "24115e5c2359f85f6840b42acd2f7ea47bc239583e576d766fa173bf711bdd2f";

// Act
byte[] outputData = CryptoLib.Keccak256(inputData);
string outputHashHex = Hex.ToHexString(outputData);

// Assert
Assert.AreEqual(expectedHashHex, outputHashHex, "Keccak256 hash did not match expected value for the longer string.");
}

[TestMethod]
public void TestKeccak256_BlankString()
{
// Arrange
byte[] inputData = ""u8.ToArray();
string expectedHashHex = "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470";

// Act
byte[] outputData = CryptoLib.Keccak256(inputData);
string outputHashHex = Hex.ToHexString(outputData);

// Assert
Assert.AreEqual(expectedHashHex, outputHashHex, "Keccak256 hash did not match expected value for blank string.");
}
}
}

0 comments on commit 8c9e0c6

Please sign in to comment.