Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
herumi committed May 17, 2024
2 parents 882951f + 5b91102 commit a026d3a
Show file tree
Hide file tree
Showing 16 changed files with 671 additions and 269 deletions.
32 changes: 32 additions & 0 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Contributing to mcl

Thank you for considering contributing to the mcl project. This document provides guidelines on how to contribute.

## Bug Reports and Feedback

If you find a bug, have a feature request, or have questions, please open an issue. Include the following information:

- Detailed description of the problem
- Steps to reproduce
- Expected behavior
- Actual behavior
- Environment details (OS, compiler version, etc.)

## Creating Pull Requests

If you want to add features or make fixes, follow these steps to create a pull request:

1. Fork the repository
2. Create a new branch: `git checkout -b my-feature-branch`
3. Make your changes
4. Run tests and ensure all tests pass
5. Commit your changes: `git commit -am 'Add new feature'`
6. Push the branch: `git push origin my-feature-branch`
7. Create a pull request

When creating a pull request, clearly describe the changes and include any related issue numbers.

## License

mcl is released under the BSD-3-Clause License. Any code contributions will be licensed under the same license.

3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -283,8 +283,10 @@ endif()
foreach(bit IN ITEMS 256 384 384_256)
if (MCL_STATIC_LIB)
add_library(mclbn${bit} STATIC src/bn_c${bit}.cpp)
target_link_libraries(mclbn${bit} PUBLIC mcl::mcl_st)
else()
add_library(mclbn${bit} SHARED src/bn_c${bit}.cpp)
target_link_libraries(mclbn${bit} PUBLIC mcl::mcl)
endif()
add_library(mcl::mclbn${bit} ALIAS mclbn${bit})
set_target_properties(mclbn${bit} PROPERTIES
Expand All @@ -294,7 +296,6 @@ foreach(bit IN ITEMS 256 384 384_256)
target_compile_options(mclbn${bit} PRIVATE ${MCL_COMPILE_OPTIONS})
target_compile_definitions(mclbn${bit}
PUBLIC MCL_NO_AUTOLINK MCLBN_NO_AUTOLINK)
target_link_libraries(mclbn${bit} PUBLIC mcl::mcl)
set_target_properties(mclbn${bit} PROPERTIES
VERSION ${mcl_VERSION}
SOVERSION ${mcl_VERSION_MAJOR})
Expand Down
7 changes: 7 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,13 @@ bin/llvm_test64.exe: test/llvm_test.cpp src/base64.ll
bin/llvm_test32.exe: test/llvm_test.cpp src/base32.ll
$(CLANG) -o $@ -Ofast -DNDEBUG -Wall -Wextra -I ./include test/llvm_test.cpp src/base32.ll -m32

$(OBJ_DIR)/$(MSM)_test.o: src/$(MSM).cpp
$(PRE)$(CXX) -c $< -o $@ $(CFLAGS) -mavx512f -mavx512ifma -std=c++11 $(CFLAGS_USER) -DMCL_MSM_TEST
MSM_TEST_OBJ=$(OBJ_DIR)/$(MSM)_test.o $(filter-out $(OBJ_DIR)/msm_avx.o,$(LIB_OBJ))
$(EXE_DIR)/msm_test.exe: $(MSM_TEST_OBJ)
$(PRE)$(CXX) -o $@ $(LDFLAGS) $(MSM_TEST_OBJ)
-include $(OBJ_DIR)/msm_test.d

make_tbl:
$(MAKE) ../bls/src/qcoeff-bn254.hpp

Expand Down
8 changes: 4 additions & 4 deletions api.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ r = |G1| = |G2| = |GT|
curveType | b| r and p |
------------|--|------------------|
BN254 | 2|r = 0x2523648240000001ba344d8000000007ff9f800000000010a10000000000000d <br> p = 0x2523648240000001ba344d80000000086121000000000013a700000000000013 |
BN_SNARK1|3|r = 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47 <br> p = 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47|
BN_SNARK1|3|r = 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001 <br> p = 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47|
BLS12-381 | 4|r = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001 <br> p = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab |
BN381 | 2|r = 0x240026400f3d82b2e42de125b00158405b710818ac000007e0042f008e3e00000000001080046200000000000000000d <br> p = 0x240026400f3d82b2e42de125b00158405b710818ac00000840046200950400000000001380052e000000000000000013 |

Expand Down Expand Up @@ -253,7 +253,7 @@ C++
T x = <integer literal>;
```

### Set `buf[0..bufSize-1]` to `x` with masking according to the following way.
### Set `bufSize` bytes `buf` to `x` with masking according to the following way.
```
int mclBnFp_setLittleEndian(mclBnFp *x, const void *buf, mclSize bufSize);
int mclBnFr_setLittleEndian(mclBnFr *x, const void *buf, mclSize bufSize);
Expand All @@ -270,7 +270,7 @@ T::setArrayMask(const uint8_t *buf, size_t n);

- always return 0

### Set (`buf[0..bufSize-1]` mod `p` or `r`) to `x`.
### Set `bufSize` bytes `buf` of mod `p` or `r` to `x`.
```
int mclBnFp_setLittleEndianMod(mclBnFp *x, const void *buf, mclSize bufSize);
int mclBnFr_setLittleEndianMod(mclBnFr *x, const void *buf, mclSize bufSize);
Expand All @@ -281,7 +281,7 @@ C++
T::setLittleEndianMod(const uint8_t *buf, mclSize bufSize);
```

- return 0 if bufSize <= (sizeof(*x) * 8 * 2) else -1
- return 0 if bufSize <= (sizeof(T) * 2) else -1

### Get little-endian byte sequence `buf` corresponding to `x`
```
Expand Down
3 changes: 3 additions & 0 deletions include/mcl/bn.h
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,9 @@ MCLBN_DLL_API void mclBnG1_mulVec(mclBnG1 *z, mclBnG1 *x, const mclBnFr *y, mclS
MCLBN_DLL_API void mclBnG2_mulVec(mclBnG2 *z, mclBnG2 *x, const mclBnFr *y, mclSize n);
MCLBN_DLL_API void mclBnGT_powVec(mclBnGT *z, const mclBnGT *x, const mclBnFr *y, mclSize n);

// x[i] *= y[i]
MCLBN_DLL_API void mclBnG1_mulEach(mclBnG1 *x, const mclBnFr *y, mclSize n);

MCLBN_DLL_API void mclBn_pairing(mclBnGT *z, const mclBnG1 *x, const mclBnG2 *y);
MCLBN_DLL_API void mclBn_finalExp(mclBnGT *y, const mclBnGT *x);
MCLBN_DLL_API void mclBn_millerLoop(mclBnGT *z, const mclBnG1 *x, const mclBnG2 *y);
Expand Down
42 changes: 14 additions & 28 deletions include/mcl/bn.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ namespace msm {

bool initMsm(const mcl::CurveParam& cp, const Param *param);
void mulVecAVX512(Unit *_P, Unit *_x, const Unit *_y, size_t n);
void mulEachAVX512(Unit *_x, const Unit *_y, size_t n);

} // mcl::msm
#endif
Expand Down Expand Up @@ -692,9 +693,12 @@ struct GLV1 : mcl::GLV1T<G1, Fr> {
const mpz_class& r = Fr::getOp().mp;
B[0][0] = z * z - 1; // L
v0 = (B[0][0] << rBitSize) / r;
if (curveType == BLS12_381.curveType && MCL_SIZEOF_UNIT == 8) {
#if MCL_SIZEOF_UNIT == 8
if (curveType == BLS12_381.curveType) {
optimizedSplit = optimizedSplitForBLS12_381;
} else {
} else
#endif
{
optimizedSplit = splitForBLS12;
}
} else {
Expand Down Expand Up @@ -723,38 +727,19 @@ struct GLV1 : mcl::GLV1T<G1, Fr> {
b = (x * v0) >> rBitSize;
a = x - b * B[0][0];
}
#if MCL_SIZEOF_UNIT == 8
static inline void optimizedSplitForBLS12_381(mpz_class u[2], const mpz_class& x)
{
assert(sizeof(Unit) == 8);
/*
z = -0xd201000000010000
L = z^2-1 = 0xac45a4010001a40200000000ffffffff
r = L^2+L+1 = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001
s=255
v = 0xbe35f678f00fd56eb1fb72917b67f718
*/
mpz_class& a = u[0];
mpz_class& b = u[1];
static const uint64_t Lv[] = { 0x00000000ffffffff, 0xac45a4010001a402 };
static const uint64_t vv[] = { 0xb1fb72917b67f718, 0xbe35f678f00fd56e };
static const size_t n = 128 / mcl::UnitBitSize;
Unit t[n*3];
// n = 128 bit
// t[n*3] = x[n*2] * vv[n]
mcl::bint::mulNM(t, gmp::getUnit(x), n*2, (const Unit*)vv, n);
// t[n] <- t[n*3]
mcl::bint::shrT<n+1>(t, t+n*2-1, mcl::UnitBitSize-1); // >>255
Unit xa[n*2], a[2], b[2];
mcl::gmp::getArray(xa, n*2, x);
ec::local::optimizedSplitRawForBLS12_381(a, b, xa);
bool dummy;
gmp::setArray(&dummy, b, t, n);
Unit t2[n*2];
// t2[n*2] = t[n] * Lv[n]
// Do not overlap I/O buffers on pre-Broadwell CPUs.
mcl::bint::mulT<n>(t2, t, (const Unit*)Lv);
// t[n] = x[n*2] - t2[n*2]
mcl::bint::subT<n>(t, gmp::getUnit(x), t2);
gmp::setArray(&dummy, a, t, n);
gmp::setArray(&dummy, u[0], a, n);
gmp::setArray(&dummy, u[1], b, n);
(void)dummy;
}
#endif
};

/*
Expand Down Expand Up @@ -2314,6 +2299,7 @@ inline void init(bool *pb, const mcl::CurveParam& cp = mcl::BN254, fp::Mode mode
if (sizeof(Unit) == 8 && sizeof(Fp) == sizeof(mcl::msm::FpA) && sizeof(Fr) == sizeof(mcl::msm::FrA)) {
if (mcl::msm::initMsm(cp, &para)) {
G1::setMulVecOpti(mcl::msm::mulVecAVX512);
G1::setMulEachOpti(mcl::msm::mulEachAVX512);
}
}
#endif
Expand Down
81 changes: 74 additions & 7 deletions include/mcl/ec.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,10 +242,54 @@ void normalizeVecT(Eout& Q, Ein& P, size_t n, size_t N = 256)
}
}

#if MCL_SIZEOF_UNIT == 8
/*
split x to (a, b) such that x = a + b L where 0 <= a, b <= L, 0 <= x <= r-1 = L^2+L
if adj is true, then 0 <= a < L, 0 <= b <= L+1
*/
inline void optimizedSplitRawForBLS12_381(Unit a[2], Unit b[2], const Unit x[4])
{
const bool adj = false;
assert(sizeof(Unit) == 8);
/*
z = -0xd201000000010000
L = z^2-1 = 0xac45a4010001a40200000000ffffffff
r = L^2+L+1 = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001
s=255
v = (1<<s)//L = 0xbe35f678f00fd56eb1fb72917b67f718
*/
static const uint64_t L[] = { 0x00000000ffffffff, 0xac45a4010001a402 };
static const uint64_t v[] = { 0xb1fb72917b67f718, 0xbe35f678f00fd56e };
static const uint64_t one[] = { 1, 0 };
static const size_t n = 128 / mcl::UnitBitSize;
Unit t[n*3];
// n = 128 bit
// t[n*3] = x[n*2] * v[n]
mcl::bint::mulNM(t, x, n*2, v, n);
// b[n] = t[n*3]>>255
mcl::bint::shrT<n+1>(t, t+n*2-1, mcl::UnitBitSize-1); // >>255
b[0] = t[0];
b[1] = t[1];
Unit t2[n*2];
// t2[n*2] = t[n] * L[n]
// Do not overlap I/O buffers on pre-Broadwell CPUs.
mcl::bint::mulT<n>(t2, t, L);
// a[n] = x[n*2] - t2[n*2]
mcl::bint::subT<n>(a, x, t2);
if (adj) {
if (mcl::bint::cmpEqT<n>(a, L)) {
// if a == L then b = b + 1 and a = 0
mcl::bint::addT<n>(b, b, one);
mcl::bint::clearT<n>(a);
}
}
}
#endif

} // mcl::ec::local

// [X:Y:Z] as Proj = (X/Z, Y/Z) as Affine = [XZ:YZ^2:Z] as Jacobi
// Remark. convert P = [1:0:0] to Q = [0:0:0]
// Remark. convert P = [*:*:0] to Q = [0:0:0]
template<class E>
void ProjToJacobi(E& Q, const E& P)
{
Expand All @@ -257,7 +301,7 @@ void ProjToJacobi(E& Q, const E& P)
}

// [X:Y:Z] as Jacobi = (X/Z^2, Y/Z^3) as Affine = [XZ:Y:Z^3] as Proj
// Remark. convert P = [1:1:0] to Q = [0:1:0]
// Remark. convert P = [*:1:0] to Q = [0:1:0]
template<class E>
void JacobiToProj(E& Q, const E& P)
{
Expand Down Expand Up @@ -1316,6 +1360,7 @@ class EcT : public fp::Serializable<EcT<_Fp, _Fr> > {
static mpz_class order_;
static bool (*mulVecGLV)(EcT& z, const EcT *xVec, const void *yVec, size_t n, bool constTime);
static void (*mulVecOpti)(Unit *z, Unit *xVec, const Unit *yVec, size_t n);
static void (*mulEachOpti)(Unit *xVec, const Unit *yVec, size_t n);
static bool (*isValidOrderFast)(const EcT& x);
/* default constructor is undefined value */
EcT() {}
Expand Down Expand Up @@ -1382,6 +1427,7 @@ class EcT : public fp::Serializable<EcT<_Fp, _Fr> > {
order_ = 0;
mulVecGLV = 0;
mulVecOpti = 0;
mulEachOpti = 0;
isValidOrderFast = 0;
mode_ = mode;
}
Expand Down Expand Up @@ -1412,6 +1458,10 @@ class EcT : public fp::Serializable<EcT<_Fp, _Fr> > {
{
mulVecOpti = f;
}
static void setMulEachOpti(void f(Unit *_xVec, const Unit *_yVec, size_t yn))
{
mulEachOpti = f;
}
static inline void init(bool *pb, const char *astr, const char *bstr, int mode = ec::Jacobi)
{
Fp a, b;
Expand Down Expand Up @@ -1463,12 +1513,14 @@ class EcT : public fp::Serializable<EcT<_Fp, _Fr> > {
void clear()
{
if (mode_ == ec::Jacobi) {
x = 1;
} else {
x = 0;
y = 0;
z.clear();
} else { // ec::Proj
x.clear();
y = 1;
z.clear();
}
y = 1;
z.clear();
}
static inline void clear(EcT& P)
{
Expand Down Expand Up @@ -2080,7 +2132,7 @@ class EcT : public fp::Serializable<EcT<_Fp, _Fr> > {
return;
}
if (mulVecOpti && n >= 128) {
mulVecOpti((Unit*)&z, (Unit*)xVec, (const Unit*)yVec, n);
mulVecOpti((Unit*)&z, (Unit*)xVec, yVec[0].getUnit(), n);
return;
}
if (mulVecGLV && mulVecGLV(z, xVec, yVec, n, false)) {
Expand Down Expand Up @@ -2133,6 +2185,20 @@ class EcT : public fp::Serializable<EcT<_Fp, _Fr> > {
mulVec(z, xVec, yVec, n);
#endif
}
// xVec[i] *= yVec[i]
static void mulEach(EcT *xVec, const EcT::Fr *yVec, size_t n)
{
if (mulEachOpti && n >= 8) {
size_t n8 = n & ~size_t(7);
mulEachOpti((Unit*)xVec, yVec[0].getUnit(), n8);
xVec += n8;
yVec += n8;
n -= n8;
}
for (size_t i = 0; i < n; i++) {
xVec[i] *= yVec[i];
}
}
#ifndef CYBOZU_DONT_USE_EXCEPTION
static inline void init(const std::string& astr, const std::string& bstr, int mode = ec::Jacobi)
{
Expand Down Expand Up @@ -2192,6 +2258,7 @@ template<class Fp, class Fr> bool (*EcT<Fp, Fr>::mulVecGLV)(EcT& z, const EcT *x
template<class Fp, class Fr> void (*EcT<Fp, Fr>::mulVecOpti)(Unit *z, Unit *xVec, const Unit *yVec, size_t n);
template<class Fp, class Fr> bool (*EcT<Fp, Fr>::isValidOrderFast)(const EcT& x);
template<class Fp, class Fr> int EcT<Fp, Fr>::mode_;
template<class Fp, class Fr> void (*EcT<Fp, Fr>::mulEachOpti)(Unit *xVec, const Unit *yVec, size_t n);

// r = the order of Ec
template<class Ec, class _Fr>
Expand Down
4 changes: 4 additions & 0 deletions include/mcl/impl/bn_c_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,10 @@ void mclBnGT_powVec(mclBnGT *z, const mclBnGT *x, const mclBnFr *y, mclSize n)
{
GT::powVec(*cast(z), cast(x), cast(y), n);
}
void mclBnG1_mulEach(mclBnG1 *x, const mclBnFr *y, mclSize n)
{
G1::mulEach(cast(x), cast(y), n);
}

void mclBn_pairing(mclBnGT *z, const mclBnG1 *x, const mclBnG2 *y)
{
Expand Down
2 changes: 1 addition & 1 deletion include/mcl/op.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

namespace mcl {

static const int version = 0x191; /* 0xABC = A.BC */
static const int version = 0x192; /* 0xABC = A.BC */

/*
specifies available string format mode for X::setIoMode()
Expand Down
Loading

0 comments on commit a026d3a

Please sign in to comment.