Skip to content

Commit

Permalink
add mmh3
Browse files Browse the repository at this point in the history
  • Loading branch information
ixje authored Aug 8, 2022
2 parents 1011333 + 0aea9cd commit 393befb
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 6 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[submodule "microecc"]
path = microecc
url = https://github.com/kmackay/micro-ecc
[submodule "smhasher"]
path = smhasher
url = https://github.com/aappleby/smhasher.git
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ FetchContent_Declare(
)
FetchContent_MakeAvailable(pybind11)

pybind11_add_module(neo3crypto python-bindings.cpp ecc.h ecc.cpp microecc/uECC.h microecc/uECC.c)
pybind11_add_module(neo3crypto python-bindings.cpp ecc.h ecc.cpp microecc/uECC.h microecc/uECC.c smhasher/src/MurmurHash3.h smhasher/src/MurmurHash3.cpp)
if(MSVC)
target_link_libraries(neo3crypto PRIVATE advapi32)
endif()
9 changes: 6 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

NEO3VM
------
C++ implementations of cryptographic functions used in the NEO3 Blockchain with bindings for Python 3.7 & 3.8.
C++ implementations of cryptographic functions used in the NEO3 Blockchain with bindings for Python 3.8, 3.9 & 3.10.

The current version only supports EllipticCurve functions by wrapping `micro-ecc <https://github.com/kmackay/micro-ecc>`_)
The current version supports `mmh3` and EllipticCurve functions by wrapping (part of `smhasher <https://github.com/aappleby/smhasher>`_ and `micro-ecc <https://github.com/kmackay/micro-ecc>`_)
and exposing helper classes. ``SECP256R1`` (a.k.a ``NIST256P``) and ``SECP256K1`` are the only curves exposed, but others can easily
be enabled if needed.

Expand All @@ -29,7 +29,7 @@ Usage

import hashlib
import os
from neo3crypto import ECCCurve, ECPoint, sign, verify
from neo3crypto import ECCCurve, ECPoint, sign, verify, mmh3_hash_bytes, mmh3_hash


curve = ECCCurve.SECP256R1
Expand All @@ -39,6 +39,9 @@ Usage
signature = sign(private_key, b'message', curve, hashlib.sha256)
assert ecdsa.verify(signature, b'message', public_key, hashlib.sha256) == True

assert mmh3_hash("foo", signed=False) == 4138058784
assert bytes.fromhex("0bc59d0ad25fde2982ed65af61227a0e") == mmh3_hash_bytes("hello", 123)

Any hashlib hashing function can be used. Further documentation on the classes can be queried from the extension module
using ``help(neo3crypto)``.

Expand Down
50 changes: 49 additions & 1 deletion python-bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,21 @@
#include "ecc.h"
#include <utility>
#include <vector>
#include "smhasher/src/MurmurHash3.h"

// for mmh3
#if defined(_MSC_VER)
typedef signed __int8 int8_t;
typedef signed __int32 int32_t;
typedef signed __int64 int64_t;
typedef unsigned __int8 uint8_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
// Other compilers
#else // defined(_MSC_VER)
#include <stdint.h>
#endif // !defined(_MSC_VER)
// end for mmh3

namespace py = pybind11;
using namespace neo3crypto;
Expand Down Expand Up @@ -106,4 +121,37 @@ PYBIND11_MODULE(neo3crypto, m) {
auto message_hash = to_vector(hash_result);
return verify(to_vector(signature), message_hash, public_key);
}, py::arg("signature"), py::arg("message"), py::arg("public_key"), py::arg("hash_func"));
}

m.def("mmh3_hash", [](const std::string &s, uint32_t seed, bool is_signed) {
const char *target_str = s.data();
int32_t iresult[1];
uint32_t uresult[1];
if (is_signed)
MurmurHash3_x86_32(target_str, s.length(), seed, iresult);
else
MurmurHash3_x86_32(target_str, s.length(), seed, uresult);

// depending on the input type PYBIND will use PyLong_FromLong or PyLong_FromUnsignedLong
// can't seem to specify this as a param?
if (is_signed) {
return py::int_(iresult[0]);
} else {
return py::int_(uresult[0]);
}
}, py::arg("value"), py::arg("seed") = 0, py::arg("signed") = true);
m.def("mmh3_hash_bytes", [](const std::string &s, uint32_t seed, bool x64arch) {
const char *target_str = s.data();
uint32_t result[4];

if (x64arch) {
MurmurHash3_x64_128(target_str, s.length(), seed, result);
} else {
MurmurHash3_x86_128(target_str, s.length(), seed, result);
}

char bytes[16];
memcpy(bytes, result, 16);
return py::bytes(bytes, 16);
}, py::arg("value"), py::arg("seed") = 0, py::arg("x64arch") = true);
}

5 changes: 4 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,16 @@ def build_extension(self, ext):
description="Native crypto functions for the NEO 3 Blockchain",
long_description=readme,
long_description_content_type="text/x-rst",
version='0.2.2',
version='0.3',
license='MIT',
url='https://github.com/CityOfZion/neo3crypto',
classifiers=[
'Development Status :: 4 - Beta',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
"Programming Language :: C++"
],
ext_modules=[CMakeExtension('neo3crypto')],
Expand Down
1 change: 1 addition & 0 deletions smhasher
Submodule smhasher added at 61a053

0 comments on commit 393befb

Please sign in to comment.