Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
herumi committed Feb 29, 2024
2 parents 0e6074a + aed4339 commit f1b89e8
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 15 deletions.
14 changes: 14 additions & 0 deletions ffi/cs/mcl/mcl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ public class MCL {
[DllImport(dllName)] public static extern void mclBnG1_sub(ref G1 z, in G1 x, in G1 y);
[DllImport(dllName)] public static extern void mclBnG1_mul(ref G1 z, in G1 x, in Fr y);
[DllImport(dllName)] public static extern void mclBnG1_mulVec(ref G1 z, [In] G1[] x, [In] Fr[] y, long n);
[DllImport(dllName)] public static extern int mclBnG1_setDst([In][MarshalAs(UnmanagedType.LPStr)] string dst, long dstSize);

[DllImport(dllName)] public static extern void mclBnG2_clear(ref G2 x);
[DllImport(dllName)] public static extern int mclBnG2_setStr(ref G2 x, [In][MarshalAs(UnmanagedType.LPStr)] string buf, long bufSize, int ioMode);
Expand All @@ -88,6 +89,7 @@ public class MCL {
[DllImport(dllName)] public static extern void mclBnG2_sub(ref G2 z, in G2 x, in G2 y);
[DllImport(dllName)] public static extern void mclBnG2_mul(ref G2 z, in G2 x, in Fr y);
[DllImport(dllName)] public static extern void mclBnG2_mulVec(ref G2 z, [In] G2[] x, [In] Fr[] y, long n);
[DllImport(dllName)] public static extern int mclBnG2_setDst([In][MarshalAs(UnmanagedType.LPStr)] string dst, long dstSize);

[DllImport(dllName)] public static extern void mclBnGT_clear(ref GT x);
[DllImport(dllName)] public static extern int mclBnGT_setStr(ref GT x, [In][MarshalAs(UnmanagedType.LPStr)] string buf, long bufSize, int ioMode);
Expand Down Expand Up @@ -145,6 +147,18 @@ public static void ETHmode()
mclBn_setETHserialization(1);
mclBn_setMapToMode(MCL_MAP_TO_MODE_HASH_TO_CURVE);
}
public static void G1setDst(string s)
{
if (mclBnG1_setDst(s, s.Length) != 0) {
throw new ArgumentException("mclBnG1_setDst");
}
}
public static void G2setDst(string s)
{
if (mclBnG2_setDst(s, s.Length) != 0) {
throw new ArgumentException("mclBnG2_setDst");
}
}
public static void Add(ref Fr z, in Fr x, in Fr y)
{
mclBnFr_add(ref z, x, y);
Expand Down
4 changes: 2 additions & 2 deletions include/mcl/bint.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -460,12 +460,12 @@ MCL_DLL_API void sqr_SECP256K1(Unit *y, const Unit *x, const Unit *p);
MCL_DLL_API void maskN(Unit *x, size_t n, size_t bitSize);

// ppLow = Unit(p)
inline Unit getMontgomeryCoeff(Unit pLow)
inline Unit getMontgomeryCoeff(Unit pLow, size_t bitSize = sizeof(Unit) * 8)
{
Unit pp = 0;
Unit t = 0;
Unit x = 1;
for (size_t i = 0; i < sizeof(Unit) * 8; i++) {
for (size_t i = 0; i < bitSize; i++) {
if ((t & 1) == 0) {
t += pLow;
pp += x;
Expand Down
60 changes: 49 additions & 11 deletions include/mcl/bn.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -654,26 +654,31 @@ struct GLV1 : mcl::GLV1T<G1, Fr> {
}
return false;
}
static void initForBN(const mpz_class& z, bool isBLS12 = false, int curveType = -1)
static void init(const mpz_class& z, bool isBLS12, int curveType)
{
optimizedSplit = 0;
if (usePrecomputedTable(curveType)) return;
bool b = Fp::squareRoot(rw, -3);
assert(b);
(void)b;
rw = -(rw + 1) / 2;
rBitSize = Fr::getOp().bitSize;
rBitSize = (rBitSize + UnitBitSize - 1) & ~(UnitBitSize - 1);// a little better size
if (isBLS12) {
/*
BLS12
L = z^4
(-z^2+1) + L = 0
1 + z^2 L = 0
*/
B[0][0] = -z * z + 1;
B[0][1] = 1;
B[1][0] = 1;
B[1][1] = z * z;
// only B[0][0] and v0 are used
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) {
optimizedSplit = optimizedSplitForBLS12_381;
} else {
optimizedSplit = splitForBLS12;
}
} else {
/*
BN
Expand All @@ -685,11 +690,44 @@ struct GLV1 : mcl::GLV1T<G1, Fr> {
B[0][1] = -2 * z - 1;
B[1][0] = -2 * z - 1;
B[1][1] = -6 * z * z - 4 * z - 1;
// [v0 v1] = [r 0] * B^(-1)
const mpz_class& r = Fr::getOp().mp;
v0 = ((-B[1][1]) << rBitSize) / r;
v1 = ((B[1][0]) << rBitSize) / r;
}
// [v0 v1] = [r 0] * B^(-1)
const mpz_class& r = Fr::getOp().mp;
v0 = ((-B[1][1]) << rBitSize) / r;
v1 = ((B[1][0]) << rBitSize) / r;
}
// x = (a + b L) mod r
static inline void splitForBLS12(mpz_class u[2], const mpz_class& x)
{
mpz_class& a = u[0];
mpz_class& b = u[1];
mpz_class t;
b = (x * v0) >> rBitSize;
a = x - b * B[0][0];
}
static inline void optimizedSplitForBLS12_381(mpz_class u[2], const mpz_class& x)
{
/*
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];
mcl::bint::mulNM(t, x.getUnit(), n*2, (const Unit*)vv, n);
mcl::bint::shrT<n+1>(t, t+n*2-1, mcl::UnitBitSize-1); // >>255
bool dummy;
b.setArray(&dummy, t, n);
mcl::bint::mulT<n>(t, t, (const Unit*)Lv);
mcl::bint::subT<n>(t, x.getUnit(), t);
a.setArray(&dummy, t, n);
(void)dummy;
}
};

Expand Down Expand Up @@ -942,7 +980,7 @@ struct Param {
} else {
mapTo.init(2 * p - r, z, cp.curveType);
}
GLV1::initForBN(z, isBLS12, cp.curveType);
GLV1::init(z, isBLS12, cp.curveType);
GLV2T<Fr>::init(z, isBLS12);
basePoint.clear();
G1::setOrder(r);
Expand Down
9 changes: 8 additions & 1 deletion include/mcl/ec.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2154,6 +2154,7 @@ struct GLV1T {
static size_t rBitSize;
static mpz_class v0, v1;
static mpz_class B[2][2];
static void (*optimizedSplit)(mpz_class u[2], const mpz_class& x);
public:
#ifndef CYBOZU_DONT_USE_STRING
static void dump(const mpz_class& x)
Expand Down Expand Up @@ -2184,6 +2185,10 @@ struct GLV1T {
static void split(mpz_class u[2], mpz_class& x)
{
Fr::getOp().modp.modp(x, x);
if (optimizedSplit) {
optimizedSplit(u, x);
return;
}
mpz_class& a = u[0];
mpz_class& b = u[1];
mpz_class t;
Expand All @@ -2193,7 +2198,7 @@ struct GLV1T {
b = - (t * B[0][1] + b * B[1][1]);
}
/*
initForBN() is defined in bn.hpp
init() is defined in bn.hpp
*/
static void initForSecp256k1()
{
Expand All @@ -2213,6 +2218,7 @@ struct GLV1T {
const mpz_class& r = Fr::getOp().mp;
v0 = ((B[1][1]) << rBitSize) / r;
v1 = ((-B[0][1]) << rBitSize) / r;
optimizedSplit = 0;
}
};

Expand All @@ -2222,6 +2228,7 @@ template<class Ec, class Fr> size_t GLV1T<Ec, Fr>::rBitSize;
template<class Ec, class Fr> mpz_class GLV1T<Ec, Fr>::v0;
template<class Ec, class Fr> mpz_class GLV1T<Ec, Fr>::v1;
template<class Ec, class Fr> mpz_class GLV1T<Ec, Fr>::B[2][2];
template<class Ec, class Fr> void (*GLV1T<Ec, Fr>::optimizedSplit)(mpz_class u[2], const mpz_class& x);

/*
Ec : elliptic curve
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 = 0x186; /* 0xABC = A.BC */
static const int version = 0x187; /* 0xABC = A.BC */

/*
specifies available string format mode for X::setIoMode()
Expand Down
54 changes: 54 additions & 0 deletions misc/internal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Internal Algorithm

# GLV method

## Split function for BLS12-381

### Definition of parameters

```python
M = 1<<256
H = 1<<128
z = -0xd201000000010000
L = z*z - 1
r = L*L + L + 1
s = r.bit_length()
S = 1<<s
v = S // L
r0 = S % L
```

variables|z|L|r|S|v
-|-|-|-|-|-
bit_length|64|128|255|255|128


### Split function
```python
def split(x):
b = (x * v) >> s
a = x - b * L
return (a, b)
```
- a + b L = x for (a, b) = split(x).

### Theorem
0 <= a, b < H for all x in [0, M-r].

### Proof

```
Let r0 := L S % r, then S=v L + r0 and r0 in [0, L-1].
Let r1 := x v % S, then x v = b S + r1 and r1 in [0, S-1].
```

```
b <= xv / S < (M-r) (S/L)/S = (M-r)/L < H.
```

```
aS = (x - bL)S = xS - bSL = xS - (xv - r1)L = x(S - vL) + r1 L = r0 x + r1 L
<= r0 (M-r) + (S-1)L < S H.
```
Then, a < H.
So for x in [0, M-1], set x = x - r if x >= H and apply split() to x.
1 change: 1 addition & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ mcl is a library for pairing-based cryptography,
which supports the optimal Ate pairing over BN curves and BLS12-381 curves.

# News
- a little performance improvement of G1::mulVec of BLS12-381
- improve performance of Fr::inv on M1 mac
- add mcl::bn::isValidGT(x) and mclBnGT_isValid(x) to check x in GT for x in Fp12.
- support BN\_P256 (hash-to-curve is not yet standard way.)
Expand Down

0 comments on commit f1b89e8

Please sign in to comment.