diff --git a/Makefile b/Makefile index 039f573..b613ee0 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ EXE_DIR=bin SRC_SRC=fp.cpp bn_c256.cpp bn_c384.cpp bn_c512.cpp she_c256.cpp TEST_SRC=fp_test.cpp ec_test.cpp fp_util_test.cpp window_method_test.cpp elgamal_test.cpp fp_tower_test.cpp gmp_test.cpp bn_test.cpp bn384_test.cpp glv_test.cpp paillier_test.cpp she_test.cpp vint_test.cpp bn512_test.cpp ecdsa_test.cpp conversion_test.cpp 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+=aggregate_sig_test.cpp vector_test.cpp TEST_SRC+=bls12_test.cpp TEST_SRC+=ecdsa_c_test.cpp ifeq ($(CPU),x86-64) diff --git a/include/mcl/bn.hpp b/include/mcl/bn.hpp index 04397f6..1070c44 100644 --- a/include/mcl/bn.hpp +++ b/include/mcl/bn.hpp @@ -10,6 +10,7 @@ #include #include #include +#include /* set bit size of Fp and Fr @@ -105,7 +106,7 @@ void Frobenius3(G2& D, const G2& S); namespace local { -typedef std::vector SignVec; +typedef mcl::Vector SignVec; inline size_t getPrecomputeQcoeffSize(const SignVec& sv) { @@ -1707,6 +1708,13 @@ inline void precomputeG2(std::vector& Qcoeff, const G2& Q) Qcoeff.resize(BN::param.precomputedQcoeffSize); precomputeG2(Qcoeff.data(), Q); } +inline bool precomputeG2(mcl::Vector& Qcoeff, const G2& Q) +{ + bool b = Qcoeff.resize(BN::param.precomputedQcoeffSize); + if (!b) return false; + precomputeG2(Qcoeff.data(), Q); + return true; +} inline void precomputedMillerLoop(Fp12& f, const G1& P_, const Fp6* Qcoeff) { G1 P(P_); @@ -1747,6 +1755,10 @@ inline void precomputedMillerLoop(Fp12& f, const G1& P, const std::vector& { precomputedMillerLoop(f, P, Qcoeff.data()); } +inline void precomputedMillerLoop(Fp12& f, const G1& P, const mcl::Vector& Qcoeff) +{ + precomputedMillerLoop(f, P, Qcoeff.data()); +} /* f = MillerLoop(P1, Q1) x MillerLoop(P2, Q2) */ @@ -1805,6 +1817,10 @@ inline void precomputedMillerLoop2(Fp12& f, const G1& P1, const std::vector { precomputedMillerLoop2(f, P1, Q1coeff.data(), P2, Q2coeff.data()); } +inline void precomputedMillerLoop2(Fp12& f, const G1& P1, const mcl::Vector& Q1coeff, const G1& P2, const mcl::Vector& Q2coeff) +{ + precomputedMillerLoop2(f, P1, Q1coeff.data(), P2, Q2coeff.data()); +} inline void mapToG1(bool *pb, G1& P, const Fp& x) { *pb = BN::param.mapTo.calcG1(P, x); } inline void mapToG2(bool *pb, G2& P, const Fp2& x) { *pb = BN::param.mapTo.calcG2(P, x); } inline void mapToG1(G1& P, const Fp& x) diff --git a/include/mcl/fp.hpp b/include/mcl/fp.hpp index 6c39d1f..4b6d848 100644 --- a/include/mcl/fp.hpp +++ b/include/mcl/fp.hpp @@ -6,9 +6,7 @@ @license modified new BSD license http://opensource.org/licenses/BSD-3-Clause */ -#include -#include -#include +#include #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable : 4127) diff --git a/include/mcl/gmp_util.hpp b/include/mcl/gmp_util.hpp index 47c1ab8..f27253c 100644 --- a/include/mcl/gmp_util.hpp +++ b/include/mcl/gmp_util.hpp @@ -9,7 +9,6 @@ */ #include #include -#include #include #include #include @@ -440,8 +439,13 @@ inline void getRand(mpz_class& z, size_t bitSize, fp::RandGen rg = fp::RandGen() assert(bitSize > 1); const size_t rem = bitSize & 31; const size_t n = (bitSize + 31) / 32; - std::vector buf(n); - rg.read(buf.data(), n * sizeof(buf[0])); + uint32_t buf[128]; + assert(n <= CYBOZU_NUM_OF_ARRAY(buf)); + if (n > CYBOZU_NUM_OF_ARRAY(buf)) { + z = 0; + return; + } + rg.read(buf, n * sizeof(buf[0])); uint32_t v = buf[n - 1]; if (rem == 0) { v |= 1U << 31; @@ -450,7 +454,7 @@ inline void getRand(mpz_class& z, size_t bitSize, fp::RandGen rg = fp::RandGen() v |= 1U << (rem - 1); } buf[n - 1] = v; - setArray(z, &buf[0], n); + setArray(z, buf, n); } inline void getRandPrime(mpz_class& z, size_t bitSize, fp::RandGen rg = fp::RandGen(), bool setSecondBit = false, bool mustBe3mod4 = false) @@ -482,9 +486,9 @@ template void convertToBinary(Vec& v, const mpz_class& x) { const size_t len = gmp::getBitSize(x); - v.clear(); + v.resize(len); for (size_t i = 0; i < len; i++) { - v.push_back(gmp::testBit(x, len - 1 - i) ? 1 : 0); + v[i] = gmp::testBit(x, len - 1 - i) ? 1 : 0; } } @@ -501,7 +505,8 @@ size_t getContinuousVal(const Vec& v, size_t pos, int val) template void convertToNAF(Vec& v, const Vec& in) { - v = in; +// v = in; + v.copy(in); size_t pos = v.size() - 1; for (;;) { size_t p = getContinuousVal(v, pos, 0); diff --git a/include/mcl/op.hpp b/include/mcl/op.hpp index c0c1098..b947284 100644 --- a/include/mcl/op.hpp +++ b/include/mcl/op.hpp @@ -8,6 +8,7 @@ */ #include #include +#include #ifndef MCL_MAX_BIT_SIZE #define MCL_MAX_BIT_SIZE 521 @@ -179,7 +180,7 @@ struct Op { Unit one[maxUnitSize]; Unit R2[maxUnitSize]; Unit R3[maxUnitSize]; - std::vector invTbl; + mcl::Vector invTbl; size_t N; size_t bitSize; bool (*fp_isZero)(const Unit*); diff --git a/include/mcl/vector.hpp b/include/mcl/vector.hpp new file mode 100644 index 0000000..eb0fb07 --- /dev/null +++ b/include/mcl/vector.hpp @@ -0,0 +1,77 @@ +#pragma once +/** + @file + @brief tiny vector class + @author MITSUNARI Shigeo(@herumi) + @license modified new BSD license + http://opensource.org/licenses/BSD-3-Clause +*/ +#include +#include +#include + +namespace mcl { +template +class Vector { + T *p_; + size_t n_; + Vector(const Vector&); + void operator=(const Vector&); +public: + Vector() : p_(0), n_(0) {} + ~Vector() + { + free(p_); + } + bool resize(size_t n) + { + if (n <= n_) { + n_ = n; + if (n == 0) { + free(p_); + p_ = 0; + } + return true; + } + T *q = (T*)malloc(sizeof(T) * n); + if (q == 0) return false; + for (size_t i = 0; i < n_; i++) { + q[i] = p_[i]; + } + free(p_); + p_ = q; + n_ = n; + return true; + } + bool copy(const Vector& rhs) + { + if (this == &rhs) return true; + if (n_ < rhs.n_) { + clear(); + if (!resize(rhs.n_)) return false; + } + for (size_t i = 0; i < rhs.n_; i++) { + p_[i] = rhs.p_[i]; + } + n_ = rhs.n_; + return true; + } + void clear() + { + free(p_); + p_ = 0; + n_ = 0; + } + size_t size() const { return n_; } + void swap(Vector& rhs) + { + std::swap(p_, rhs.p_); + std::swap(n_, rhs.n_); + } + T& operator[](size_t n) { return p_[n]; } + const T& operator[](size_t n) const { return p_[n]; } + T* data() { return p_; } + const T* data() const { return p_; } +}; +} // mcl + diff --git a/include/mcl/vint.hpp b/include/mcl/vint.hpp index 5530b46..1ffeba2 100644 --- a/include/mcl/vint.hpp +++ b/include/mcl/vint.hpp @@ -4,11 +4,10 @@ */ #include #include -#include -#include #include #include #include +#include #include #include #include @@ -619,34 +618,6 @@ void divNM(T *q, size_t qn, T *r, const T *x, size_t xn, const T *y, size_t yn) } } -template -class VariableBuffer { - std::vector v_; -public: - typedef T Unit; - VariableBuffer() - { - } - void clear() { v_.clear(); } - - /* - @note extended buffer may be not cleared - */ - void alloc(size_t n) - { - v_.resize(n); - } - void swap(VariableBuffer& rhs) { v_.swap(rhs.v_); } - - /* - *this = rhs - rhs may be destroyed - */ - size_t allocSize() const { return v_.size(); } - const T& operator[](size_t n) const { return v_[n]; } - T& operator[](size_t n) { return v_[n]; } -}; - template class Buffer { size_t allocSize_; @@ -680,6 +651,7 @@ public: std::swap(allocSize_, rhs.allocSize_); std::swap(ptr_, rhs.ptr_); } +#if 0 #if CYBOZU_CPP_VERSION >= CYBOZU_CPP_VERSION_CPP11 Buffer(Buffer&& rhs) noexcept : allocSize_(0) @@ -692,6 +664,7 @@ public: swap(rhs); return *this; } +#endif #endif void clear() { @@ -1789,7 +1762,6 @@ public: VintT operator>>(size_t n) const { VintT c = *this; c >>= n; return c; } }; -//typedef VintT > Vint; #ifdef MCL_VINT_FIXED_BUFFER typedef VintT > Vint; #else diff --git a/test/fp_util_test.cpp b/test/fp_util_test.cpp index 3e77b3b..b11311b 100644 --- a/test/fp_util_test.cpp +++ b/test/fp_util_test.cpp @@ -3,6 +3,7 @@ #include #include #include +#include CYBOZU_TEST_AUTO(arrayToHex) { diff --git a/test/vector_test.cpp b/test/vector_test.cpp new file mode 100644 index 0000000..d593e4c --- /dev/null +++ b/test/vector_test.cpp @@ -0,0 +1,32 @@ +#include +#include + +CYBOZU_TEST_AUTO(resize) +{ + mcl::Vector a, b; + CYBOZU_TEST_EQUAL(a.size(), 0); + CYBOZU_TEST_EQUAL(b.size(), 0); + + const size_t n = 3; + bool ok = a.resize(n); + CYBOZU_TEST_ASSERT(ok); + CYBOZU_TEST_EQUAL(n, a.size()); + for (size_t i = 0; i < n; i++) { + a[i] = i; + } + ok = b.copy(a); + CYBOZU_TEST_ASSERT(ok); + CYBOZU_TEST_EQUAL(b.size(), n); + CYBOZU_TEST_EQUAL_ARRAY(a.data(), b.data(), n); + + const size_t small = n - 1; + ok = b.resize(small); + CYBOZU_TEST_ASSERT(ok); + CYBOZU_TEST_EQUAL(b.size(), small); + CYBOZU_TEST_EQUAL_ARRAY(a.data(), b.data(), small); + const size_t large = n * 2; + ok = b.resize(large); + CYBOZU_TEST_ASSERT(ok); + CYBOZU_TEST_EQUAL(b.size(), large); + CYBOZU_TEST_EQUAL_ARRAY(a.data(), b.data(), small); +}