aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMITSUNARI Shigeo <herumi@nifty.com>2018-05-05 20:29:40 +0800
committerMITSUNARI Shigeo <herumi@nifty.com>2018-05-05 20:29:40 +0800
commitbe71d27d9aa5410a0c6c489c3a70320fc74d4d3e (patch)
treec6ee15bb1139270af85cc6f34ba6571c5d79b584
parente1b875e3864cf8a0ccba8f5a0fc176b84a248df6 (diff)
downloaddexon-mcl-be71d27d9aa5410a0c6c489c3a70320fc74d4d3e.tar.gz
dexon-mcl-be71d27d9aa5410a0c6c489c3a70320fc74d4d3e.tar.zst
dexon-mcl-be71d27d9aa5410a0c6c489c3a70320fc74d4d3e.zip
add ecdsaPrecomputed
-rw-r--r--Makefile11
-rw-r--r--include/mcl/ecdsa.h105
-rw-r--r--include/mcl/ecdsa.hpp4
-rw-r--r--src/ecdsa_c.cpp121
-rw-r--r--test/ecdsa_c_test.cpp36
-rw-r--r--test/ecdsa_test.cpp2
6 files changed, 275 insertions, 4 deletions
diff --git a/Makefile b/Makefile
index d5bd408..0b0d6dd 100644
--- a/Makefile
+++ b/Makefile
@@ -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()));