Skip to content

Commit

Permalink
add optimizedSplitForBLS12_381
Browse files Browse the repository at this point in the history
  • Loading branch information
herumi committed Feb 29, 2024
1 parent d831d1d commit 90742e6
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 38 deletions.
41 changes: 21 additions & 20 deletions include/mcl/bn.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -663,18 +663,22 @@ struct GLV1 : mcl::GLV1T<G1, Fr> {
(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 @@ -686,18 +690,21 @@ 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;
if (curveType == BLS12_381.curveType) {
optimizedSplit = optimizedSplitForBLS12_381;
v0 = -v0;
B[0][0] = -B[0][0];
// [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)
{
/*
Expand All @@ -709,7 +716,6 @@ struct GLV1 : mcl::GLV1T<G1, Fr> {
*/
mpz_class& a = u[0];
mpz_class& b = u[1];
#if MCL_SIZEOF_UNIT == 8
static const uint64_t Lv[] = { 0x00000000ffffffff, 0xac45a4010001a402 };
static const uint64_t vv[] = { 0xb1fb72917b67f718, 0xbe35f678f00fd56e };
static const size_t n = 128 / mcl::UnitBitSize;
Expand All @@ -722,11 +728,6 @@ struct GLV1 : mcl::GLV1T<G1, Fr> {
mcl::bint::subT<n>(t, x.getUnit(), t);
a.setArray(&dummy, t, n);
(void)dummy;
#else
mpz_class t;
b = (x * v0) >> 255;
a = x - b * B[0][0];
#endif
}
};

Expand Down
29 changes: 11 additions & 18 deletions misc/internal.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@
### 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 = (L+1)*S // r
r0 = (L+1)*S % r
v = S // L
r0 = S % L
```

variables|z|L|r|S|v
Expand All @@ -28,34 +30,25 @@ def split(x):
a = x - b * L
return (a, b)
```

- x in [0, r-1].
- a + b L = x for (a, b) = split(x).

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

### Proof

```
Let r0 := (L+1)S % r, then (L+1)S=v r + r0 and r0 in [0, r-1].
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 = floor((xv)/S) <= (xv)/S = (xvr)/(Sr) = x((L+1)S - r0) / (Sr) = (x/r)(L+1) - (r0/Sr)
<= (L+1) < 2^128.
b <= xv / S < (M-r) (S/L)/S = (M-r)/L < H.
```

```
arS = (x - bL)rS = xrS - bSrL = xrS - (xv - r1)rL = xrS - x(vr)L + r1 rL
= xrS - xL((L+1)S - r0) + r1 rL = xrS - xL(L+1)S + x r0 L + r1 rL
= xS(r - L^2-L) + (x r0 + r1 r)L
= x(S + r0 L) + r1 r L.
```
Then,
```
a = (x/r)(1 + (r0/S)L) + (r1/r)L
< 1 + (r0/S)L + L.
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.
```
r0/S < 0.10017, then a < 2^128.
Then, a < H.
So for x in [0, M-1], set x = x - r if x >= H and apply split() to x.

0 comments on commit 90742e6

Please sign in to comment.