diff options
author | MITSUNARI Shigeo <herumi@nifty.com> | 2018-05-05 20:29:40 +0800 |
---|---|---|
committer | MITSUNARI Shigeo <herumi@nifty.com> | 2018-05-05 20:29:40 +0800 |
commit | be71d27d9aa5410a0c6c489c3a70320fc74d4d3e (patch) | |
tree | c6ee15bb1139270af85cc6f34ba6571c5d79b584 | |
parent | e1b875e3864cf8a0ccba8f5a0fc176b84a248df6 (diff) | |
download | dexon-mcl-be71d27d9aa5410a0c6c489c3a70320fc74d4d3e.tar.gz dexon-mcl-be71d27d9aa5410a0c6c489c3a70320fc74d4d3e.tar.zst dexon-mcl-be71d27d9aa5410a0c6c489c3a70320fc74d4d3e.zip |
add ecdsaPrecomputed
-rw-r--r-- | Makefile | 11 | ||||
-rw-r--r-- | include/mcl/ecdsa.h | 105 | ||||
-rw-r--r-- | include/mcl/ecdsa.hpp | 4 | ||||
-rw-r--r-- | src/ecdsa_c.cpp | 121 | ||||
-rw-r--r-- | test/ecdsa_c_test.cpp | 36 | ||||
-rw-r--r-- | test/ecdsa_test.cpp | 2 |
6 files changed, 275 insertions, 4 deletions
@@ -7,6 +7,7 @@ TEST_SRC=fp_test.cpp ec_test.cpp fp_util_test.cpp window_method_test.cpp elgamal TEST_SRC+=bn_c256_test.cpp bn_c384_test.cpp bn_c512_test.cpp she_c256_test.cpp she_c384_test.cpp TEST_SRC+=aggregate_sig_test.cpp TEST_SRC+=bls12_test.cpp +TEST_SRC+=ecdsa_c_test.cpp ifeq ($(CPU),x86-64) MCL_USE_XBYAK?=1 TEST_SRC+=mont_fp_test.cpp sq_test.cpp @@ -42,7 +43,8 @@ BN512_LIB=$(LIB_DIR)/libmclbn512.a BN512_SLIB=$(LIB_DIR)/lib$(BN512_SNAME).$(LIB_SUF) SHE256_LIB=$(LIB_DIR)/libmclshe256.a SHE384_LIB=$(LIB_DIR)/libmclshe384.a -all: $(MCL_LIB) $(MCL_SLIB) $(BN256_LIB) $(BN256_SLIB) $(BN384_LIB) $(BN384_SLIB) $(BN512_LIB) $(BN512_SLIB) $(SHE256_LIB) $(SHE384_lib) +ECDSA_LIB=$(LIB_DIR)/libmclecdsa.a +all: $(MCL_LIB) $(MCL_SLIB) $(BN256_LIB) $(BN256_SLIB) $(BN384_LIB) $(BN384_SLIB) $(BN512_LIB) $(BN512_SLIB) $(SHE256_LIB) $(SHE384_lib) $(ECDSA_LIB) #LLVM_VER=-3.8 LLVM_LLC=llc$(LLVM_VER) @@ -70,6 +72,7 @@ BN384_OBJ=$(OBJ_DIR)/bn_c384.o BN512_OBJ=$(OBJ_DIR)/bn_c512.o SHE256_OBJ=$(OBJ_DIR)/she_c256.o SHE384_OBJ=$(OBJ_DIR)/she_c384.o +ECDSA_OBJ=$(OBJ_DIR)/ecdsa_c.o FUNC_LIST=src/func.list MCL_USE_LLVM?=1 ifeq ($(MCL_USE_LLVM),1) @@ -120,6 +123,9 @@ $(SHE256_LIB): $(SHE256_OBJ) $(SHE384_LIB): $(SHE384_OBJ) $(AR) $@ $(SHE384_OBJ) +$(ECDSA_LIB): $(ECDSA_OBJ) + $(AR) $@ $(ECDSA_OBJ) + ifeq ($(OS),mac) MAC_LDFLAGS+=-l$(MCL_SNAME) -L./lib endif @@ -222,6 +228,9 @@ $(EXE_DIR)/she_c256_test.exe: $(OBJ_DIR)/she_c256_test.o $(SHE256_LIB) $(MCL_LIB $(EXE_DIR)/she_c384_test.exe: $(OBJ_DIR)/she_c384_test.o $(SHE384_LIB) $(MCL_LIB) $(PRE)$(CXX) $< -o $@ $(SHE384_LIB) $(MCL_LIB) $(LDFLAGS) +$(EXE_DIR)/ecdsa_c_test.exe: $(OBJ_DIR)/ecdsa_c_test.o $(ECDSA_LIB) $(MCL_LIB) + $(PRE)$(CXX) $< -o $@ $(ECDSA_LIB) $(MCL_LIB) $(LDFLAGS) + SAMPLE_EXE=$(addprefix $(EXE_DIR)/,$(addsuffix .exe,$(basename $(SAMPLE_SRC)))) sample: $(SAMPLE_EXE) $(MCL_LIB) diff --git a/include/mcl/ecdsa.h b/include/mcl/ecdsa.h new file mode 100644 index 0000000..daeb6be --- /dev/null +++ b/include/mcl/ecdsa.h @@ -0,0 +1,105 @@ +#pragma once +/** + @file + @brief C interface of ECDSA + @author MITSUNARI Shigeo(@herumi) + @license modified new BSD license + http://opensource.org/licenses/BSD-3-Clause +*/ +#include <stdint.h> // for uint64_t, uint8_t +#include <stdlib.h> // for size_t + +#if defined(_MSC_VER) + #ifdef ECDSA_DLL_EXPORT + #define ECDSA_DLL_API __declspec(dllexport) + #else + #define ECDSA_DLL_API __declspec(dllimport) + #ifndef ECDSA_NO_AUTOLINK + #pragma comment(lib, "mclecdsa.lib") + #endif + #endif +#elif defined(__EMSCRIPTEN__) + #define ECDSA_DLL_API __attribute__((used)) +#else + #define ECDSA_DLL_API +#endif + +#ifndef mclSize + #ifdef __EMSCRIPTEN__ + // avoid 64-bit integer + #define mclSize unsigned int + #define mclInt int + #else + // use #define for cgo + #define mclSize size_t + #define mclInt int64_t + #endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef ECDSA_NOT_DEFINE_STRUCT + +typedef struct ecdsaSecretKey ecdsaSecretKey; +typedef struct ecdsaPublicKey ecdsaPublicKey; +typedef struct ecdsaSignature ecdsaSignature; + +#else + +typedef struct { + uint64_t d[4]; +} ecdsaSecretKey; + +typedef struct { + uint64_t d[4 * 3]; +} ecdsaPublicKey; + +typedef struct { + uint64_t d[4 * 2]; +} ecdsaSignature; + +#endif + +struct ecdsaPrecomputedPublicKey; + +/* + init library + return 0 if success + @note not threadsafe +*/ +ECDSA_DLL_API int ecdsaInit(void); + +// return written byte size if success else 0 +ECDSA_DLL_API mclSize ecdsaSecretKeySerialize(void *buf, mclSize maxBufSize, const ecdsaSecretKey *sec); +ECDSA_DLL_API mclSize ecdsaPublicKeySerialize(void *buf, mclSize maxBufSize, const ecdsaPublicKey *pub); +ECDSA_DLL_API mclSize ecdsaSignatureSerialize(void *buf, mclSize maxBufSize, const ecdsaSignature *sig); + +// return read byte size if sucess else 0 +ECDSA_DLL_API mclSize ecdsaSecretKeyDeserialize(ecdsaSecretKey* sec, const void *buf, mclSize bufSize); +ECDSA_DLL_API mclSize ecdsaPublicKeyDeserialize(ecdsaPublicKey* pub, const void *buf, mclSize bufSize); +ECDSA_DLL_API mclSize ecdsaSignatureDeserialize(ecdsaSignature* sig, const void *buf, mclSize bufSize); + +// return 0 if success +ECDSA_DLL_API int ecdsaSecretKeySetByCSPRNG(ecdsaSecretKey *sec); + +ECDSA_DLL_API void ecdsaGetPublicKey(ecdsaPublicKey *pub, const ecdsaSecretKey *sec); + +ECDSA_DLL_API void ecdsaSign(ecdsaSignature *sig, const ecdsaSecretKey *sec, const void *m, mclSize size); + +// return 1 if valid +ECDSA_DLL_API int ecdsaVerify(const ecdsaSignature *sig, const ecdsaPublicKey *pub, const void *m, mclSize size); +ECDSA_DLL_API int ecdsaVerifyPrecomputed(const ecdsaSignature *sig, const ecdsaPrecomputedPublicKey *pub, const void *m, mclSize size); + +// return nonzero if success +ECDSA_DLL_API ecdsaPrecomputedPublicKey *ecdsaPrecomputedPublicKeyCreate(); +// call this function to avoid memory leak +ECDSA_DLL_API void ecdsaPrecomputedPublicKeyDestroy(ecdsaPrecomputedPublicKey *ppub); +// return 0 if success +ECDSA_DLL_API int ecdsaPrecomputedPublicKeyInit(ecdsaPrecomputedPublicKey *ppub, const ecdsaPublicKey *pub); + +#ifdef __cplusplus +} +#endif + diff --git a/include/mcl/ecdsa.hpp b/include/mcl/ecdsa.hpp index 2a06205..2be3274 100644 --- a/include/mcl/ecdsa.hpp +++ b/include/mcl/ecdsa.hpp @@ -136,7 +136,7 @@ struct Signature : public mcl::fp::Serializable<Signature> { } }; -inline bool sign(Signature& sig, const SecretKey& sec, const void *msg, size_t msgSize) +inline void sign(Signature& sig, const SecretKey& sec, const void *msg, size_t msgSize) { Zn& r = sig.r; Zn& s = sig.s; @@ -154,7 +154,7 @@ inline bool sign(Signature& sig, const SecretKey& sec, const void *msg, size_t m s += z; if (s.isZero()) continue; s /= k; - return true; + return; } } diff --git a/src/ecdsa_c.cpp b/src/ecdsa_c.cpp new file mode 100644 index 0000000..d91f1ba --- /dev/null +++ b/src/ecdsa_c.cpp @@ -0,0 +1,121 @@ +#define ECDSA_DLL_EXPORT +#include <mcl/ecdsa.h> +#include <mcl/ecdsa.hpp> + +using namespace mcl::ecdsa; + +static SecretKey *cast(ecdsaSecretKey *p) { return reinterpret_cast<SecretKey*>(p); } +static const SecretKey *cast(const ecdsaSecretKey *p) { return reinterpret_cast<const SecretKey*>(p); } + +static PublicKey *cast(ecdsaPublicKey *p) { return reinterpret_cast<PublicKey*>(p); } +static const PublicKey *cast(const ecdsaPublicKey *p) { return reinterpret_cast<const PublicKey*>(p); } + +static Signature *cast(ecdsaSignature *p) { return reinterpret_cast<Signature*>(p); } +static const Signature *cast(const ecdsaSignature *p) { return reinterpret_cast<const Signature*>(p); } + +static PrecomputedPublicKey *cast(ecdsaPrecomputedPublicKey *p) { return reinterpret_cast<PrecomputedPublicKey*>(p); } +static const PrecomputedPublicKey *cast(const ecdsaPrecomputedPublicKey *p) { return reinterpret_cast<const PrecomputedPublicKey*>(p); } + +int ecdsaInit(void) + try +{ + init(); + return 0; +} catch (std::exception&) { + return -1; +} + +template<class T> +mclSize serialize(void *buf, mclSize maxBufSize, const T *x) + try +{ + return (mclSize)cast(x)->serialize(buf, maxBufSize); +} catch (std::exception&) { + return 0; +} + +mclSize ecdsaSecretKeySerialize(void *buf, mclSize maxBufSize, const ecdsaSecretKey *sec) +{ + return serialize(buf, maxBufSize, sec); +} +mclSize ecdsaPublicKeySerialize(void *buf, mclSize maxBufSize, const ecdsaPublicKey *pub) +{ + return serialize(buf, maxBufSize, pub); +} +mclSize ecdsaSignatureSerialize(void *buf, mclSize maxBufSize, const ecdsaSignature *sig) +{ + return serialize(buf, maxBufSize, sig); +} + +template<class T> +mclSize deserialize(T *x, const void *buf, mclSize bufSize) + try +{ + return (mclSize)cast(x)->deserialize(buf, bufSize); +} catch (std::exception&) { + return 0; +} + +mclSize ecdsaSecretKeyDeserialize(ecdsaSecretKey* sec, const void *buf, mclSize bufSize) +{ + return deserialize(sec, buf, bufSize); +} +mclSize ecdsaPublicKeyDeserialize(ecdsaPublicKey* pub, const void *buf, mclSize bufSize) +{ + return deserialize(pub, buf, bufSize); +} +mclSize ecdsaSignatureDeserialize(ecdsaSignature* sig, const void *buf, mclSize bufSize) +{ + return deserialize(sig, buf, bufSize); +} + +// return 0 if success +int ecdsaSecretKeySetByCSPRNG(ecdsaSecretKey *sec) + try +{ + cast(sec)->setByCSPRNG(); + return 0; +} catch (...) { + return -1; +} + +void ecdsaGetPublicKey(ecdsaPublicKey *pub, const ecdsaSecretKey *sec) +{ + getPublicKey(*cast(pub), *cast(sec)); +} + +void ecdsaSign(ecdsaSignature *sig, const ecdsaSecretKey *sec, const void *m, mclSize size) +{ + sign(*cast(sig), *cast(sec), m, size); +} + +int ecdsaVerify(const ecdsaSignature *sig, const ecdsaPublicKey *pub, const void *m, mclSize size) +{ + return verify(*cast(sig), *cast(pub), m, size); +} +int ecdsaVerifyPrecomputed(const ecdsaSignature *sig, const ecdsaPrecomputedPublicKey *ppub, const void *m, mclSize size) +{ + return verify(*cast(sig), *cast(ppub), m, size); +} + +ecdsaPrecomputedPublicKey *ecdsaPrecomputedPublicKeyCreate() + try +{ + return reinterpret_cast<ecdsaPrecomputedPublicKey*>(new PrecomputedPublicKey()); +} catch (...) { + return 0; +} + +void ecdsaPrecomputedPublicKeyDestroy(ecdsaPrecomputedPublicKey *ppub) +{ + delete cast(ppub); +} + +int ecdsaPrecomputedPublicKeyInit(ecdsaPrecomputedPublicKey *ppub, const ecdsaPublicKey *pub) + try +{ + cast(ppub)->init(*cast(pub)); + return 0; +} catch (...) { + return -1; +} diff --git a/test/ecdsa_c_test.cpp b/test/ecdsa_c_test.cpp new file mode 100644 index 0000000..d3b360f --- /dev/null +++ b/test/ecdsa_c_test.cpp @@ -0,0 +1,36 @@ +#include <mcl/ecdsa.h> +#include <cybozu/test.hpp> +#include <string.h> + +CYBOZU_TEST_AUTO(ecdsa) +{ + int ret; + ret = ecdsaInit(); + CYBOZU_TEST_EQUAL(ret, 0); + ecdsaSecretKey sec; + ecdsaPublicKey pub; + ecdsaPrecomputedPublicKey *ppub; + ecdsaSignature sig; + const char *msg = "hello"; + mclSize msgSize = strlen(msg); + + ret = ecdsaSecretKeySetByCSPRNG(&sec); + CYBOZU_TEST_EQUAL(ret, 0); + + ecdsaGetPublicKey(&pub, &sec); + ecdsaSign(&sig, &sec, msg, msgSize); + CYBOZU_TEST_ASSERT(ecdsaVerify(&sig, &pub, msg, msgSize)); + + ppub = ecdsaPrecomputedPublicKeyCreate(); + CYBOZU_TEST_ASSERT(ppub); + ret = ecdsaPrecomputedPublicKeyInit(ppub, &pub); + CYBOZU_TEST_EQUAL(ret, 0); + + CYBOZU_TEST_ASSERT(ecdsaVerifyPrecomputed(&sig, ppub, msg, msgSize)); + + sig.d[0]++; + CYBOZU_TEST_ASSERT(!ecdsaVerify(&sig, &pub, msg, msgSize)); + CYBOZU_TEST_ASSERT(!ecdsaVerifyPrecomputed(&sig, ppub, msg, msgSize)); + + ecdsaPrecomputedPublicKeyDestroy(ppub); +} diff --git a/test/ecdsa_test.cpp b/test/ecdsa_test.cpp index 74efc0f..332c9ee 100644 --- a/test/ecdsa_test.cpp +++ b/test/ecdsa_test.cpp @@ -24,7 +24,7 @@ CYBOZU_TEST_AUTO(ecdsa) getPublicKey(pub, sec); Signature sig; const std::string msg = "hello"; - CYBOZU_TEST_ASSERT(sign(sig, sec, msg.c_str(), msg.size())); + sign(sig, sec, msg.c_str(), msg.size()); CYBOZU_TEST_ASSERT(verify(sig, pub, msg.c_str(), msg.size())); sig.s += 1; CYBOZU_TEST_ASSERT(!verify(sig, pub, msg.c_str(), msg.size())); |