Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
herumi committed Oct 21, 2024
2 parents 00f3d89 + cc173d9 commit 12eab6a
Show file tree
Hide file tree
Showing 11 changed files with 312 additions and 176 deletions.
9 changes: 6 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
name: test
on: [push]
on:
push:
branches:
- '*'

jobs:
build:
Expand All @@ -8,8 +11,8 @@ jobs:
steps:
- uses: actions/checkout@v4
- run: lscpu
- run: sudo apt update
- run: sudo apt install valgrind nasm
- run: apt -y update
- run: apt -y install valgrind nasm
- run: make bin/pairing.exe -j4
- run: valgrind bin/pairing.exe
- run: make clean
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ ifeq ($(MCL_STATIC_CODE),1)
endif
ifeq ($(CPU),x86-64)
MCL_USE_XBYAK?=1
TEST_SRC+=mont_fp_test.cpp sq_test.cpp
TEST_SRC+=mont_fp_test.cpp #sq_test.cpp
ifeq ($(MCL_USE_XBYAK),1)
TEST_SRC+=fp_generator_test.cpp
endif
Expand Down
10 changes: 1 addition & 9 deletions include/mcl/fp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,15 +207,7 @@ class FpT : public fp::Serializable<FpT<tag, maxBitSize>,
}
static inline bool squareRoot(FpT& y, const FpT& x)
{
if (isMont()) return op_.sq.get(y, x);
mpz_class mx, my;
bool b = false;
x.getMpz(&b, mx);
if (!b) return false;
b = op_.sq.get(my, mx);
if (!b) return false;
y.setMpz(&b, my);
return b;
return op_.sq.get(y, x);
}
FpT() {}
FpT(const FpT& x)
Expand Down
155 changes: 64 additions & 91 deletions include/mcl/gmp_util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,61 @@ class SquareRoot {
}
return false;
}
/*
solve x^2 = a in Fp
*/
template<class Fp>
bool getCandidate(Fp& x, const Fp& a) const
{
assert(Fp::getOp().mp == p);
if (a.isZero() || a.isOne()) {
x = a;
return true;
}
if (r == 1) {
// (p + 1) / 4 = (q + 1) / 2
Fp::pow(x, a, q_add_1_div_2);
return true;
}
Fp c, d;
{
bool b;
c.setMpz(&b, s);
assert(b);
}
int e = r;
Fp::pow(d, a, q);
Fp::pow(x, a, q_add_1_div_2); // destroy a if &x == &a
Fp dd;
Fp b;
while (!d.isOne()) {
int i = 1;
Fp::sqr(dd, d);
while (!dd.isOne()) {
Fp::sqr(dd, dd);
i++;
if (i >= e) return false;
}
assert(e > i);
int t = e - i - 1;
const int tMax = 30; // int32_t max
if (t < tMax) {
b = 1 << t;
} else {
b = 1 << tMax;
t -= tMax;
for (int j = 0; j < t; j++) {
b += b;
}
}
Fp::pow(b, c, b);
x *= b;
Fp::sqr(c, b);
d *= c;
e = i;
}
return true;
}
public:
SquareRoot() { clear(); }
bool isPrecomputed() const { return isPrecomputed_; }
Expand Down Expand Up @@ -838,100 +893,18 @@ class SquareRoot {
q_add_1_div_2 = (q + 1) / 2;
*pb = true;
}
/*
solve x^2 = a mod p
*/
bool get(mpz_class& x, const mpz_class& a) const
{
if (!isPrime) {
return false;
}
if (a == 0) {
x = 0;
return true;
}
if (gmp::legendre(a, p) < 0) return false;
if (r == 1) {
// (p + 1) / 4 = (q + 1) / 2
gmp::powMod(x, a, q_add_1_div_2, p);
return true;
}
mpz_class c = s, d;
int e = r;
gmp::powMod(d, a, q, p);
gmp::powMod(x, a, q_add_1_div_2, p); // destroy a if &x == &a
mpz_class dd;
mpz_class b;
while (d != 1) {
int i = 1;
dd = d * d; dd %= p;
while (dd != 1) {
dd *= dd; dd %= p;
i++;
}
b = 1;
b <<= e - i - 1;
gmp::powMod(b, c, b, p);
x *= b; x %= p;
c = b * b; c %= p;
d *= c; d %= p;
e = i;
}
return true;
}
/*
solve x^2 = a in Fp
*/
template<class Fp>
bool get(Fp& x, const Fp& a) const
template<class T>
bool get(T& x, const T& a) const
{
assert(Fp::getOp().mp == p);
if (a == 0) {
x = 0;
return true;
}
{
bool b;
mpz_class aa;
a.getMpz(&b, aa);
assert(b);
if (gmp::legendre(aa, p) < 0) return false;
}
if (r == 1) {
// (p + 1) / 4 = (q + 1) / 2
Fp::pow(x, a, q_add_1_div_2);
return true;
}
Fp c, d;
{
bool b;
c.setMpz(&b, s);
assert(b);
}
int e = r;
Fp::pow(d, a, q);
Fp::pow(x, a, q_add_1_div_2); // destroy a if &x == &a
Fp dd;
Fp b;
while (!d.isOne()) {
int i = 1;
Fp::sqr(dd, d);
while (!dd.isOne()) {
dd *= dd;
i++;
}
b = 1;
// b <<= e - i - 1;
for (int j = 0; j < e - i - 1; j++) {
b += b;
T t, t2;
if (getCandidate(t, a)) {
T::sqr(t2, t);
if (t2 == a) {
x = t;
return true;
}
Fp::pow(b, c, b);
x *= b;
Fp::sqr(c, b);
d *= c;
e = i;
}
return true;
return false;
}
bool operator==(const SquareRoot& rhs) const
{
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 = 0x210; /* 0xABC = A.BC */
static const int version = 0x211; /* 0xABC = A.BC */

/*
specifies available string format mode for X::setIoMode()
Expand Down
3 changes: 3 additions & 0 deletions include/mcl/vint.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,9 @@ class Vint {
// logical left shift (copy sign)
static void shl(Vint& y, const Vint& x, size_t shiftBit)
{
if (shiftBit > MCL_MAX_BIT_SIZE*2) {
printf("shiftBit=%zd\n", shiftBit);
}
assert(shiftBit <= MCL_MAX_BIT_SIZE * 2); // many be too big
size_t xn = x.size();
size_t yn = xn + (shiftBit + UnitBitSize - 1) / UnitBitSize;
Expand Down
59 changes: 3 additions & 56 deletions src/bint_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,50 +46,18 @@ struct UnrollMulLowT<1, 1> {
} // impl

#if MCL_BINT_ASM != 1
#ifdef MCL_WASM32
inline uint64_t load8byte(const uint32_t *x)
{
return x[0] | (uint64_t(x[1]) << 32);
}
inline void store8byte(uint32_t *x, uint64_t v)
{
x[0] = uint32_t(v);
x[1] = uint32_t(v >> 32);
}
#endif
template<size_t N>
Unit addT(Unit *z, const Unit *x, const Unit *y)
{
#if defined(MCL_WASM32) && MCL_SIZEOF_UNIT == 4
#ifdef MCL_WASM32
// wasm32 supports 64-bit add
#if 1
uint64_t c = 0;
for (size_t i = 0; i < N; i++) {
uint64_t v = uint64_t(x[i]) + y[i] + c;
z[i] = uint32_t(v);
c = v >> 32;
}
return uint32_t(c);
#else
uint32_t c = 0;
for (size_t i = 0; i < N - 1; i += 2) {
uint64_t xc = load8byte(x + i) + c;
c = xc < c;
uint64_t yi = load8byte(y + i);
xc += yi;
c += xc < yi;
store8byte(z + i, xc);
}
if (N & 1) {
uint32_t xc = x[N - 1] + c;
c = xc < c;
uint32_t yi = y[N - 1];
xc += yi;
c += xc < yi;
z[N - 1] = xc;
}
return c;
#endif
#else
Unit c = 0;
for (size_t i = 0; i < N; i++) {
Expand All @@ -107,36 +75,15 @@ Unit addT(Unit *z, const Unit *x, const Unit *y)
template<size_t N, typename T>
Unit subT(Unit *z, const T *x, const Unit *y)
{
#if defined(MCL_WASM32) && MCL_SIZEOF_UNIT == 4
#ifdef MCL_WASM32
// wasm32 supports 64-bit sub
#if 1
uint64_t c = 0;
for (size_t i = 0; i < N; i++) {
uint64_t v = uint64_t(x[i]) - y[i] - c;
z[i] = uint32_t(v);
c = v >> 63;
}
return c;
#else
uint32_t c = 0;
for (size_t i = 0; i < N - 1; i += 2) {
uint64_t yi = load8byte(y + i);
yi += c;
c = yi < c;
uint64_t xi = load8byte(x + i);
c += xi < yi;
store8byte(z + i, xi - yi);
}
if (N & 1) {
uint32_t yi = y[N - 1];
yi += c;
c = yi < c;
uint32_t xi = x[N - 1];
c += xi < yi;
z[N - 1] = xi - yi;
}
return c;
#endif
#else
Unit c = 0;
for (size_t i = 0; i < N; i++) {
Expand Down Expand Up @@ -203,7 +150,7 @@ Unit mulUnitT(T *z, const Unit *x, Unit y)
template<size_t N, typename T>
Unit mulUnitAddT(T *z, const Unit *x, Unit y)
{
#if defined(MCL_WASM32) && MCL_SIZEOF_UNIT == 4
#ifdef MCL_WASM32
uint64_t y_ = y;
uint64_t v = z[0] + x[0] * y_;
z[0] = uint32_t(v);
Expand Down
Loading

0 comments on commit 12eab6a

Please sign in to comment.