Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
cc3de083
Commit
cc3de083
authored
Sep 13, 2021
by
George Hotz
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bls12381 system
parent
f193a1b2
Changes
16
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
3910 additions
and
2 deletions
+3910
-2
contracts.go
minigeth/core/vm/contracts.go
+2
-2
arithmetic_fallback.go
minigeth/crypto/bls12381/arithmetic_fallback.go
+566
-0
bls12_381.go
minigeth/crypto/bls12381/bls12_381.go
+230
-0
field_element.go
minigeth/crypto/bls12381/field_element.go
+340
-0
fp.go
minigeth/crypto/bls12381/fp.go
+167
-0
fp12.go
minigeth/crypto/bls12381/fp12.go
+279
-0
fp2.go
minigeth/crypto/bls12381/fp2.go
+252
-0
fp6.go
minigeth/crypto/bls12381/fp6.go
+351
-0
g1.go
minigeth/crypto/bls12381/g1.go
+434
-0
g2.go
minigeth/crypto/bls12381/g2.go
+456
-0
gt.go
minigeth/crypto/bls12381/gt.go
+121
-0
isogeny.go
minigeth/crypto/bls12381/isogeny.go
+227
-0
pairing.go
minigeth/crypto/bls12381/pairing.go
+282
-0
swu.go
minigeth/crypto/bls12381/swu.go
+158
-0
utils.go
minigeth/crypto/bls12381/utils.go
+45
-0
.bn256_slow.go.swp
minigeth/crypto/bn256/.bn256_slow.go.swp
+0
-0
No files found.
minigeth/core/vm/contracts.go
View file @
cc3de083
...
@@ -26,8 +26,8 @@ import (
...
@@ -26,8 +26,8 @@ import (
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/crypto"
/*"github.com/ethereum/go-ethereum/crypto/blake2b"
/*"github.com/ethereum/go-ethereum/crypto/blake2b"
*/
"github.com/ethereum/go-ethereum/crypto/bls12381"
*/
"github.com/ethereum/go-ethereum/crypto/bls12381"
"github.com/ethereum/go-ethereum/crypto/bn256"
"github.com/ethereum/go-ethereum/crypto/bn256"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/params"
...
...
minigeth/crypto/bls12381/arithmetic_fallback.go
0 → 100644
View file @
cc3de083
This diff is collapsed.
Click to expand it.
minigeth/crypto/bls12381/bls12_381.go
0 → 100644
View file @
cc3de083
This diff is collapsed.
Click to expand it.
minigeth/crypto/bls12381/field_element.go
0 → 100644
View file @
cc3de083
// Copyright 2020 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package
bls12381
import
(
"crypto/rand"
"encoding/hex"
"fmt"
"io"
"math/big"
)
// fe is base field element representation
type
fe
[
6
]
uint64
// fe2 is element representation of 'fp2' which is quadratic extension of base field 'fp'
// Representation follows c[0] + c[1] * u encoding order.
type
fe2
[
2
]
fe
// fe6 is element representation of 'fp6' field which is cubic extension of 'fp2'
// Representation follows c[0] + c[1] * v + c[2] * v^2 encoding order.
type
fe6
[
3
]
fe2
// fe12 is element representation of 'fp12' field which is quadratic extension of 'fp6'
// Representation follows c[0] + c[1] * w encoding order.
type
fe12
[
2
]
fe6
func
(
fe
*
fe
)
setBytes
(
in
[]
byte
)
*
fe
{
size
:=
48
l
:=
len
(
in
)
if
l
>=
size
{
l
=
size
}
padded
:=
make
([]
byte
,
size
)
copy
(
padded
[
size
-
l
:
],
in
[
:
])
var
a
int
for
i
:=
0
;
i
<
6
;
i
++
{
a
=
size
-
i
*
8
fe
[
i
]
=
uint64
(
padded
[
a
-
1
])
|
uint64
(
padded
[
a
-
2
])
<<
8
|
uint64
(
padded
[
a
-
3
])
<<
16
|
uint64
(
padded
[
a
-
4
])
<<
24
|
uint64
(
padded
[
a
-
5
])
<<
32
|
uint64
(
padded
[
a
-
6
])
<<
40
|
uint64
(
padded
[
a
-
7
])
<<
48
|
uint64
(
padded
[
a
-
8
])
<<
56
}
return
fe
}
func
(
fe
*
fe
)
setBig
(
a
*
big
.
Int
)
*
fe
{
return
fe
.
setBytes
(
a
.
Bytes
())
}
func
(
fe
*
fe
)
setString
(
s
string
)
(
*
fe
,
error
)
{
if
s
[
:
2
]
==
"0x"
{
s
=
s
[
2
:
]
}
bytes
,
err
:=
hex
.
DecodeString
(
s
)
if
err
!=
nil
{
return
nil
,
err
}
return
fe
.
setBytes
(
bytes
),
nil
}
func
(
fe
*
fe
)
set
(
fe2
*
fe
)
*
fe
{
fe
[
0
]
=
fe2
[
0
]
fe
[
1
]
=
fe2
[
1
]
fe
[
2
]
=
fe2
[
2
]
fe
[
3
]
=
fe2
[
3
]
fe
[
4
]
=
fe2
[
4
]
fe
[
5
]
=
fe2
[
5
]
return
fe
}
func
(
fe
*
fe
)
bytes
()
[]
byte
{
out
:=
make
([]
byte
,
48
)
var
a
int
for
i
:=
0
;
i
<
6
;
i
++
{
a
=
48
-
i
*
8
out
[
a
-
1
]
=
byte
(
fe
[
i
])
out
[
a
-
2
]
=
byte
(
fe
[
i
]
>>
8
)
out
[
a
-
3
]
=
byte
(
fe
[
i
]
>>
16
)
out
[
a
-
4
]
=
byte
(
fe
[
i
]
>>
24
)
out
[
a
-
5
]
=
byte
(
fe
[
i
]
>>
32
)
out
[
a
-
6
]
=
byte
(
fe
[
i
]
>>
40
)
out
[
a
-
7
]
=
byte
(
fe
[
i
]
>>
48
)
out
[
a
-
8
]
=
byte
(
fe
[
i
]
>>
56
)
}
return
out
}
func
(
fe
*
fe
)
big
()
*
big
.
Int
{
return
new
(
big
.
Int
)
.
SetBytes
(
fe
.
bytes
())
}
func
(
fe
*
fe
)
string
()
(
s
string
)
{
for
i
:=
5
;
i
>=
0
;
i
--
{
s
=
fmt
.
Sprintf
(
"%s%16.16x"
,
s
,
fe
[
i
])
}
return
"0x"
+
s
}
func
(
fe
*
fe
)
zero
()
*
fe
{
fe
[
0
]
=
0
fe
[
1
]
=
0
fe
[
2
]
=
0
fe
[
3
]
=
0
fe
[
4
]
=
0
fe
[
5
]
=
0
return
fe
}
func
(
fe
*
fe
)
one
()
*
fe
{
return
fe
.
set
(
r1
)
}
func
(
fe
*
fe
)
rand
(
r
io
.
Reader
)
(
*
fe
,
error
)
{
bi
,
err
:=
rand
.
Int
(
r
,
modulus
.
big
())
if
err
!=
nil
{
return
nil
,
err
}
return
fe
.
setBig
(
bi
),
nil
}
func
(
fe
*
fe
)
isValid
()
bool
{
return
fe
.
cmp
(
&
modulus
)
<
0
}
func
(
fe
*
fe
)
isOdd
()
bool
{
var
mask
uint64
=
1
return
fe
[
0
]
&
mask
!=
0
}
func
(
fe
*
fe
)
isEven
()
bool
{
var
mask
uint64
=
1
return
fe
[
0
]
&
mask
==
0
}
func
(
fe
*
fe
)
isZero
()
bool
{
return
(
fe
[
5
]
|
fe
[
4
]
|
fe
[
3
]
|
fe
[
2
]
|
fe
[
1
]
|
fe
[
0
])
==
0
}
func
(
fe
*
fe
)
isOne
()
bool
{
return
fe
.
equal
(
r1
)
}
func
(
fe
*
fe
)
cmp
(
fe2
*
fe
)
int
{
for
i
:=
5
;
i
>=
0
;
i
--
{
if
fe
[
i
]
>
fe2
[
i
]
{
return
1
}
else
if
fe
[
i
]
<
fe2
[
i
]
{
return
-
1
}
}
return
0
}
func
(
fe
*
fe
)
equal
(
fe2
*
fe
)
bool
{
return
fe2
[
0
]
==
fe
[
0
]
&&
fe2
[
1
]
==
fe
[
1
]
&&
fe2
[
2
]
==
fe
[
2
]
&&
fe2
[
3
]
==
fe
[
3
]
&&
fe2
[
4
]
==
fe
[
4
]
&&
fe2
[
5
]
==
fe
[
5
]
}
func
(
e
*
fe
)
sign
()
bool
{
r
:=
new
(
fe
)
fromMont
(
r
,
e
)
return
r
[
0
]
&
1
==
0
}
func
(
fe
*
fe
)
div2
(
e
uint64
)
{
fe
[
0
]
=
fe
[
0
]
>>
1
|
fe
[
1
]
<<
63
fe
[
1
]
=
fe
[
1
]
>>
1
|
fe
[
2
]
<<
63
fe
[
2
]
=
fe
[
2
]
>>
1
|
fe
[
3
]
<<
63
fe
[
3
]
=
fe
[
3
]
>>
1
|
fe
[
4
]
<<
63
fe
[
4
]
=
fe
[
4
]
>>
1
|
fe
[
5
]
<<
63
fe
[
5
]
=
fe
[
5
]
>>
1
|
e
<<
63
}
func
(
fe
*
fe
)
mul2
()
uint64
{
e
:=
fe
[
5
]
>>
63
fe
[
5
]
=
fe
[
5
]
<<
1
|
fe
[
4
]
>>
63
fe
[
4
]
=
fe
[
4
]
<<
1
|
fe
[
3
]
>>
63
fe
[
3
]
=
fe
[
3
]
<<
1
|
fe
[
2
]
>>
63
fe
[
2
]
=
fe
[
2
]
<<
1
|
fe
[
1
]
>>
63
fe
[
1
]
=
fe
[
1
]
<<
1
|
fe
[
0
]
>>
63
fe
[
0
]
=
fe
[
0
]
<<
1
return
e
}
func
(
e
*
fe2
)
zero
()
*
fe2
{
e
[
0
]
.
zero
()
e
[
1
]
.
zero
()
return
e
}
func
(
e
*
fe2
)
one
()
*
fe2
{
e
[
0
]
.
one
()
e
[
1
]
.
zero
()
return
e
}
func
(
e
*
fe2
)
set
(
e2
*
fe2
)
*
fe2
{
e
[
0
]
.
set
(
&
e2
[
0
])
e
[
1
]
.
set
(
&
e2
[
1
])
return
e
}
func
(
e
*
fe2
)
rand
(
r
io
.
Reader
)
(
*
fe2
,
error
)
{
a0
,
err
:=
new
(
fe
)
.
rand
(
r
)
if
err
!=
nil
{
return
nil
,
err
}
a1
,
err
:=
new
(
fe
)
.
rand
(
r
)
if
err
!=
nil
{
return
nil
,
err
}
return
&
fe2
{
*
a0
,
*
a1
},
nil
}
func
(
e
*
fe2
)
isOne
()
bool
{
return
e
[
0
]
.
isOne
()
&&
e
[
1
]
.
isZero
()
}
func
(
e
*
fe2
)
isZero
()
bool
{
return
e
[
0
]
.
isZero
()
&&
e
[
1
]
.
isZero
()
}
func
(
e
*
fe2
)
equal
(
e2
*
fe2
)
bool
{
return
e
[
0
]
.
equal
(
&
e2
[
0
])
&&
e
[
1
]
.
equal
(
&
e2
[
1
])
}
func
(
e
*
fe2
)
sign
()
bool
{
r
:=
new
(
fe
)
if
!
e
[
0
]
.
isZero
()
{
fromMont
(
r
,
&
e
[
0
])
return
r
[
0
]
&
1
==
0
}
fromMont
(
r
,
&
e
[
1
])
return
r
[
0
]
&
1
==
0
}
func
(
e
*
fe6
)
zero
()
*
fe6
{
e
[
0
]
.
zero
()
e
[
1
]
.
zero
()
e
[
2
]
.
zero
()
return
e
}
func
(
e
*
fe6
)
one
()
*
fe6
{
e
[
0
]
.
one
()
e
[
1
]
.
zero
()
e
[
2
]
.
zero
()
return
e
}
func
(
e
*
fe6
)
set
(
e2
*
fe6
)
*
fe6
{
e
[
0
]
.
set
(
&
e2
[
0
])
e
[
1
]
.
set
(
&
e2
[
1
])
e
[
2
]
.
set
(
&
e2
[
2
])
return
e
}
func
(
e
*
fe6
)
rand
(
r
io
.
Reader
)
(
*
fe6
,
error
)
{
a0
,
err
:=
new
(
fe2
)
.
rand
(
r
)
if
err
!=
nil
{
return
nil
,
err
}
a1
,
err
:=
new
(
fe2
)
.
rand
(
r
)
if
err
!=
nil
{
return
nil
,
err
}
a2
,
err
:=
new
(
fe2
)
.
rand
(
r
)
if
err
!=
nil
{
return
nil
,
err
}
return
&
fe6
{
*
a0
,
*
a1
,
*
a2
},
nil
}
func
(
e
*
fe6
)
isOne
()
bool
{
return
e
[
0
]
.
isOne
()
&&
e
[
1
]
.
isZero
()
&&
e
[
2
]
.
isZero
()
}
func
(
e
*
fe6
)
isZero
()
bool
{
return
e
[
0
]
.
isZero
()
&&
e
[
1
]
.
isZero
()
&&
e
[
2
]
.
isZero
()
}
func
(
e
*
fe6
)
equal
(
e2
*
fe6
)
bool
{
return
e
[
0
]
.
equal
(
&
e2
[
0
])
&&
e
[
1
]
.
equal
(
&
e2
[
1
])
&&
e
[
2
]
.
equal
(
&
e2
[
2
])
}
func
(
e
*
fe12
)
zero
()
*
fe12
{
e
[
0
]
.
zero
()
e
[
1
]
.
zero
()
return
e
}
func
(
e
*
fe12
)
one
()
*
fe12
{
e
[
0
]
.
one
()
e
[
1
]
.
zero
()
return
e
}
func
(
e
*
fe12
)
set
(
e2
*
fe12
)
*
fe12
{
e
[
0
]
.
set
(
&
e2
[
0
])
e
[
1
]
.
set
(
&
e2
[
1
])
return
e
}
func
(
e
*
fe12
)
rand
(
r
io
.
Reader
)
(
*
fe12
,
error
)
{
a0
,
err
:=
new
(
fe6
)
.
rand
(
r
)
if
err
!=
nil
{
return
nil
,
err
}
a1
,
err
:=
new
(
fe6
)
.
rand
(
r
)
if
err
!=
nil
{
return
nil
,
err
}
return
&
fe12
{
*
a0
,
*
a1
},
nil
}
func
(
e
*
fe12
)
isOne
()
bool
{
return
e
[
0
]
.
isOne
()
&&
e
[
1
]
.
isZero
()
}
func
(
e
*
fe12
)
isZero
()
bool
{
return
e
[
0
]
.
isZero
()
&&
e
[
1
]
.
isZero
()
}
func
(
e
*
fe12
)
equal
(
e2
*
fe12
)
bool
{
return
e
[
0
]
.
equal
(
&
e2
[
0
])
&&
e
[
1
]
.
equal
(
&
e2
[
1
])
}
minigeth/crypto/bls12381/fp.go
0 → 100644
View file @
cc3de083
// Copyright 2020 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package
bls12381
import
(
"errors"
"math/big"
)
func
fromBytes
(
in
[]
byte
)
(
*
fe
,
error
)
{
fe
:=
&
fe
{}
if
len
(
in
)
!=
48
{
return
nil
,
errors
.
New
(
"input string should be equal 48 bytes"
)
}
fe
.
setBytes
(
in
)
if
!
fe
.
isValid
()
{
return
nil
,
errors
.
New
(
"must be less than modulus"
)
}
toMont
(
fe
,
fe
)
return
fe
,
nil
}
func
fromBig
(
in
*
big
.
Int
)
(
*
fe
,
error
)
{
fe
:=
new
(
fe
)
.
setBig
(
in
)
if
!
fe
.
isValid
()
{
return
nil
,
errors
.
New
(
"invalid input string"
)
}
toMont
(
fe
,
fe
)
return
fe
,
nil
}
func
fromString
(
in
string
)
(
*
fe
,
error
)
{
fe
,
err
:=
new
(
fe
)
.
setString
(
in
)
if
err
!=
nil
{
return
nil
,
err
}
if
!
fe
.
isValid
()
{
return
nil
,
errors
.
New
(
"invalid input string"
)
}
toMont
(
fe
,
fe
)
return
fe
,
nil
}
func
toBytes
(
e
*
fe
)
[]
byte
{
e2
:=
new
(
fe
)
fromMont
(
e2
,
e
)
return
e2
.
bytes
()
}
func
toBig
(
e
*
fe
)
*
big
.
Int
{
e2
:=
new
(
fe
)
fromMont
(
e2
,
e
)
return
e2
.
big
()
}
func
toString
(
e
*
fe
)
(
s
string
)
{
e2
:=
new
(
fe
)
fromMont
(
e2
,
e
)
return
e2
.
string
()
}
func
toMont
(
c
,
a
*
fe
)
{
mul
(
c
,
a
,
r2
)
}
func
fromMont
(
c
,
a
*
fe
)
{
mul
(
c
,
a
,
&
fe
{
1
})
}
func
exp
(
c
,
a
*
fe
,
e
*
big
.
Int
)
{
z
:=
new
(
fe
)
.
set
(
r1
)
for
i
:=
e
.
BitLen
();
i
>=
0
;
i
--
{
mul
(
z
,
z
,
z
)
if
e
.
Bit
(
i
)
==
1
{
mul
(
z
,
z
,
a
)
}
}
c
.
set
(
z
)
}
func
inverse
(
inv
,
e
*
fe
)
{
if
e
.
isZero
()
{
inv
.
zero
()
return
}
u
:=
new
(
fe
)
.
set
(
&
modulus
)
v
:=
new
(
fe
)
.
set
(
e
)
s
:=
&
fe
{
1
}
r
:=
&
fe
{
0
}
var
k
int
var
z
uint64
var
found
=
false
// Phase 1
for
i
:=
0
;
i
<
768
;
i
++
{
if
v
.
isZero
()
{
found
=
true
break
}
if
u
.
isEven
()
{
u
.
div2
(
0
)
s
.
mul2
()
}
else
if
v
.
isEven
()
{
v
.
div2
(
0
)
z
+=
r
.
mul2
()
}
else
if
u
.
cmp
(
v
)
==
1
{
lsubAssign
(
u
,
v
)
u
.
div2
(
0
)
laddAssign
(
r
,
s
)
s
.
mul2
()
}
else
{
lsubAssign
(
v
,
u
)
v
.
div2
(
0
)
laddAssign
(
s
,
r
)
z
+=
r
.
mul2
()
}
k
+=
1
}
if
!
found
{
inv
.
zero
()
return
}
if
k
<
381
||
k
>
381
+
384
{
inv
.
zero
()
return
}
if
r
.
cmp
(
&
modulus
)
!=
-
1
||
z
>
0
{
lsubAssign
(
r
,
&
modulus
)
}
u
.
set
(
&
modulus
)
lsubAssign
(
u
,
r
)
// Phase 2
for
i
:=
k
;
i
<
384
*
2
;
i
++
{
double
(
u
,
u
)
}
inv
.
set
(
u
)
}
func
sqrt
(
c
,
a
*
fe
)
bool
{
u
,
v
:=
new
(
fe
)
.
set
(
a
),
new
(
fe
)
exp
(
c
,
a
,
pPlus1Over4
)
square
(
v
,
c
)
return
u
.
equal
(
v
)
}
func
isQuadraticNonResidue
(
elem
*
fe
)
bool
{
result
:=
new
(
fe
)
exp
(
result
,
elem
,
pMinus1Over2
)
return
!
result
.
isOne
()
}
minigeth/crypto/bls12381/fp12.go
0 → 100644
View file @
cc3de083
// Copyright 2020 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package
bls12381
import
(
"errors"
"math/big"
)
type
fp12
struct
{
fp12temp
fp6
*
fp6
}
type
fp12temp
struct
{
t2
[
9
]
*
fe2
t6
[
5
]
*
fe6
t12
*
fe12
}
func
newFp12Temp
()
fp12temp
{
t2
:=
[
9
]
*
fe2
{}
t6
:=
[
5
]
*
fe6
{}
for
i
:=
0
;
i
<
len
(
t2
);
i
++
{
t2
[
i
]
=
&
fe2
{}
}
for
i
:=
0
;
i
<
len
(
t6
);
i
++
{
t6
[
i
]
=
&
fe6
{}
}
return
fp12temp
{
t2
,
t6
,
&
fe12
{}}
}
func
newFp12
(
fp6
*
fp6
)
*
fp12
{
t
:=
newFp12Temp
()
if
fp6
==
nil
{
return
&
fp12
{
t
,
newFp6
(
nil
)}
}
return
&
fp12
{
t
,
fp6
}
}
func
(
e
*
fp12
)
fp2
()
*
fp2
{
return
e
.
fp6
.
fp2
}
func
(
e
*
fp12
)
fromBytes
(
in
[]
byte
)
(
*
fe12
,
error
)
{
if
len
(
in
)
!=
576
{
return
nil
,
errors
.
New
(
"input string should be larger than 96 bytes"
)
}
fp6
:=
e
.
fp6
c1
,
err
:=
fp6
.
fromBytes
(
in
[
:
288
])
if
err
!=
nil
{
return
nil
,
err
}
c0
,
err
:=
fp6
.
fromBytes
(
in
[
288
:
])
if
err
!=
nil
{
return
nil
,
err
}
return
&
fe12
{
*
c0
,
*
c1
},
nil
}
func
(
e
*
fp12
)
toBytes
(
a
*
fe12
)
[]
byte
{
fp6
:=
e
.
fp6
out
:=
make
([]
byte
,
576
)
copy
(
out
[
:
288
],
fp6
.
toBytes
(
&
a
[
1
]))
copy
(
out
[
288
:
],
fp6
.
toBytes
(
&
a
[
0
]))
return
out
}
func
(
e
*
fp12
)
new
()
*
fe12
{
return
new
(
fe12
)
}
func
(
e
*
fp12
)
zero
()
*
fe12
{
return
new
(
fe12
)
}
func
(
e
*
fp12
)
one
()
*
fe12
{
return
new
(
fe12
)
.
one
()
}
func
(
e
*
fp12
)
add
(
c
,
a
,
b
*
fe12
)
{
fp6
:=
e
.
fp6
fp6
.
add
(
&
c
[
0
],
&
a
[
0
],
&
b
[
0
])
fp6
.
add
(
&
c
[
1
],
&
a
[
1
],
&
b
[
1
])
}
func
(
e
*
fp12
)
double
(
c
,
a
*
fe12
)
{
fp6
:=
e
.
fp6
fp6
.
double
(
&
c
[
0
],
&
a
[
0
])
fp6
.
double
(
&
c
[
1
],
&
a
[
1
])
}
func
(
e
*
fp12
)
sub
(
c
,
a
,
b
*
fe12
)
{
fp6
:=
e
.
fp6
fp6
.
sub
(
&
c
[
0
],
&
a
[
0
],
&
b
[
0
])
fp6
.
sub
(
&
c
[
1
],
&
a
[
1
],
&
b
[
1
])
}
func
(
e
*
fp12
)
neg
(
c
,
a
*
fe12
)
{
fp6
:=
e
.
fp6
fp6
.
neg
(
&
c
[
0
],
&
a
[
0
])
fp6
.
neg
(
&
c
[
1
],
&
a
[
1
])
}
func
(
e
*
fp12
)
conjugate
(
c
,
a
*
fe12
)
{
fp6
:=
e
.
fp6
c
[
0
]
.
set
(
&
a
[
0
])
fp6
.
neg
(
&
c
[
1
],
&
a
[
1
])
}
func
(
e
*
fp12
)
square
(
c
,
a
*
fe12
)
{
fp6
,
t
:=
e
.
fp6
,
e
.
t6
fp6
.
add
(
t
[
0
],
&
a
[
0
],
&
a
[
1
])
fp6
.
mul
(
t
[
2
],
&
a
[
0
],
&
a
[
1
])
fp6
.
mulByNonResidue
(
t
[
1
],
&
a
[
1
])
fp6
.
addAssign
(
t
[
1
],
&
a
[
0
])
fp6
.
mulByNonResidue
(
t
[
3
],
t
[
2
])
fp6
.
mulAssign
(
t
[
0
],
t
[
1
])
fp6
.
subAssign
(
t
[
0
],
t
[
2
])
fp6
.
sub
(
&
c
[
0
],
t
[
0
],
t
[
3
])
fp6
.
double
(
&
c
[
1
],
t
[
2
])
}
func
(
e
*
fp12
)
cyclotomicSquare
(
c
,
a
*
fe12
)
{
t
,
fp2
:=
e
.
t2
,
e
.
fp2
()
e
.
fp4Square
(
t
[
3
],
t
[
4
],
&
a
[
0
][
0
],
&
a
[
1
][
1
])
fp2
.
sub
(
t
[
2
],
t
[
3
],
&
a
[
0
][
0
])
fp2
.
doubleAssign
(
t
[
2
])
fp2
.
add
(
&
c
[
0
][
0
],
t
[
2
],
t
[
3
])
fp2
.
add
(
t
[
2
],
t
[
4
],
&
a
[
1
][
1
])
fp2
.
doubleAssign
(
t
[
2
])
fp2
.
add
(
&
c
[
1
][
1
],
t
[
2
],
t
[
4
])
e
.
fp4Square
(
t
[
3
],
t
[
4
],
&
a
[
1
][
0
],
&
a
[
0
][
2
])
e
.
fp4Square
(
t
[
5
],
t
[
6
],
&
a
[
0
][
1
],
&
a
[
1
][
2
])
fp2
.
sub
(
t
[
2
],
t
[
3
],
&
a
[
0
][
1
])
fp2
.
doubleAssign
(
t
[
2
])
fp2
.
add
(
&
c
[
0
][
1
],
t
[
2
],
t
[
3
])
fp2
.
add
(
t
[
2
],
t
[
4
],
&
a
[
1
][
2
])
fp2
.
doubleAssign
(
t
[
2
])
fp2
.
add
(
&
c
[
1
][
2
],
t
[
2
],
t
[
4
])
fp2
.
mulByNonResidue
(
t
[
3
],
t
[
6
])
fp2
.
add
(
t
[
2
],
t
[
3
],
&
a
[
1
][
0
])
fp2
.
doubleAssign
(
t
[
2
])
fp2
.
add
(
&
c
[
1
][
0
],
t
[
2
],
t
[
3
])
fp2
.
sub
(
t
[
2
],
t
[
5
],
&
a
[
0
][
2
])
fp2
.
doubleAssign
(
t
[
2
])
fp2
.
add
(
&
c
[
0
][
2
],
t
[
2
],
t
[
5
])
}
func
(
e
*
fp12
)
mul
(
c
,
a
,
b
*
fe12
)
{
t
,
fp6
:=
e
.
t6
,
e
.
fp6
fp6
.
mul
(
t
[
1
],
&
a
[
0
],
&
b
[
0
])
fp6
.
mul
(
t
[
2
],
&
a
[
1
],
&
b
[
1
])
fp6
.
add
(
t
[
0
],
t
[
1
],
t
[
2
])
fp6
.
mulByNonResidue
(
t
[
2
],
t
[
2
])
fp6
.
add
(
t
[
3
],
t
[
1
],
t
[
2
])
fp6
.
add
(
t
[
1
],
&
a
[
0
],
&
a
[
1
])
fp6
.
add
(
t
[
2
],
&
b
[
0
],
&
b
[
1
])
fp6
.
mulAssign
(
t
[
1
],
t
[
2
])
c
[
0
]
.
set
(
t
[
3
])
fp6
.
sub
(
&
c
[
1
],
t
[
1
],
t
[
0
])
}
func
(
e
*
fp12
)
mulAssign
(
a
,
b
*
fe12
)
{
t
,
fp6
:=
e
.
t6
,
e
.
fp6
fp6
.
mul
(
t
[
1
],
&
a
[
0
],
&
b
[
0
])
fp6
.
mul
(
t
[
2
],
&
a
[
1
],
&
b
[
1
])
fp6
.
add
(
t
[
0
],
t
[
1
],
t
[
2
])
fp6
.
mulByNonResidue
(
t
[
2
],
t
[
2
])
fp6
.
add
(
t
[
3
],
t
[
1
],
t
[
2
])
fp6
.
add
(
t
[
1
],
&
a
[
0
],
&
a
[
1
])
fp6
.
add
(
t
[
2
],
&
b
[
0
],
&
b
[
1
])
fp6
.
mulAssign
(
t
[
1
],
t
[
2
])
a
[
0
]
.
set
(
t
[
3
])
fp6
.
sub
(
&
a
[
1
],
t
[
1
],
t
[
0
])
}
func
(
e
*
fp12
)
fp4Square
(
c0
,
c1
,
a0
,
a1
*
fe2
)
{
t
,
fp2
:=
e
.
t2
,
e
.
fp2
()
fp2
.
square
(
t
[
0
],
a0
)
fp2
.
square
(
t
[
1
],
a1
)
fp2
.
mulByNonResidue
(
t
[
2
],
t
[
1
])
fp2
.
add
(
c0
,
t
[
2
],
t
[
0
])
fp2
.
add
(
t
[
2
],
a0
,
a1
)
fp2
.
squareAssign
(
t
[
2
])
fp2
.
subAssign
(
t
[
2
],
t
[
0
])
fp2
.
sub
(
c1
,
t
[
2
],
t
[
1
])
}
func
(
e
*
fp12
)
inverse
(
c
,
a
*
fe12
)
{
fp6
,
t
:=
e
.
fp6
,
e
.
t6
fp6
.
square
(
t
[
0
],
&
a
[
0
])
fp6
.
square
(
t
[
1
],
&
a
[
1
])
fp6
.
mulByNonResidue
(
t
[
1
],
t
[
1
])
fp6
.
sub
(
t
[
1
],
t
[
0
],
t
[
1
])
fp6
.
inverse
(
t
[
0
],
t
[
1
])
fp6
.
mul
(
&
c
[
0
],
&
a
[
0
],
t
[
0
])
fp6
.
mulAssign
(
t
[
0
],
&
a
[
1
])
fp6
.
neg
(
&
c
[
1
],
t
[
0
])
}
func
(
e
*
fp12
)
mulBy014Assign
(
a
*
fe12
,
c0
,
c1
,
c4
*
fe2
)
{
fp2
,
fp6
,
t
,
t2
:=
e
.
fp2
(),
e
.
fp6
,
e
.
t6
,
e
.
t2
[
0
]
fp6
.
mulBy01
(
t
[
0
],
&
a
[
0
],
c0
,
c1
)
fp6
.
mulBy1
(
t
[
1
],
&
a
[
1
],
c4
)
fp2
.
add
(
t2
,
c1
,
c4
)
fp6
.
add
(
t
[
2
],
&
a
[
1
],
&
a
[
0
])
fp6
.
mulBy01Assign
(
t
[
2
],
c0
,
t2
)
fp6
.
subAssign
(
t
[
2
],
t
[
0
])
fp6
.
sub
(
&
a
[
1
],
t
[
2
],
t
[
1
])
fp6
.
mulByNonResidue
(
t
[
1
],
t
[
1
])
fp6
.
add
(
&
a
[
0
],
t
[
1
],
t
[
0
])
}
func
(
e
*
fp12
)
exp
(
c
,
a
*
fe12
,
s
*
big
.
Int
)
{
z
:=
e
.
one
()
for
i
:=
s
.
BitLen
()
-
1
;
i
>=
0
;
i
--
{
e
.
square
(
z
,
z
)
if
s
.
Bit
(
i
)
==
1
{
e
.
mul
(
z
,
z
,
a
)
}
}
c
.
set
(
z
)
}
func
(
e
*
fp12
)
cyclotomicExp
(
c
,
a
*
fe12
,
s
*
big
.
Int
)
{
z
:=
e
.
one
()
for
i
:=
s
.
BitLen
()
-
1
;
i
>=
0
;
i
--
{
e
.
cyclotomicSquare
(
z
,
z
)
if
s
.
Bit
(
i
)
==
1
{
e
.
mul
(
z
,
z
,
a
)
}
}
c
.
set
(
z
)
}
func
(
e
*
fp12
)
frobeniusMap
(
c
,
a
*
fe12
,
power
uint
)
{
fp6
:=
e
.
fp6
fp6
.
frobeniusMap
(
&
c
[
0
],
&
a
[
0
],
power
)
fp6
.
frobeniusMap
(
&
c
[
1
],
&
a
[
1
],
power
)
switch
power
{
case
0
:
return
case
6
:
fp6
.
neg
(
&
c
[
1
],
&
c
[
1
])
default
:
fp6
.
mulByBaseField
(
&
c
[
1
],
&
c
[
1
],
&
frobeniusCoeffs12
[
power
])
}
}
func
(
e
*
fp12
)
frobeniusMapAssign
(
a
*
fe12
,
power
uint
)
{
fp6
:=
e
.
fp6
fp6
.
frobeniusMapAssign
(
&
a
[
0
],
power
)
fp6
.
frobeniusMapAssign
(
&
a
[
1
],
power
)
switch
power
{
case
0
:
return
case
6
:
fp6
.
neg
(
&
a
[
1
],
&
a
[
1
])
default
:
fp6
.
mulByBaseField
(
&
a
[
1
],
&
a
[
1
],
&
frobeniusCoeffs12
[
power
])
}
}
minigeth/crypto/bls12381/fp2.go
0 → 100644
View file @
cc3de083
// Copyright 2020 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package
bls12381
import
(
"errors"
"math/big"
)
type
fp2Temp
struct
{
t
[
4
]
*
fe
}
type
fp2
struct
{
fp2Temp
}
func
newFp2Temp
()
fp2Temp
{
t
:=
[
4
]
*
fe
{}
for
i
:=
0
;
i
<
len
(
t
);
i
++
{
t
[
i
]
=
&
fe
{}
}
return
fp2Temp
{
t
}
}
func
newFp2
()
*
fp2
{
t
:=
newFp2Temp
()
return
&
fp2
{
t
}
}
func
(
e
*
fp2
)
fromBytes
(
in
[]
byte
)
(
*
fe2
,
error
)
{
if
len
(
in
)
!=
96
{
return
nil
,
errors
.
New
(
"length of input string should be 96 bytes"
)
}
c1
,
err
:=
fromBytes
(
in
[
:
48
])
if
err
!=
nil
{
return
nil
,
err
}
c0
,
err
:=
fromBytes
(
in
[
48
:
])
if
err
!=
nil
{
return
nil
,
err
}
return
&
fe2
{
*
c0
,
*
c1
},
nil
}
func
(
e
*
fp2
)
toBytes
(
a
*
fe2
)
[]
byte
{
out
:=
make
([]
byte
,
96
)
copy
(
out
[
:
48
],
toBytes
(
&
a
[
1
]))
copy
(
out
[
48
:
],
toBytes
(
&
a
[
0
]))
return
out
}
func
(
e
*
fp2
)
new
()
*
fe2
{
return
new
(
fe2
)
.
zero
()
}
func
(
e
*
fp2
)
zero
()
*
fe2
{
return
new
(
fe2
)
.
zero
()
}
func
(
e
*
fp2
)
one
()
*
fe2
{
return
new
(
fe2
)
.
one
()
}
func
(
e
*
fp2
)
add
(
c
,
a
,
b
*
fe2
)
{
add
(
&
c
[
0
],
&
a
[
0
],
&
b
[
0
])
add
(
&
c
[
1
],
&
a
[
1
],
&
b
[
1
])
}
func
(
e
*
fp2
)
addAssign
(
a
,
b
*
fe2
)
{
addAssign
(
&
a
[
0
],
&
b
[
0
])
addAssign
(
&
a
[
1
],
&
b
[
1
])
}
func
(
e
*
fp2
)
ladd
(
c
,
a
,
b
*
fe2
)
{
ladd
(
&
c
[
0
],
&
a
[
0
],
&
b
[
0
])
ladd
(
&
c
[
1
],
&
a
[
1
],
&
b
[
1
])
}
func
(
e
*
fp2
)
double
(
c
,
a
*
fe2
)
{
double
(
&
c
[
0
],
&
a
[
0
])
double
(
&
c
[
1
],
&
a
[
1
])
}
func
(
e
*
fp2
)
doubleAssign
(
a
*
fe2
)
{
doubleAssign
(
&
a
[
0
])
doubleAssign
(
&
a
[
1
])
}
func
(
e
*
fp2
)
ldouble
(
c
,
a
*
fe2
)
{
ldouble
(
&
c
[
0
],
&
a
[
0
])
ldouble
(
&
c
[
1
],
&
a
[
1
])
}
func
(
e
*
fp2
)
sub
(
c
,
a
,
b
*
fe2
)
{
sub
(
&
c
[
0
],
&
a
[
0
],
&
b
[
0
])
sub
(
&
c
[
1
],
&
a
[
1
],
&
b
[
1
])
}
func
(
e
*
fp2
)
subAssign
(
c
,
a
*
fe2
)
{
subAssign
(
&
c
[
0
],
&
a
[
0
])
subAssign
(
&
c
[
1
],
&
a
[
1
])
}
func
(
e
*
fp2
)
neg
(
c
,
a
*
fe2
)
{
neg
(
&
c
[
0
],
&
a
[
0
])
neg
(
&
c
[
1
],
&
a
[
1
])
}
func
(
e
*
fp2
)
mul
(
c
,
a
,
b
*
fe2
)
{
t
:=
e
.
t
mul
(
t
[
1
],
&
a
[
0
],
&
b
[
0
])
mul
(
t
[
2
],
&
a
[
1
],
&
b
[
1
])
add
(
t
[
0
],
&
a
[
0
],
&
a
[
1
])
add
(
t
[
3
],
&
b
[
0
],
&
b
[
1
])
sub
(
&
c
[
0
],
t
[
1
],
t
[
2
])
addAssign
(
t
[
1
],
t
[
2
])
mul
(
t
[
0
],
t
[
0
],
t
[
3
])
sub
(
&
c
[
1
],
t
[
0
],
t
[
1
])
}
func
(
e
*
fp2
)
mulAssign
(
a
,
b
*
fe2
)
{
t
:=
e
.
t
mul
(
t
[
1
],
&
a
[
0
],
&
b
[
0
])
mul
(
t
[
2
],
&
a
[
1
],
&
b
[
1
])
add
(
t
[
0
],
&
a
[
0
],
&
a
[
1
])
add
(
t
[
3
],
&
b
[
0
],
&
b
[
1
])
sub
(
&
a
[
0
],
t
[
1
],
t
[
2
])
addAssign
(
t
[
1
],
t
[
2
])
mul
(
t
[
0
],
t
[
0
],
t
[
3
])
sub
(
&
a
[
1
],
t
[
0
],
t
[
1
])
}
func
(
e
*
fp2
)
square
(
c
,
a
*
fe2
)
{
t
:=
e
.
t
ladd
(
t
[
0
],
&
a
[
0
],
&
a
[
1
])
sub
(
t
[
1
],
&
a
[
0
],
&
a
[
1
])
ldouble
(
t
[
2
],
&
a
[
0
])
mul
(
&
c
[
0
],
t
[
0
],
t
[
1
])
mul
(
&
c
[
1
],
t
[
2
],
&
a
[
1
])
}
func
(
e
*
fp2
)
squareAssign
(
a
*
fe2
)
{
t
:=
e
.
t
ladd
(
t
[
0
],
&
a
[
0
],
&
a
[
1
])
sub
(
t
[
1
],
&
a
[
0
],
&
a
[
1
])
ldouble
(
t
[
2
],
&
a
[
0
])
mul
(
&
a
[
0
],
t
[
0
],
t
[
1
])
mul
(
&
a
[
1
],
t
[
2
],
&
a
[
1
])
}
func
(
e
*
fp2
)
mulByNonResidue
(
c
,
a
*
fe2
)
{
t
:=
e
.
t
sub
(
t
[
0
],
&
a
[
0
],
&
a
[
1
])
add
(
&
c
[
1
],
&
a
[
0
],
&
a
[
1
])
c
[
0
]
.
set
(
t
[
0
])
}
func
(
e
*
fp2
)
mulByB
(
c
,
a
*
fe2
)
{
t
:=
e
.
t
double
(
t
[
0
],
&
a
[
0
])
double
(
t
[
1
],
&
a
[
1
])
doubleAssign
(
t
[
0
])
doubleAssign
(
t
[
1
])
sub
(
&
c
[
0
],
t
[
0
],
t
[
1
])
add
(
&
c
[
1
],
t
[
0
],
t
[
1
])
}
func
(
e
*
fp2
)
inverse
(
c
,
a
*
fe2
)
{
t
:=
e
.
t
square
(
t
[
0
],
&
a
[
0
])
square
(
t
[
1
],
&
a
[
1
])
addAssign
(
t
[
0
],
t
[
1
])
inverse
(
t
[
0
],
t
[
0
])
mul
(
&
c
[
0
],
&
a
[
0
],
t
[
0
])
mul
(
t
[
0
],
t
[
0
],
&
a
[
1
])
neg
(
&
c
[
1
],
t
[
0
])
}
func
(
e
*
fp2
)
mulByFq
(
c
,
a
*
fe2
,
b
*
fe
)
{
mul
(
&
c
[
0
],
&
a
[
0
],
b
)
mul
(
&
c
[
1
],
&
a
[
1
],
b
)
}
func
(
e
*
fp2
)
exp
(
c
,
a
*
fe2
,
s
*
big
.
Int
)
{
z
:=
e
.
one
()
for
i
:=
s
.
BitLen
()
-
1
;
i
>=
0
;
i
--
{
e
.
square
(
z
,
z
)
if
s
.
Bit
(
i
)
==
1
{
e
.
mul
(
z
,
z
,
a
)
}
}
c
.
set
(
z
)
}
func
(
e
*
fp2
)
frobeniusMap
(
c
,
a
*
fe2
,
power
uint
)
{
c
[
0
]
.
set
(
&
a
[
0
])
if
power
%
2
==
1
{
neg
(
&
c
[
1
],
&
a
[
1
])
return
}
c
[
1
]
.
set
(
&
a
[
1
])
}
func
(
e
*
fp2
)
frobeniusMapAssign
(
a
*
fe2
,
power
uint
)
{
if
power
%
2
==
1
{
neg
(
&
a
[
1
],
&
a
[
1
])
return
}
}
func
(
e
*
fp2
)
sqrt
(
c
,
a
*
fe2
)
bool
{
u
,
x0
,
a1
,
alpha
:=
&
fe2
{},
&
fe2
{},
&
fe2
{},
&
fe2
{}
u
.
set
(
a
)
e
.
exp
(
a1
,
a
,
pMinus3Over4
)
e
.
square
(
alpha
,
a1
)
e
.
mul
(
alpha
,
alpha
,
a
)
e
.
mul
(
x0
,
a1
,
a
)
if
alpha
.
equal
(
negativeOne2
)
{
neg
(
&
c
[
0
],
&
x0
[
1
])
c
[
1
]
.
set
(
&
x0
[
0
])
return
true
}
e
.
add
(
alpha
,
alpha
,
e
.
one
())
e
.
exp
(
alpha
,
alpha
,
pMinus1Over2
)
e
.
mul
(
c
,
alpha
,
x0
)
e
.
square
(
alpha
,
c
)
return
alpha
.
equal
(
u
)
}
func
(
e
*
fp2
)
isQuadraticNonResidue
(
a
*
fe2
)
bool
{
// https://github.com/leovt/constructible/wiki/Taking-Square-Roots-in-quadratic-extension-Fields
c0
,
c1
:=
new
(
fe
),
new
(
fe
)
square
(
c0
,
&
a
[
0
])
square
(
c1
,
&
a
[
1
])
add
(
c1
,
c1
,
c0
)
return
isQuadraticNonResidue
(
c1
)
}
minigeth/crypto/bls12381/fp6.go
0 → 100644
View file @
cc3de083
// Copyright 2020 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package
bls12381
import
(
"errors"
"math/big"
)
type
fp6Temp
struct
{
t
[
6
]
*
fe2
}
type
fp6
struct
{
fp2
*
fp2
fp6Temp
}
func
newFp6Temp
()
fp6Temp
{
t
:=
[
6
]
*
fe2
{}
for
i
:=
0
;
i
<
len
(
t
);
i
++
{
t
[
i
]
=
&
fe2
{}
}
return
fp6Temp
{
t
}
}
func
newFp6
(
f
*
fp2
)
*
fp6
{
t
:=
newFp6Temp
()
if
f
==
nil
{
return
&
fp6
{
newFp2
(),
t
}
}
return
&
fp6
{
f
,
t
}
}
func
(
e
*
fp6
)
fromBytes
(
b
[]
byte
)
(
*
fe6
,
error
)
{
if
len
(
b
)
<
288
{
return
nil
,
errors
.
New
(
"input string should be larger than 288 bytes"
)
}
fp2
:=
e
.
fp2
u2
,
err
:=
fp2
.
fromBytes
(
b
[
:
96
])
if
err
!=
nil
{
return
nil
,
err
}
u1
,
err
:=
fp2
.
fromBytes
(
b
[
96
:
192
])
if
err
!=
nil
{
return
nil
,
err
}
u0
,
err
:=
fp2
.
fromBytes
(
b
[
192
:
])
if
err
!=
nil
{
return
nil
,
err
}
return
&
fe6
{
*
u0
,
*
u1
,
*
u2
},
nil
}
func
(
e
*
fp6
)
toBytes
(
a
*
fe6
)
[]
byte
{
fp2
:=
e
.
fp2
out
:=
make
([]
byte
,
288
)
copy
(
out
[
:
96
],
fp2
.
toBytes
(
&
a
[
2
]))
copy
(
out
[
96
:
192
],
fp2
.
toBytes
(
&
a
[
1
]))
copy
(
out
[
192
:
],
fp2
.
toBytes
(
&
a
[
0
]))
return
out
}
func
(
e
*
fp6
)
new
()
*
fe6
{
return
new
(
fe6
)
}
func
(
e
*
fp6
)
zero
()
*
fe6
{
return
new
(
fe6
)
}
func
(
e
*
fp6
)
one
()
*
fe6
{
return
new
(
fe6
)
.
one
()
}
func
(
e
*
fp6
)
add
(
c
,
a
,
b
*
fe6
)
{
fp2
:=
e
.
fp2
fp2
.
add
(
&
c
[
0
],
&
a
[
0
],
&
b
[
0
])
fp2
.
add
(
&
c
[
1
],
&
a
[
1
],
&
b
[
1
])
fp2
.
add
(
&
c
[
2
],
&
a
[
2
],
&
b
[
2
])
}
func
(
e
*
fp6
)
addAssign
(
a
,
b
*
fe6
)
{
fp2
:=
e
.
fp2
fp2
.
addAssign
(
&
a
[
0
],
&
b
[
0
])
fp2
.
addAssign
(
&
a
[
1
],
&
b
[
1
])
fp2
.
addAssign
(
&
a
[
2
],
&
b
[
2
])
}
func
(
e
*
fp6
)
double
(
c
,
a
*
fe6
)
{
fp2
:=
e
.
fp2
fp2
.
double
(
&
c
[
0
],
&
a
[
0
])
fp2
.
double
(
&
c
[
1
],
&
a
[
1
])
fp2
.
double
(
&
c
[
2
],
&
a
[
2
])
}
func
(
e
*
fp6
)
doubleAssign
(
a
*
fe6
)
{
fp2
:=
e
.
fp2
fp2
.
doubleAssign
(
&
a
[
0
])
fp2
.
doubleAssign
(
&
a
[
1
])
fp2
.
doubleAssign
(
&
a
[
2
])
}
func
(
e
*
fp6
)
sub
(
c
,
a
,
b
*
fe6
)
{
fp2
:=
e
.
fp2
fp2
.
sub
(
&
c
[
0
],
&
a
[
0
],
&
b
[
0
])
fp2
.
sub
(
&
c
[
1
],
&
a
[
1
],
&
b
[
1
])
fp2
.
sub
(
&
c
[
2
],
&
a
[
2
],
&
b
[
2
])
}
func
(
e
*
fp6
)
subAssign
(
a
,
b
*
fe6
)
{
fp2
:=
e
.
fp2
fp2
.
subAssign
(
&
a
[
0
],
&
b
[
0
])
fp2
.
subAssign
(
&
a
[
1
],
&
b
[
1
])
fp2
.
subAssign
(
&
a
[
2
],
&
b
[
2
])
}
func
(
e
*
fp6
)
neg
(
c
,
a
*
fe6
)
{
fp2
:=
e
.
fp2
fp2
.
neg
(
&
c
[
0
],
&
a
[
0
])
fp2
.
neg
(
&
c
[
1
],
&
a
[
1
])
fp2
.
neg
(
&
c
[
2
],
&
a
[
2
])
}
func
(
e
*
fp6
)
mul
(
c
,
a
,
b
*
fe6
)
{
fp2
,
t
:=
e
.
fp2
,
e
.
t
fp2
.
mul
(
t
[
0
],
&
a
[
0
],
&
b
[
0
])
fp2
.
mul
(
t
[
1
],
&
a
[
1
],
&
b
[
1
])
fp2
.
mul
(
t
[
2
],
&
a
[
2
],
&
b
[
2
])
fp2
.
add
(
t
[
3
],
&
a
[
1
],
&
a
[
2
])
fp2
.
add
(
t
[
4
],
&
b
[
1
],
&
b
[
2
])
fp2
.
mulAssign
(
t
[
3
],
t
[
4
])
fp2
.
add
(
t
[
4
],
t
[
1
],
t
[
2
])
fp2
.
subAssign
(
t
[
3
],
t
[
4
])
fp2
.
mulByNonResidue
(
t
[
3
],
t
[
3
])
fp2
.
add
(
t
[
5
],
t
[
0
],
t
[
3
])
fp2
.
add
(
t
[
3
],
&
a
[
0
],
&
a
[
1
])
fp2
.
add
(
t
[
4
],
&
b
[
0
],
&
b
[
1
])
fp2
.
mulAssign
(
t
[
3
],
t
[
4
])
fp2
.
add
(
t
[
4
],
t
[
0
],
t
[
1
])
fp2
.
subAssign
(
t
[
3
],
t
[
4
])
fp2
.
mulByNonResidue
(
t
[
4
],
t
[
2
])
fp2
.
add
(
&
c
[
1
],
t
[
3
],
t
[
4
])
fp2
.
add
(
t
[
3
],
&
a
[
0
],
&
a
[
2
])
fp2
.
add
(
t
[
4
],
&
b
[
0
],
&
b
[
2
])
fp2
.
mulAssign
(
t
[
3
],
t
[
4
])
fp2
.
add
(
t
[
4
],
t
[
0
],
t
[
2
])
fp2
.
subAssign
(
t
[
3
],
t
[
4
])
fp2
.
add
(
&
c
[
2
],
t
[
1
],
t
[
3
])
c
[
0
]
.
set
(
t
[
5
])
}
func
(
e
*
fp6
)
mulAssign
(
a
,
b
*
fe6
)
{
fp2
,
t
:=
e
.
fp2
,
e
.
t
fp2
.
mul
(
t
[
0
],
&
a
[
0
],
&
b
[
0
])
fp2
.
mul
(
t
[
1
],
&
a
[
1
],
&
b
[
1
])
fp2
.
mul
(
t
[
2
],
&
a
[
2
],
&
b
[
2
])
fp2
.
add
(
t
[
3
],
&
a
[
1
],
&
a
[
2
])
fp2
.
add
(
t
[
4
],
&
b
[
1
],
&
b
[
2
])
fp2
.
mulAssign
(
t
[
3
],
t
[
4
])
fp2
.
add
(
t
[
4
],
t
[
1
],
t
[
2
])
fp2
.
subAssign
(
t
[
3
],
t
[
4
])
fp2
.
mulByNonResidue
(
t
[
3
],
t
[
3
])
fp2
.
add
(
t
[
5
],
t
[
0
],
t
[
3
])
fp2
.
add
(
t
[
3
],
&
a
[
0
],
&
a
[
1
])
fp2
.
add
(
t
[
4
],
&
b
[
0
],
&
b
[
1
])
fp2
.
mulAssign
(
t
[
3
],
t
[
4
])
fp2
.
add
(
t
[
4
],
t
[
0
],
t
[
1
])
fp2
.
subAssign
(
t
[
3
],
t
[
4
])
fp2
.
mulByNonResidue
(
t
[
4
],
t
[
2
])
fp2
.
add
(
&
a
[
1
],
t
[
3
],
t
[
4
])
fp2
.
add
(
t
[
3
],
&
a
[
0
],
&
a
[
2
])
fp2
.
add
(
t
[
4
],
&
b
[
0
],
&
b
[
2
])
fp2
.
mulAssign
(
t
[
3
],
t
[
4
])
fp2
.
add
(
t
[
4
],
t
[
0
],
t
[
2
])
fp2
.
subAssign
(
t
[
3
],
t
[
4
])
fp2
.
add
(
&
a
[
2
],
t
[
1
],
t
[
3
])
a
[
0
]
.
set
(
t
[
5
])
}
func
(
e
*
fp6
)
square
(
c
,
a
*
fe6
)
{
fp2
,
t
:=
e
.
fp2
,
e
.
t
fp2
.
square
(
t
[
0
],
&
a
[
0
])
fp2
.
mul
(
t
[
1
],
&
a
[
0
],
&
a
[
1
])
fp2
.
doubleAssign
(
t
[
1
])
fp2
.
sub
(
t
[
2
],
&
a
[
0
],
&
a
[
1
])
fp2
.
addAssign
(
t
[
2
],
&
a
[
2
])
fp2
.
squareAssign
(
t
[
2
])
fp2
.
mul
(
t
[
3
],
&
a
[
1
],
&
a
[
2
])
fp2
.
doubleAssign
(
t
[
3
])
fp2
.
square
(
t
[
4
],
&
a
[
2
])
fp2
.
mulByNonResidue
(
t
[
5
],
t
[
3
])
fp2
.
add
(
&
c
[
0
],
t
[
0
],
t
[
5
])
fp2
.
mulByNonResidue
(
t
[
5
],
t
[
4
])
fp2
.
add
(
&
c
[
1
],
t
[
1
],
t
[
5
])
fp2
.
addAssign
(
t
[
1
],
t
[
2
])
fp2
.
addAssign
(
t
[
1
],
t
[
3
])
fp2
.
addAssign
(
t
[
0
],
t
[
4
])
fp2
.
sub
(
&
c
[
2
],
t
[
1
],
t
[
0
])
}
func
(
e
*
fp6
)
mulBy01Assign
(
a
*
fe6
,
b0
,
b1
*
fe2
)
{
fp2
,
t
:=
e
.
fp2
,
e
.
t
fp2
.
mul
(
t
[
0
],
&
a
[
0
],
b0
)
fp2
.
mul
(
t
[
1
],
&
a
[
1
],
b1
)
fp2
.
add
(
t
[
5
],
&
a
[
1
],
&
a
[
2
])
fp2
.
mul
(
t
[
2
],
b1
,
t
[
5
])
fp2
.
subAssign
(
t
[
2
],
t
[
1
])
fp2
.
mulByNonResidue
(
t
[
2
],
t
[
2
])
fp2
.
add
(
t
[
5
],
&
a
[
0
],
&
a
[
2
])
fp2
.
mul
(
t
[
3
],
b0
,
t
[
5
])
fp2
.
subAssign
(
t
[
3
],
t
[
0
])
fp2
.
add
(
&
a
[
2
],
t
[
3
],
t
[
1
])
fp2
.
add
(
t
[
4
],
b0
,
b1
)
fp2
.
add
(
t
[
5
],
&
a
[
0
],
&
a
[
1
])
fp2
.
mulAssign
(
t
[
4
],
t
[
5
])
fp2
.
subAssign
(
t
[
4
],
t
[
0
])
fp2
.
sub
(
&
a
[
1
],
t
[
4
],
t
[
1
])
fp2
.
add
(
&
a
[
0
],
t
[
2
],
t
[
0
])
}
func
(
e
*
fp6
)
mulBy01
(
c
,
a
*
fe6
,
b0
,
b1
*
fe2
)
{
fp2
,
t
:=
e
.
fp2
,
e
.
t
fp2
.
mul
(
t
[
0
],
&
a
[
0
],
b0
)
fp2
.
mul
(
t
[
1
],
&
a
[
1
],
b1
)
fp2
.
add
(
t
[
2
],
&
a
[
1
],
&
a
[
2
])
fp2
.
mulAssign
(
t
[
2
],
b1
)
fp2
.
subAssign
(
t
[
2
],
t
[
1
])
fp2
.
mulByNonResidue
(
t
[
2
],
t
[
2
])
fp2
.
add
(
t
[
3
],
&
a
[
0
],
&
a
[
2
])
fp2
.
mulAssign
(
t
[
3
],
b0
)
fp2
.
subAssign
(
t
[
3
],
t
[
0
])
fp2
.
add
(
&
c
[
2
],
t
[
3
],
t
[
1
])
fp2
.
add
(
t
[
4
],
b0
,
b1
)
fp2
.
add
(
t
[
3
],
&
a
[
0
],
&
a
[
1
])
fp2
.
mulAssign
(
t
[
4
],
t
[
3
])
fp2
.
subAssign
(
t
[
4
],
t
[
0
])
fp2
.
sub
(
&
c
[
1
],
t
[
4
],
t
[
1
])
fp2
.
add
(
&
c
[
0
],
t
[
2
],
t
[
0
])
}
func
(
e
*
fp6
)
mulBy1
(
c
,
a
*
fe6
,
b1
*
fe2
)
{
fp2
,
t
:=
e
.
fp2
,
e
.
t
fp2
.
mul
(
t
[
0
],
&
a
[
2
],
b1
)
fp2
.
mul
(
&
c
[
2
],
&
a
[
1
],
b1
)
fp2
.
mul
(
&
c
[
1
],
&
a
[
0
],
b1
)
fp2
.
mulByNonResidue
(
&
c
[
0
],
t
[
0
])
}
func
(
e
*
fp6
)
mulByNonResidue
(
c
,
a
*
fe6
)
{
fp2
,
t
:=
e
.
fp2
,
e
.
t
t
[
0
]
.
set
(
&
a
[
0
])
fp2
.
mulByNonResidue
(
&
c
[
0
],
&
a
[
2
])
c
[
2
]
.
set
(
&
a
[
1
])
c
[
1
]
.
set
(
t
[
0
])
}
func
(
e
*
fp6
)
mulByBaseField
(
c
,
a
*
fe6
,
b
*
fe2
)
{
fp2
:=
e
.
fp2
fp2
.
mul
(
&
c
[
0
],
&
a
[
0
],
b
)
fp2
.
mul
(
&
c
[
1
],
&
a
[
1
],
b
)
fp2
.
mul
(
&
c
[
2
],
&
a
[
2
],
b
)
}
func
(
e
*
fp6
)
exp
(
c
,
a
*
fe6
,
s
*
big
.
Int
)
{
z
:=
e
.
one
()
for
i
:=
s
.
BitLen
()
-
1
;
i
>=
0
;
i
--
{
e
.
square
(
z
,
z
)
if
s
.
Bit
(
i
)
==
1
{
e
.
mul
(
z
,
z
,
a
)
}
}
c
.
set
(
z
)
}
func
(
e
*
fp6
)
inverse
(
c
,
a
*
fe6
)
{
fp2
,
t
:=
e
.
fp2
,
e
.
t
fp2
.
square
(
t
[
0
],
&
a
[
0
])
fp2
.
mul
(
t
[
1
],
&
a
[
1
],
&
a
[
2
])
fp2
.
mulByNonResidue
(
t
[
1
],
t
[
1
])
fp2
.
subAssign
(
t
[
0
],
t
[
1
])
fp2
.
square
(
t
[
1
],
&
a
[
1
])
fp2
.
mul
(
t
[
2
],
&
a
[
0
],
&
a
[
2
])
fp2
.
subAssign
(
t
[
1
],
t
[
2
])
fp2
.
square
(
t
[
2
],
&
a
[
2
])
fp2
.
mulByNonResidue
(
t
[
2
],
t
[
2
])
fp2
.
mul
(
t
[
3
],
&
a
[
0
],
&
a
[
1
])
fp2
.
subAssign
(
t
[
2
],
t
[
3
])
fp2
.
mul
(
t
[
3
],
&
a
[
2
],
t
[
2
])
fp2
.
mul
(
t
[
4
],
&
a
[
1
],
t
[
1
])
fp2
.
addAssign
(
t
[
3
],
t
[
4
])
fp2
.
mulByNonResidue
(
t
[
3
],
t
[
3
])
fp2
.
mul
(
t
[
4
],
&
a
[
0
],
t
[
0
])
fp2
.
addAssign
(
t
[
3
],
t
[
4
])
fp2
.
inverse
(
t
[
3
],
t
[
3
])
fp2
.
mul
(
&
c
[
0
],
t
[
0
],
t
[
3
])
fp2
.
mul
(
&
c
[
1
],
t
[
2
],
t
[
3
])
fp2
.
mul
(
&
c
[
2
],
t
[
1
],
t
[
3
])
}
func
(
e
*
fp6
)
frobeniusMap
(
c
,
a
*
fe6
,
power
uint
)
{
fp2
:=
e
.
fp2
fp2
.
frobeniusMap
(
&
c
[
0
],
&
a
[
0
],
power
)
fp2
.
frobeniusMap
(
&
c
[
1
],
&
a
[
1
],
power
)
fp2
.
frobeniusMap
(
&
c
[
2
],
&
a
[
2
],
power
)
switch
power
%
6
{
case
0
:
return
case
3
:
neg
(
&
c
[
0
][
0
],
&
a
[
1
][
1
])
c
[
1
][
1
]
.
set
(
&
a
[
1
][
0
])
fp2
.
neg
(
&
a
[
2
],
&
a
[
2
])
default
:
fp2
.
mul
(
&
c
[
1
],
&
c
[
1
],
&
frobeniusCoeffs61
[
power
%
6
])
fp2
.
mul
(
&
c
[
2
],
&
c
[
2
],
&
frobeniusCoeffs62
[
power
%
6
])
}
}
func
(
e
*
fp6
)
frobeniusMapAssign
(
a
*
fe6
,
power
uint
)
{
fp2
:=
e
.
fp2
fp2
.
frobeniusMapAssign
(
&
a
[
0
],
power
)
fp2
.
frobeniusMapAssign
(
&
a
[
1
],
power
)
fp2
.
frobeniusMapAssign
(
&
a
[
2
],
power
)
t
:=
e
.
t
switch
power
%
6
{
case
0
:
return
case
3
:
neg
(
&
t
[
0
][
0
],
&
a
[
1
][
1
])
a
[
1
][
1
]
.
set
(
&
a
[
1
][
0
])
a
[
1
][
0
]
.
set
(
&
t
[
0
][
0
])
fp2
.
neg
(
&
a
[
2
],
&
a
[
2
])
default
:
fp2
.
mulAssign
(
&
a
[
1
],
&
frobeniusCoeffs61
[
power
%
6
])
fp2
.
mulAssign
(
&
a
[
2
],
&
frobeniusCoeffs62
[
power
%
6
])
}
}
minigeth/crypto/bls12381/g1.go
0 → 100644
View file @
cc3de083
This diff is collapsed.
Click to expand it.
minigeth/crypto/bls12381/g2.go
0 → 100644
View file @
cc3de083
This diff is collapsed.
Click to expand it.
minigeth/crypto/bls12381/gt.go
0 → 100644
View file @
cc3de083
// Copyright 2020 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package
bls12381
import
(
"errors"
"math/big"
)
// E is type for target group element
type
E
=
fe12
// GT is type for target multiplicative group GT.
type
GT
struct
{
fp12
*
fp12
}
func
(
e
*
E
)
Set
(
e2
*
E
)
*
E
{
return
e
.
set
(
e2
)
}
// One sets a new target group element to one
func
(
e
*
E
)
One
()
*
E
{
e
=
new
(
fe12
)
.
one
()
return
e
}
// IsOne returns true if given element equals to one
func
(
e
*
E
)
IsOne
()
bool
{
return
e
.
isOne
()
}
// Equal returns true if given two element is equal, otherwise returns false
func
(
g
*
E
)
Equal
(
g2
*
E
)
bool
{
return
g
.
equal
(
g2
)
}
// NewGT constructs new target group instance.
func
NewGT
()
*
GT
{
fp12
:=
newFp12
(
nil
)
return
&
GT
{
fp12
}
}
// Q returns group order in big.Int.
func
(
g
*
GT
)
Q
()
*
big
.
Int
{
return
new
(
big
.
Int
)
.
Set
(
q
)
}
// FromBytes expects 576 byte input and returns target group element
// FromBytes returns error if given element is not on correct subgroup.
func
(
g
*
GT
)
FromBytes
(
in
[]
byte
)
(
*
E
,
error
)
{
e
,
err
:=
g
.
fp12
.
fromBytes
(
in
)
if
err
!=
nil
{
return
nil
,
err
}
if
!
g
.
IsValid
(
e
)
{
return
e
,
errors
.
New
(
"invalid element"
)
}
return
e
,
nil
}
// ToBytes serializes target group element.
func
(
g
*
GT
)
ToBytes
(
e
*
E
)
[]
byte
{
return
g
.
fp12
.
toBytes
(
e
)
}
// IsValid checks whether given target group element is in correct subgroup.
func
(
g
*
GT
)
IsValid
(
e
*
E
)
bool
{
r
:=
g
.
New
()
g
.
fp12
.
exp
(
r
,
e
,
q
)
return
r
.
isOne
()
}
// New initializes a new target group element which is equal to one
func
(
g
*
GT
)
New
()
*
E
{
return
new
(
E
)
.
One
()
}
// Add adds two field element `a` and `b` and assigns the result to the element in first argument.
func
(
g
*
GT
)
Add
(
c
,
a
,
b
*
E
)
{
g
.
fp12
.
add
(
c
,
a
,
b
)
}
// Sub subtracts two field element `a` and `b`, and assigns the result to the element in first argument.
func
(
g
*
GT
)
Sub
(
c
,
a
,
b
*
E
)
{
g
.
fp12
.
sub
(
c
,
a
,
b
)
}
// Mul multiplies two field element `a` and `b` and assigns the result to the element in first argument.
func
(
g
*
GT
)
Mul
(
c
,
a
,
b
*
E
)
{
g
.
fp12
.
mul
(
c
,
a
,
b
)
}
// Square squares an element `a` and assigns the result to the element in first argument.
func
(
g
*
GT
)
Square
(
c
,
a
*
E
)
{
g
.
fp12
.
cyclotomicSquare
(
c
,
a
)
}
// Exp exponents an element `a` by a scalar `s` and assigns the result to the element in first argument.
func
(
g
*
GT
)
Exp
(
c
,
a
*
E
,
s
*
big
.
Int
)
{
g
.
fp12
.
cyclotomicExp
(
c
,
a
,
s
)
}
// Inverse inverses an element `a` and assigns the result to the element in first argument.
func
(
g
*
GT
)
Inverse
(
c
,
a
*
E
)
{
g
.
fp12
.
inverse
(
c
,
a
)
}
minigeth/crypto/bls12381/isogeny.go
0 → 100644
View file @
cc3de083
This diff is collapsed.
Click to expand it.
minigeth/crypto/bls12381/pairing.go
0 → 100644
View file @
cc3de083
// Copyright 2020 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package
bls12381
type
pair
struct
{
g1
*
PointG1
g2
*
PointG2
}
func
newPair
(
g1
*
PointG1
,
g2
*
PointG2
)
pair
{
return
pair
{
g1
,
g2
}
}
// Engine is BLS12-381 elliptic curve pairing engine
type
Engine
struct
{
G1
*
G1
G2
*
G2
fp12
*
fp12
fp2
*
fp2
pairingEngineTemp
pairs
[]
pair
}
// NewPairingEngine creates new pairing engine instance.
func
NewPairingEngine
()
*
Engine
{
fp2
:=
newFp2
()
fp6
:=
newFp6
(
fp2
)
fp12
:=
newFp12
(
fp6
)
g1
:=
NewG1
()
g2
:=
newG2
(
fp2
)
return
&
Engine
{
fp2
:
fp2
,
fp12
:
fp12
,
G1
:
g1
,
G2
:
g2
,
pairingEngineTemp
:
newEngineTemp
(),
}
}
type
pairingEngineTemp
struct
{
t2
[
10
]
*
fe2
t12
[
9
]
fe12
}
func
newEngineTemp
()
pairingEngineTemp
{
t2
:=
[
10
]
*
fe2
{}
for
i
:=
0
;
i
<
10
;
i
++
{
t2
[
i
]
=
&
fe2
{}
}
t12
:=
[
9
]
fe12
{}
return
pairingEngineTemp
{
t2
,
t12
}
}
// AddPair adds a g1, g2 point pair to pairing engine
func
(
e
*
Engine
)
AddPair
(
g1
*
PointG1
,
g2
*
PointG2
)
*
Engine
{
p
:=
newPair
(
g1
,
g2
)
if
!
e
.
isZero
(
p
)
{
e
.
affine
(
p
)
e
.
pairs
=
append
(
e
.
pairs
,
p
)
}
return
e
}
// AddPairInv adds a G1, G2 point pair to pairing engine. G1 point is negated.
func
(
e
*
Engine
)
AddPairInv
(
g1
*
PointG1
,
g2
*
PointG2
)
*
Engine
{
e
.
G1
.
Neg
(
g1
,
g1
)
e
.
AddPair
(
g1
,
g2
)
return
e
}
// Reset deletes added pairs.
func
(
e
*
Engine
)
Reset
()
*
Engine
{
e
.
pairs
=
[]
pair
{}
return
e
}
func
(
e
*
Engine
)
isZero
(
p
pair
)
bool
{
return
e
.
G1
.
IsZero
(
p
.
g1
)
||
e
.
G2
.
IsZero
(
p
.
g2
)
}
func
(
e
*
Engine
)
affine
(
p
pair
)
{
e
.
G1
.
Affine
(
p
.
g1
)
e
.
G2
.
Affine
(
p
.
g2
)
}
func
(
e
*
Engine
)
doublingStep
(
coeff
*
[
3
]
fe2
,
r
*
PointG2
)
{
// Adaptation of Formula 3 in https://eprint.iacr.org/2010/526.pdf
fp2
:=
e
.
fp2
t
:=
e
.
t2
fp2
.
mul
(
t
[
0
],
&
r
[
0
],
&
r
[
1
])
fp2
.
mulByFq
(
t
[
0
],
t
[
0
],
twoInv
)
fp2
.
square
(
t
[
1
],
&
r
[
1
])
fp2
.
square
(
t
[
2
],
&
r
[
2
])
fp2
.
double
(
t
[
7
],
t
[
2
])
fp2
.
add
(
t
[
7
],
t
[
7
],
t
[
2
])
fp2
.
mulByB
(
t
[
3
],
t
[
7
])
fp2
.
double
(
t
[
4
],
t
[
3
])
fp2
.
add
(
t
[
4
],
t
[
4
],
t
[
3
])
fp2
.
add
(
t
[
5
],
t
[
1
],
t
[
4
])
fp2
.
mulByFq
(
t
[
5
],
t
[
5
],
twoInv
)
fp2
.
add
(
t
[
6
],
&
r
[
1
],
&
r
[
2
])
fp2
.
square
(
t
[
6
],
t
[
6
])
fp2
.
add
(
t
[
7
],
t
[
2
],
t
[
1
])
fp2
.
sub
(
t
[
6
],
t
[
6
],
t
[
7
])
fp2
.
sub
(
&
coeff
[
0
],
t
[
3
],
t
[
1
])
fp2
.
square
(
t
[
7
],
&
r
[
0
])
fp2
.
sub
(
t
[
4
],
t
[
1
],
t
[
4
])
fp2
.
mul
(
&
r
[
0
],
t
[
4
],
t
[
0
])
fp2
.
square
(
t
[
2
],
t
[
3
])
fp2
.
double
(
t
[
3
],
t
[
2
])
fp2
.
add
(
t
[
3
],
t
[
3
],
t
[
2
])
fp2
.
square
(
t
[
5
],
t
[
5
])
fp2
.
sub
(
&
r
[
1
],
t
[
5
],
t
[
3
])
fp2
.
mul
(
&
r
[
2
],
t
[
1
],
t
[
6
])
fp2
.
double
(
t
[
0
],
t
[
7
])
fp2
.
add
(
&
coeff
[
1
],
t
[
0
],
t
[
7
])
fp2
.
neg
(
&
coeff
[
2
],
t
[
6
])
}
func
(
e
*
Engine
)
additionStep
(
coeff
*
[
3
]
fe2
,
r
,
q
*
PointG2
)
{
// Algorithm 12 in https://eprint.iacr.org/2010/526.pdf
fp2
:=
e
.
fp2
t
:=
e
.
t2
fp2
.
mul
(
t
[
0
],
&
q
[
1
],
&
r
[
2
])
fp2
.
neg
(
t
[
0
],
t
[
0
])
fp2
.
add
(
t
[
0
],
t
[
0
],
&
r
[
1
])
fp2
.
mul
(
t
[
1
],
&
q
[
0
],
&
r
[
2
])
fp2
.
neg
(
t
[
1
],
t
[
1
])
fp2
.
add
(
t
[
1
],
t
[
1
],
&
r
[
0
])
fp2
.
square
(
t
[
2
],
t
[
0
])
fp2
.
square
(
t
[
3
],
t
[
1
])
fp2
.
mul
(
t
[
4
],
t
[
1
],
t
[
3
])
fp2
.
mul
(
t
[
2
],
&
r
[
2
],
t
[
2
])
fp2
.
mul
(
t
[
3
],
&
r
[
0
],
t
[
3
])
fp2
.
double
(
t
[
5
],
t
[
3
])
fp2
.
sub
(
t
[
5
],
t
[
4
],
t
[
5
])
fp2
.
add
(
t
[
5
],
t
[
5
],
t
[
2
])
fp2
.
mul
(
&
r
[
0
],
t
[
1
],
t
[
5
])
fp2
.
sub
(
t
[
2
],
t
[
3
],
t
[
5
])
fp2
.
mul
(
t
[
2
],
t
[
2
],
t
[
0
])
fp2
.
mul
(
t
[
3
],
&
r
[
1
],
t
[
4
])
fp2
.
sub
(
&
r
[
1
],
t
[
2
],
t
[
3
])
fp2
.
mul
(
&
r
[
2
],
&
r
[
2
],
t
[
4
])
fp2
.
mul
(
t
[
2
],
t
[
1
],
&
q
[
1
])
fp2
.
mul
(
t
[
3
],
t
[
0
],
&
q
[
0
])
fp2
.
sub
(
&
coeff
[
0
],
t
[
3
],
t
[
2
])
fp2
.
neg
(
&
coeff
[
1
],
t
[
0
])
coeff
[
2
]
.
set
(
t
[
1
])
}
func
(
e
*
Engine
)
preCompute
(
ellCoeffs
*
[
68
][
3
]
fe2
,
twistPoint
*
PointG2
)
{
// Algorithm 5 in https://eprint.iacr.org/2019/077.pdf
if
e
.
G2
.
IsZero
(
twistPoint
)
{
return
}
r
:=
new
(
PointG2
)
.
Set
(
twistPoint
)
j
:=
0
for
i
:=
x
.
BitLen
()
-
2
;
i
>=
0
;
i
--
{
e
.
doublingStep
(
&
ellCoeffs
[
j
],
r
)
if
x
.
Bit
(
i
)
!=
0
{
j
++
ellCoeffs
[
j
]
=
fe6
{}
e
.
additionStep
(
&
ellCoeffs
[
j
],
r
,
twistPoint
)
}
j
++
}
}
func
(
e
*
Engine
)
millerLoop
(
f
*
fe12
)
{
pairs
:=
e
.
pairs
ellCoeffs
:=
make
([][
68
][
3
]
fe2
,
len
(
pairs
))
for
i
:=
0
;
i
<
len
(
pairs
);
i
++
{
e
.
preCompute
(
&
ellCoeffs
[
i
],
pairs
[
i
]
.
g2
)
}
fp12
,
fp2
:=
e
.
fp12
,
e
.
fp2
t
:=
e
.
t2
f
.
one
()
j
:=
0
for
i
:=
62
;
/* x.BitLen() - 2 */
i
>=
0
;
i
--
{
if
i
!=
62
{
fp12
.
square
(
f
,
f
)
}
for
i
:=
0
;
i
<=
len
(
pairs
)
-
1
;
i
++
{
fp2
.
mulByFq
(
t
[
0
],
&
ellCoeffs
[
i
][
j
][
2
],
&
pairs
[
i
]
.
g1
[
1
])
fp2
.
mulByFq
(
t
[
1
],
&
ellCoeffs
[
i
][
j
][
1
],
&
pairs
[
i
]
.
g1
[
0
])
fp12
.
mulBy014Assign
(
f
,
&
ellCoeffs
[
i
][
j
][
0
],
t
[
1
],
t
[
0
])
}
if
x
.
Bit
(
i
)
!=
0
{
j
++
for
i
:=
0
;
i
<=
len
(
pairs
)
-
1
;
i
++
{
fp2
.
mulByFq
(
t
[
0
],
&
ellCoeffs
[
i
][
j
][
2
],
&
pairs
[
i
]
.
g1
[
1
])
fp2
.
mulByFq
(
t
[
1
],
&
ellCoeffs
[
i
][
j
][
1
],
&
pairs
[
i
]
.
g1
[
0
])
fp12
.
mulBy014Assign
(
f
,
&
ellCoeffs
[
i
][
j
][
0
],
t
[
1
],
t
[
0
])
}
}
j
++
}
fp12
.
conjugate
(
f
,
f
)
}
func
(
e
*
Engine
)
exp
(
c
,
a
*
fe12
)
{
fp12
:=
e
.
fp12
fp12
.
cyclotomicExp
(
c
,
a
,
x
)
fp12
.
conjugate
(
c
,
c
)
}
func
(
e
*
Engine
)
finalExp
(
f
*
fe12
)
{
fp12
:=
e
.
fp12
t
:=
e
.
t12
// easy part
fp12
.
frobeniusMap
(
&
t
[
0
],
f
,
6
)
fp12
.
inverse
(
&
t
[
1
],
f
)
fp12
.
mul
(
&
t
[
2
],
&
t
[
0
],
&
t
[
1
])
t
[
1
]
.
set
(
&
t
[
2
])
fp12
.
frobeniusMapAssign
(
&
t
[
2
],
2
)
fp12
.
mulAssign
(
&
t
[
2
],
&
t
[
1
])
fp12
.
cyclotomicSquare
(
&
t
[
1
],
&
t
[
2
])
fp12
.
conjugate
(
&
t
[
1
],
&
t
[
1
])
// hard part
e
.
exp
(
&
t
[
3
],
&
t
[
2
])
fp12
.
cyclotomicSquare
(
&
t
[
4
],
&
t
[
3
])
fp12
.
mul
(
&
t
[
5
],
&
t
[
1
],
&
t
[
3
])
e
.
exp
(
&
t
[
1
],
&
t
[
5
])
e
.
exp
(
&
t
[
0
],
&
t
[
1
])
e
.
exp
(
&
t
[
6
],
&
t
[
0
])
fp12
.
mulAssign
(
&
t
[
6
],
&
t
[
4
])
e
.
exp
(
&
t
[
4
],
&
t
[
6
])
fp12
.
conjugate
(
&
t
[
5
],
&
t
[
5
])
fp12
.
mulAssign
(
&
t
[
4
],
&
t
[
5
])
fp12
.
mulAssign
(
&
t
[
4
],
&
t
[
2
])
fp12
.
conjugate
(
&
t
[
5
],
&
t
[
2
])
fp12
.
mulAssign
(
&
t
[
1
],
&
t
[
2
])
fp12
.
frobeniusMapAssign
(
&
t
[
1
],
3
)
fp12
.
mulAssign
(
&
t
[
6
],
&
t
[
5
])
fp12
.
frobeniusMapAssign
(
&
t
[
6
],
1
)
fp12
.
mulAssign
(
&
t
[
3
],
&
t
[
0
])
fp12
.
frobeniusMapAssign
(
&
t
[
3
],
2
)
fp12
.
mulAssign
(
&
t
[
3
],
&
t
[
1
])
fp12
.
mulAssign
(
&
t
[
3
],
&
t
[
6
])
fp12
.
mul
(
f
,
&
t
[
3
],
&
t
[
4
])
}
func
(
e
*
Engine
)
calculate
()
*
fe12
{
f
:=
e
.
fp12
.
one
()
if
len
(
e
.
pairs
)
==
0
{
return
f
}
e
.
millerLoop
(
f
)
e
.
finalExp
(
f
)
return
f
}
// Check computes pairing and checks if result is equal to one
func
(
e
*
Engine
)
Check
()
bool
{
return
e
.
calculate
()
.
isOne
()
}
// Result computes pairing and returns target group element as result.
func
(
e
*
Engine
)
Result
()
*
E
{
r
:=
e
.
calculate
()
e
.
Reset
()
return
r
}
// GT returns target group instance.
func
(
e
*
Engine
)
GT
()
*
GT
{
return
NewGT
()
}
minigeth/crypto/bls12381/swu.go
0 → 100644
View file @
cc3de083
// Copyright 2020 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package
bls12381
// swuMapG1 is implementation of Simplified Shallue-van de Woestijne-Ulas Method
// follows the implmentation at draft-irtf-cfrg-hash-to-curve-06.
func
swuMapG1
(
u
*
fe
)
(
*
fe
,
*
fe
)
{
var
params
=
swuParamsForG1
var
tv
[
4
]
*
fe
for
i
:=
0
;
i
<
4
;
i
++
{
tv
[
i
]
=
new
(
fe
)
}
square
(
tv
[
0
],
u
)
mul
(
tv
[
0
],
tv
[
0
],
params
.
z
)
square
(
tv
[
1
],
tv
[
0
])
x1
:=
new
(
fe
)
add
(
x1
,
tv
[
0
],
tv
[
1
])
inverse
(
x1
,
x1
)
e1
:=
x1
.
isZero
()
one
:=
new
(
fe
)
.
one
()
add
(
x1
,
x1
,
one
)
if
e1
{
x1
.
set
(
params
.
zInv
)
}
mul
(
x1
,
x1
,
params
.
minusBOverA
)
gx1
:=
new
(
fe
)
square
(
gx1
,
x1
)
add
(
gx1
,
gx1
,
params
.
a
)
mul
(
gx1
,
gx1
,
x1
)
add
(
gx1
,
gx1
,
params
.
b
)
x2
:=
new
(
fe
)
mul
(
x2
,
tv
[
0
],
x1
)
mul
(
tv
[
1
],
tv
[
0
],
tv
[
1
])
gx2
:=
new
(
fe
)
mul
(
gx2
,
gx1
,
tv
[
1
])
e2
:=
!
isQuadraticNonResidue
(
gx1
)
x
,
y2
:=
new
(
fe
),
new
(
fe
)
if
e2
{
x
.
set
(
x1
)
y2
.
set
(
gx1
)
}
else
{
x
.
set
(
x2
)
y2
.
set
(
gx2
)
}
y
:=
new
(
fe
)
sqrt
(
y
,
y2
)
if
y
.
sign
()
!=
u
.
sign
()
{
neg
(
y
,
y
)
}
return
x
,
y
}
// swuMapG2 is implementation of Simplified Shallue-van de Woestijne-Ulas Method
// defined at draft-irtf-cfrg-hash-to-curve-06.
func
swuMapG2
(
e
*
fp2
,
u
*
fe2
)
(
*
fe2
,
*
fe2
)
{
if
e
==
nil
{
e
=
newFp2
()
}
params
:=
swuParamsForG2
var
tv
[
4
]
*
fe2
for
i
:=
0
;
i
<
4
;
i
++
{
tv
[
i
]
=
e
.
new
()
}
e
.
square
(
tv
[
0
],
u
)
e
.
mul
(
tv
[
0
],
tv
[
0
],
params
.
z
)
e
.
square
(
tv
[
1
],
tv
[
0
])
x1
:=
e
.
new
()
e
.
add
(
x1
,
tv
[
0
],
tv
[
1
])
e
.
inverse
(
x1
,
x1
)
e1
:=
x1
.
isZero
()
e
.
add
(
x1
,
x1
,
e
.
one
())
if
e1
{
x1
.
set
(
params
.
zInv
)
}
e
.
mul
(
x1
,
x1
,
params
.
minusBOverA
)
gx1
:=
e
.
new
()
e
.
square
(
gx1
,
x1
)
e
.
add
(
gx1
,
gx1
,
params
.
a
)
e
.
mul
(
gx1
,
gx1
,
x1
)
e
.
add
(
gx1
,
gx1
,
params
.
b
)
x2
:=
e
.
new
()
e
.
mul
(
x2
,
tv
[
0
],
x1
)
e
.
mul
(
tv
[
1
],
tv
[
0
],
tv
[
1
])
gx2
:=
e
.
new
()
e
.
mul
(
gx2
,
gx1
,
tv
[
1
])
e2
:=
!
e
.
isQuadraticNonResidue
(
gx1
)
x
,
y2
:=
e
.
new
(),
e
.
new
()
if
e2
{
x
.
set
(
x1
)
y2
.
set
(
gx1
)
}
else
{
x
.
set
(
x2
)
y2
.
set
(
gx2
)
}
y
:=
e
.
new
()
e
.
sqrt
(
y
,
y2
)
if
y
.
sign
()
!=
u
.
sign
()
{
e
.
neg
(
y
,
y
)
}
return
x
,
y
}
var
swuParamsForG1
=
struct
{
z
*
fe
zInv
*
fe
a
*
fe
b
*
fe
minusBOverA
*
fe
}{
a
:
&
fe
{
0x2f65aa0e9af5aa51
,
0x86464c2d1e8416c3
,
0xb85ce591b7bd31e2
,
0x27e11c91b5f24e7c
,
0x28376eda6bfc1835
,
0x155455c3e5071d85
},
b
:
&
fe
{
0xfb996971fe22a1e0
,
0x9aa93eb35b742d6f
,
0x8c476013de99c5c4
,
0x873e27c3a221e571
,
0xca72b5e45a52d888
,
0x06824061418a386b
},
z
:
&
fe
{
0x886c00000023ffdc
,
0x0f70008d3090001d
,
0x77672417ed5828c3
,
0x9dac23e943dc1740
,
0x50553f1b9c131521
,
0x078c712fbe0ab6e8
},
zInv
:
&
fe
{
0x0e8a2e8ba2e83e10
,
0x5b28ba2ca4d745d1
,
0x678cd5473847377a
,
0x4c506dd8a8076116
,
0x9bcb227d79284139
,
0x0e8d3154b0ba099a
},
minusBOverA
:
&
fe
{
0x052583c93555a7fe
,
0x3b40d72430f93c82
,
0x1b75faa0105ec983
,
0x2527e7dc63851767
,
0x99fffd1f34fc181d
,
0x097cab54770ca0d3
},
}
var
swuParamsForG2
=
struct
{
z
*
fe2
zInv
*
fe2
a
*
fe2
b
*
fe2
minusBOverA
*
fe2
}{
a
:
&
fe2
{
fe
{
0
,
0
,
0
,
0
,
0
,
0
},
fe
{
0xe53a000003135242
,
0x01080c0fdef80285
,
0xe7889edbe340f6bd
,
0x0b51375126310601
,
0x02d6985717c744ab
,
0x1220b4e979ea5467
},
},
b
:
&
fe2
{
fe
{
0x22ea00000cf89db2
,
0x6ec832df71380aa4
,
0x6e1b94403db5a66e
,
0x75bf3c53a79473ba
,
0x3dd3a569412c0a34
,
0x125cdb5e74dc4fd1
},
fe
{
0x22ea00000cf89db2
,
0x6ec832df71380aa4
,
0x6e1b94403db5a66e
,
0x75bf3c53a79473ba
,
0x3dd3a569412c0a34
,
0x125cdb5e74dc4fd1
},
},
z
:
&
fe2
{
fe
{
0x87ebfffffff9555c
,
0x656fffe5da8ffffa
,
0x0fd0749345d33ad2
,
0xd951e663066576f4
,
0xde291a3d41e980d3
,
0x0815664c7dfe040d
},
fe
{
0x43f5fffffffcaaae
,
0x32b7fff2ed47fffd
,
0x07e83a49a2e99d69
,
0xeca8f3318332bb7a
,
0xef148d1ea0f4c069
,
0x040ab3263eff0206
},
},
zInv
:
&
fe2
{
fe
{
0xacd0000000011110
,
0x9dd9999dc88ccccd
,
0xb5ca2ac9b76352bf
,
0xf1b574bcf4bc90ce
,
0x42dab41f28a77081
,
0x132fc6ac14cd1e12
},
fe
{
0xe396ffffffff2223
,
0x4fbf332fcd0d9998
,
0x0c4bbd3c1aff4cc4
,
0x6b9c91267926ca58
,
0x29ae4da6aef7f496
,
0x10692e942f195791
},
},
minusBOverA
:
&
fe2
{
fe
{
0x903c555555474fb3
,
0x5f98cc95ce451105
,
0x9f8e582eefe0fade
,
0xc68946b6aebbd062
,
0x467a4ad10ee6de53
,
0x0e7146f483e23a05
},
fe
{
0x29c2aaaaaab85af8
,
0xbf133368e30eeefa
,
0xc7a27a7206cffb45
,
0x9dee04ce44c9425c
,
0x04a15ce53464ce83
,
0x0b8fcaf5b59dac95
},
},
}
minigeth/crypto/bls12381/utils.go
0 → 100644
View file @
cc3de083
// Copyright 2020 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package
bls12381
import
(
"errors"
"math/big"
"github.com/ethereum/go-ethereum/common"
)
func
bigFromHex
(
hex
string
)
*
big
.
Int
{
return
new
(
big
.
Int
)
.
SetBytes
(
common
.
FromHex
(
hex
))
}
// decodeFieldElement expects 64 byte input with zero top 16 bytes,
// returns lower 48 bytes.
func
decodeFieldElement
(
in
[]
byte
)
([]
byte
,
error
)
{
if
len
(
in
)
!=
64
{
return
nil
,
errors
.
New
(
"invalid field element length"
)
}
// check top bytes
for
i
:=
0
;
i
<
16
;
i
++
{
if
in
[
i
]
!=
byte
(
0x00
)
{
return
nil
,
errors
.
New
(
"invalid field element top bytes"
)
}
}
out
:=
make
([]
byte
,
48
)
copy
(
out
[
:
],
in
[
16
:
])
return
out
,
nil
}
minigeth/crypto/bn256/.bn256_slow.go.swp
deleted
100644 → 0
View file @
f193a1b2
File deleted
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment