feat: Waku v2 bridge

Issue #12610
This commit is contained in:
Michal Iskierko
2023-11-12 13:29:38 +01:00
parent 56e7bd01ca
commit 6d31343205
6716 changed files with 1982502 additions and 5891 deletions

2
vendor/github.com/kilic/bls12-381/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,2 @@
*.out
eip2537

202
vendor/github.com/kilic/bls12-381/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

30
vendor/github.com/kilic/bls12-381/README.md generated vendored Normal file
View File

@@ -0,0 +1,30 @@
### High Speed BLS12-381 Implementation in Go
#### Pairing Instance
A Group instance or a pairing engine instance _is not_ suitable for concurrent processing since an instance has its own preallocated memory for temporary variables. A new instance must be created for each thread.
#### Base Field
x86 optimized base field is generated with [kilic/fp](https://github.com/kilic/fp) and for native go is generated with [goff](https://github.com/ConsenSys/goff). Generated codes are slightly edited in both for further requirements.
#### Scalar Field
Standart big.Int module is currently used for scalar field implementation. x86 optimized faster field implementation is planned to be added.
#### Serialization
Point serialization is in line with [zkcrypto library](https://github.com/zkcrypto/pairing/tree/master/src/bls12_381#serialization).
#### Hashing to Curve
Hashing to curve implementations for both G1 and G2 follows `_XMD:SHA-256_SSWU_RO_` and `_XMD:SHA-256_SSWU_NU_` suites as defined in `v7` of [irtf hash to curve draft](https://github.com/cfrg/draft-irtf-cfrg-hash-to-curve/).
#### Benchmarks
on _3.1 GHz i5_
```
BenchmarkPairing 1034837 ns/op
```

66
vendor/github.com/kilic/bls12-381/arithmetic_decl.go generated vendored Normal file
View File

@@ -0,0 +1,66 @@
// +build amd64,!generic
package bls12381
import (
"golang.org/x/sys/cpu"
)
func init() {
if !cpu.X86.HasADX || !cpu.X86.HasBMI2 {
mul = mulNoADX
}
}
var mul func(c, a, b *fe) = mulADX
func square(c, a *fe) {
mul(c, a, a)
}
func neg(c, a *fe) {
if a.isZero() {
c.set(a)
} else {
_neg(c, a)
}
}
//go:noescape
func add(c, a, b *fe)
//go:noescape
func addAssign(a, b *fe)
//go:noescape
func ladd(c, a, b *fe)
//go:noescape
func laddAssign(a, b *fe)
//go:noescape
func double(c, a *fe)
//go:noescape
func doubleAssign(a *fe)
//go:noescape
func ldouble(c, a *fe)
//go:noescape
func sub(c, a, b *fe)
//go:noescape
func subAssign(a, b *fe)
//go:noescape
func lsubAssign(a, b *fe)
//go:noescape
func _neg(c, a *fe)
//go:noescape
func mulNoADX(c, a, b *fe)
//go:noescape
func mulADX(c, a, b *fe)

View File

@@ -0,0 +1,566 @@
// +build !amd64 generic
// Native go field arithmetic code is generated with 'goff'
// https://github.com/ConsenSys/goff
// Many function signature of field operations are renamed.
// Copyright 2020 ConsenSys AG
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// field modulus q =
//
// 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787
// Code generated by goff DO NOT EDIT
// goff version: v0.1.0 - build: 790f1f56eac432441e043abff8819eacddd1d668
// fe are assumed to be in Montgomery form in all methods
// /!\ WARNING /!\
// this code has not been audited and is provided as-is. In particular,
// there is no security guarantees such as constant time implementation
// or side-channel attack resistance
// /!\ WARNING /!\
// Package bls (generated by goff) contains field arithmetics operations
package bls12381
import (
"math/bits"
)
func add(z, x, y *fe) {
var carry uint64
z[0], carry = bits.Add64(x[0], y[0], 0)
z[1], carry = bits.Add64(x[1], y[1], carry)
z[2], carry = bits.Add64(x[2], y[2], carry)
z[3], carry = bits.Add64(x[3], y[3], carry)
z[4], carry = bits.Add64(x[4], y[4], carry)
z[5], _ = bits.Add64(x[5], y[5], carry)
// if z > q --> z -= q
// note: this is NOT constant time
if !(z[5] < 1873798617647539866 || (z[5] == 1873798617647539866 && (z[4] < 5412103778470702295 || (z[4] == 5412103778470702295 && (z[3] < 7239337960414712511 || (z[3] == 7239337960414712511 && (z[2] < 7435674573564081700 || (z[2] == 7435674573564081700 && (z[1] < 2210141511517208575 || (z[1] == 2210141511517208575 && (z[0] < 13402431016077863595))))))))))) {
var b uint64
z[0], b = bits.Sub64(z[0], 13402431016077863595, 0)
z[1], b = bits.Sub64(z[1], 2210141511517208575, b)
z[2], b = bits.Sub64(z[2], 7435674573564081700, b)
z[3], b = bits.Sub64(z[3], 7239337960414712511, b)
z[4], b = bits.Sub64(z[4], 5412103778470702295, b)
z[5], _ = bits.Sub64(z[5], 1873798617647539866, b)
}
}
func addAssign(x, y *fe) {
var carry uint64
x[0], carry = bits.Add64(x[0], y[0], 0)
x[1], carry = bits.Add64(x[1], y[1], carry)
x[2], carry = bits.Add64(x[2], y[2], carry)
x[3], carry = bits.Add64(x[3], y[3], carry)
x[4], carry = bits.Add64(x[4], y[4], carry)
x[5], _ = bits.Add64(x[5], y[5], carry)
// if z > q --> z -= q
// note: this is NOT constant time
if !(x[5] < 1873798617647539866 || (x[5] == 1873798617647539866 && (x[4] < 5412103778470702295 || (x[4] == 5412103778470702295 && (x[3] < 7239337960414712511 || (x[3] == 7239337960414712511 && (x[2] < 7435674573564081700 || (x[2] == 7435674573564081700 && (x[1] < 2210141511517208575 || (x[1] == 2210141511517208575 && (x[0] < 13402431016077863595))))))))))) {
var b uint64
x[0], b = bits.Sub64(x[0], 13402431016077863595, 0)
x[1], b = bits.Sub64(x[1], 2210141511517208575, b)
x[2], b = bits.Sub64(x[2], 7435674573564081700, b)
x[3], b = bits.Sub64(x[3], 7239337960414712511, b)
x[4], b = bits.Sub64(x[4], 5412103778470702295, b)
x[5], _ = bits.Sub64(x[5], 1873798617647539866, b)
}
}
func ladd(z, x, y *fe) {
var carry uint64
z[0], carry = bits.Add64(x[0], y[0], 0)
z[1], carry = bits.Add64(x[1], y[1], carry)
z[2], carry = bits.Add64(x[2], y[2], carry)
z[3], carry = bits.Add64(x[3], y[3], carry)
z[4], carry = bits.Add64(x[4], y[4], carry)
z[5], _ = bits.Add64(x[5], y[5], carry)
}
func laddAssign(x, y *fe) {
var carry uint64
x[0], carry = bits.Add64(x[0], y[0], 0)
x[1], carry = bits.Add64(x[1], y[1], carry)
x[2], carry = bits.Add64(x[2], y[2], carry)
x[3], carry = bits.Add64(x[3], y[3], carry)
x[4], carry = bits.Add64(x[4], y[4], carry)
x[5], _ = bits.Add64(x[5], y[5], carry)
}
func double(z, x *fe) {
var carry uint64
z[0], carry = bits.Add64(x[0], x[0], 0)
z[1], carry = bits.Add64(x[1], x[1], carry)
z[2], carry = bits.Add64(x[2], x[2], carry)
z[3], carry = bits.Add64(x[3], x[3], carry)
z[4], carry = bits.Add64(x[4], x[4], carry)
z[5], _ = bits.Add64(x[5], x[5], carry)
// if z > q --> z -= q
// note: this is NOT constant time
if !(z[5] < 1873798617647539866 || (z[5] == 1873798617647539866 && (z[4] < 5412103778470702295 || (z[4] == 5412103778470702295 && (z[3] < 7239337960414712511 || (z[3] == 7239337960414712511 && (z[2] < 7435674573564081700 || (z[2] == 7435674573564081700 && (z[1] < 2210141511517208575 || (z[1] == 2210141511517208575 && (z[0] < 13402431016077863595))))))))))) {
var b uint64
z[0], b = bits.Sub64(z[0], 13402431016077863595, 0)
z[1], b = bits.Sub64(z[1], 2210141511517208575, b)
z[2], b = bits.Sub64(z[2], 7435674573564081700, b)
z[3], b = bits.Sub64(z[3], 7239337960414712511, b)
z[4], b = bits.Sub64(z[4], 5412103778470702295, b)
z[5], _ = bits.Sub64(z[5], 1873798617647539866, b)
}
}
func doubleAssign(z *fe) {
var carry uint64
z[0], carry = bits.Add64(z[0], z[0], 0)
z[1], carry = bits.Add64(z[1], z[1], carry)
z[2], carry = bits.Add64(z[2], z[2], carry)
z[3], carry = bits.Add64(z[3], z[3], carry)
z[4], carry = bits.Add64(z[4], z[4], carry)
z[5], _ = bits.Add64(z[5], z[5], carry)
// if z > q --> z -= q
// note: this is NOT constant time
if !(z[5] < 1873798617647539866 || (z[5] == 1873798617647539866 && (z[4] < 5412103778470702295 || (z[4] == 5412103778470702295 && (z[3] < 7239337960414712511 || (z[3] == 7239337960414712511 && (z[2] < 7435674573564081700 || (z[2] == 7435674573564081700 && (z[1] < 2210141511517208575 || (z[1] == 2210141511517208575 && (z[0] < 13402431016077863595))))))))))) {
var b uint64
z[0], b = bits.Sub64(z[0], 13402431016077863595, 0)
z[1], b = bits.Sub64(z[1], 2210141511517208575, b)
z[2], b = bits.Sub64(z[2], 7435674573564081700, b)
z[3], b = bits.Sub64(z[3], 7239337960414712511, b)
z[4], b = bits.Sub64(z[4], 5412103778470702295, b)
z[5], _ = bits.Sub64(z[5], 1873798617647539866, b)
}
}
func ldouble(z, x *fe) {
var carry uint64
z[0], carry = bits.Add64(x[0], x[0], 0)
z[1], carry = bits.Add64(x[1], x[1], carry)
z[2], carry = bits.Add64(x[2], x[2], carry)
z[3], carry = bits.Add64(x[3], x[3], carry)
z[4], carry = bits.Add64(x[4], x[4], carry)
z[5], _ = bits.Add64(x[5], x[5], carry)
}
func sub(z, x, y *fe) {
var b uint64
z[0], b = bits.Sub64(x[0], y[0], 0)
z[1], b = bits.Sub64(x[1], y[1], b)
z[2], b = bits.Sub64(x[2], y[2], b)
z[3], b = bits.Sub64(x[3], y[3], b)
z[4], b = bits.Sub64(x[4], y[4], b)
z[5], b = bits.Sub64(x[5], y[5], b)
if b != 0 {
var c uint64
z[0], c = bits.Add64(z[0], 13402431016077863595, 0)
z[1], c = bits.Add64(z[1], 2210141511517208575, c)
z[2], c = bits.Add64(z[2], 7435674573564081700, c)
z[3], c = bits.Add64(z[3], 7239337960414712511, c)
z[4], c = bits.Add64(z[4], 5412103778470702295, c)
z[5], _ = bits.Add64(z[5], 1873798617647539866, c)
}
}
func subAssign(z, x *fe) {
var b uint64
z[0], b = bits.Sub64(z[0], x[0], 0)
z[1], b = bits.Sub64(z[1], x[1], b)
z[2], b = bits.Sub64(z[2], x[2], b)
z[3], b = bits.Sub64(z[3], x[3], b)
z[4], b = bits.Sub64(z[4], x[4], b)
z[5], b = bits.Sub64(z[5], x[5], b)
if b != 0 {
var c uint64
z[0], c = bits.Add64(z[0], 13402431016077863595, 0)
z[1], c = bits.Add64(z[1], 2210141511517208575, c)
z[2], c = bits.Add64(z[2], 7435674573564081700, c)
z[3], c = bits.Add64(z[3], 7239337960414712511, c)
z[4], c = bits.Add64(z[4], 5412103778470702295, c)
z[5], _ = bits.Add64(z[5], 1873798617647539866, c)
}
}
func lsubAssign(z, x *fe) {
var b uint64
z[0], b = bits.Sub64(z[0], x[0], 0)
z[1], b = bits.Sub64(z[1], x[1], b)
z[2], b = bits.Sub64(z[2], x[2], b)
z[3], b = bits.Sub64(z[3], x[3], b)
z[4], b = bits.Sub64(z[4], x[4], b)
z[5], _ = bits.Sub64(z[5], x[5], b)
}
func neg(z *fe, x *fe) {
if x.isZero() {
z.zero()
return
}
var borrow uint64
z[0], borrow = bits.Sub64(13402431016077863595, x[0], 0)
z[1], borrow = bits.Sub64(2210141511517208575, x[1], borrow)
z[2], borrow = bits.Sub64(7435674573564081700, x[2], borrow)
z[3], borrow = bits.Sub64(7239337960414712511, x[3], borrow)
z[4], borrow = bits.Sub64(5412103778470702295, x[4], borrow)
z[5], _ = bits.Sub64(1873798617647539866, x[5], borrow)
}
func mul(z, x, y *fe) {
var t [6]uint64
var c [3]uint64
{
// round 0
v := x[0]
c[1], c[0] = bits.Mul64(v, y[0])
m := c[0] * 9940570264628428797
c[2] = madd0(m, 13402431016077863595, c[0])
c[1], c[0] = madd1(v, y[1], c[1])
c[2], t[0] = madd2(m, 2210141511517208575, c[2], c[0])
c[1], c[0] = madd1(v, y[2], c[1])
c[2], t[1] = madd2(m, 7435674573564081700, c[2], c[0])
c[1], c[0] = madd1(v, y[3], c[1])
c[2], t[2] = madd2(m, 7239337960414712511, c[2], c[0])
c[1], c[0] = madd1(v, y[4], c[1])
c[2], t[3] = madd2(m, 5412103778470702295, c[2], c[0])
c[1], c[0] = madd1(v, y[5], c[1])
t[5], t[4] = madd3(m, 1873798617647539866, c[0], c[2], c[1])
}
{
// round 1
v := x[1]
c[1], c[0] = madd1(v, y[0], t[0])
m := c[0] * 9940570264628428797
c[2] = madd0(m, 13402431016077863595, c[0])
c[1], c[0] = madd2(v, y[1], c[1], t[1])
c[2], t[0] = madd2(m, 2210141511517208575, c[2], c[0])
c[1], c[0] = madd2(v, y[2], c[1], t[2])
c[2], t[1] = madd2(m, 7435674573564081700, c[2], c[0])
c[1], c[0] = madd2(v, y[3], c[1], t[3])
c[2], t[2] = madd2(m, 7239337960414712511, c[2], c[0])
c[1], c[0] = madd2(v, y[4], c[1], t[4])
c[2], t[3] = madd2(m, 5412103778470702295, c[2], c[0])
c[1], c[0] = madd2(v, y[5], c[1], t[5])
t[5], t[4] = madd3(m, 1873798617647539866, c[0], c[2], c[1])
}
{
// round 2
v := x[2]
c[1], c[0] = madd1(v, y[0], t[0])
m := c[0] * 9940570264628428797
c[2] = madd0(m, 13402431016077863595, c[0])
c[1], c[0] = madd2(v, y[1], c[1], t[1])
c[2], t[0] = madd2(m, 2210141511517208575, c[2], c[0])
c[1], c[0] = madd2(v, y[2], c[1], t[2])
c[2], t[1] = madd2(m, 7435674573564081700, c[2], c[0])
c[1], c[0] = madd2(v, y[3], c[1], t[3])
c[2], t[2] = madd2(m, 7239337960414712511, c[2], c[0])
c[1], c[0] = madd2(v, y[4], c[1], t[4])
c[2], t[3] = madd2(m, 5412103778470702295, c[2], c[0])
c[1], c[0] = madd2(v, y[5], c[1], t[5])
t[5], t[4] = madd3(m, 1873798617647539866, c[0], c[2], c[1])
}
{
// round 3
v := x[3]
c[1], c[0] = madd1(v, y[0], t[0])
m := c[0] * 9940570264628428797
c[2] = madd0(m, 13402431016077863595, c[0])
c[1], c[0] = madd2(v, y[1], c[1], t[1])
c[2], t[0] = madd2(m, 2210141511517208575, c[2], c[0])
c[1], c[0] = madd2(v, y[2], c[1], t[2])
c[2], t[1] = madd2(m, 7435674573564081700, c[2], c[0])
c[1], c[0] = madd2(v, y[3], c[1], t[3])
c[2], t[2] = madd2(m, 7239337960414712511, c[2], c[0])
c[1], c[0] = madd2(v, y[4], c[1], t[4])
c[2], t[3] = madd2(m, 5412103778470702295, c[2], c[0])
c[1], c[0] = madd2(v, y[5], c[1], t[5])
t[5], t[4] = madd3(m, 1873798617647539866, c[0], c[2], c[1])
}
{
// round 4
v := x[4]
c[1], c[0] = madd1(v, y[0], t[0])
m := c[0] * 9940570264628428797
c[2] = madd0(m, 13402431016077863595, c[0])
c[1], c[0] = madd2(v, y[1], c[1], t[1])
c[2], t[0] = madd2(m, 2210141511517208575, c[2], c[0])
c[1], c[0] = madd2(v, y[2], c[1], t[2])
c[2], t[1] = madd2(m, 7435674573564081700, c[2], c[0])
c[1], c[0] = madd2(v, y[3], c[1], t[3])
c[2], t[2] = madd2(m, 7239337960414712511, c[2], c[0])
c[1], c[0] = madd2(v, y[4], c[1], t[4])
c[2], t[3] = madd2(m, 5412103778470702295, c[2], c[0])
c[1], c[0] = madd2(v, y[5], c[1], t[5])
t[5], t[4] = madd3(m, 1873798617647539866, c[0], c[2], c[1])
}
{
// round 5
v := x[5]
c[1], c[0] = madd1(v, y[0], t[0])
m := c[0] * 9940570264628428797
c[2] = madd0(m, 13402431016077863595, c[0])
c[1], c[0] = madd2(v, y[1], c[1], t[1])
c[2], z[0] = madd2(m, 2210141511517208575, c[2], c[0])
c[1], c[0] = madd2(v, y[2], c[1], t[2])
c[2], z[1] = madd2(m, 7435674573564081700, c[2], c[0])
c[1], c[0] = madd2(v, y[3], c[1], t[3])
c[2], z[2] = madd2(m, 7239337960414712511, c[2], c[0])
c[1], c[0] = madd2(v, y[4], c[1], t[4])
c[2], z[3] = madd2(m, 5412103778470702295, c[2], c[0])
c[1], c[0] = madd2(v, y[5], c[1], t[5])
z[5], z[4] = madd3(m, 1873798617647539866, c[0], c[2], c[1])
}
// if z > q --> z -= q
// note: this is NOT constant time
if !(z[5] < 1873798617647539866 || (z[5] == 1873798617647539866 && (z[4] < 5412103778470702295 || (z[4] == 5412103778470702295 && (z[3] < 7239337960414712511 || (z[3] == 7239337960414712511 && (z[2] < 7435674573564081700 || (z[2] == 7435674573564081700 && (z[1] < 2210141511517208575 || (z[1] == 2210141511517208575 && (z[0] < 13402431016077863595))))))))))) {
var b uint64
z[0], b = bits.Sub64(z[0], 13402431016077863595, 0)
z[1], b = bits.Sub64(z[1], 2210141511517208575, b)
z[2], b = bits.Sub64(z[2], 7435674573564081700, b)
z[3], b = bits.Sub64(z[3], 7239337960414712511, b)
z[4], b = bits.Sub64(z[4], 5412103778470702295, b)
z[5], _ = bits.Sub64(z[5], 1873798617647539866, b)
}
}
func square(z, x *fe) {
var p [6]uint64
var u, v uint64
{
// round 0
u, p[0] = bits.Mul64(x[0], x[0])
m := p[0] * 9940570264628428797
C := madd0(m, 13402431016077863595, p[0])
var t uint64
t, u, v = madd1sb(x[0], x[1], u)
C, p[0] = madd2(m, 2210141511517208575, v, C)
t, u, v = madd1s(x[0], x[2], t, u)
C, p[1] = madd2(m, 7435674573564081700, v, C)
t, u, v = madd1s(x[0], x[3], t, u)
C, p[2] = madd2(m, 7239337960414712511, v, C)
t, u, v = madd1s(x[0], x[4], t, u)
C, p[3] = madd2(m, 5412103778470702295, v, C)
_, u, v = madd1s(x[0], x[5], t, u)
p[5], p[4] = madd3(m, 1873798617647539866, v, C, u)
}
{
// round 1
m := p[0] * 9940570264628428797
C := madd0(m, 13402431016077863595, p[0])
u, v = madd1(x[1], x[1], p[1])
C, p[0] = madd2(m, 2210141511517208575, v, C)
var t uint64
t, u, v = madd2sb(x[1], x[2], p[2], u)
C, p[1] = madd2(m, 7435674573564081700, v, C)
t, u, v = madd2s(x[1], x[3], p[3], t, u)
C, p[2] = madd2(m, 7239337960414712511, v, C)
t, u, v = madd2s(x[1], x[4], p[4], t, u)
C, p[3] = madd2(m, 5412103778470702295, v, C)
_, u, v = madd2s(x[1], x[5], p[5], t, u)
p[5], p[4] = madd3(m, 1873798617647539866, v, C, u)
}
{
// round 2
m := p[0] * 9940570264628428797
C := madd0(m, 13402431016077863595, p[0])
C, p[0] = madd2(m, 2210141511517208575, p[1], C)
u, v = madd1(x[2], x[2], p[2])
C, p[1] = madd2(m, 7435674573564081700, v, C)
var t uint64
t, u, v = madd2sb(x[2], x[3], p[3], u)
C, p[2] = madd2(m, 7239337960414712511, v, C)
t, u, v = madd2s(x[2], x[4], p[4], t, u)
C, p[3] = madd2(m, 5412103778470702295, v, C)
_, u, v = madd2s(x[2], x[5], p[5], t, u)
p[5], p[4] = madd3(m, 1873798617647539866, v, C, u)
}
{
// round 3
m := p[0] * 9940570264628428797
C := madd0(m, 13402431016077863595, p[0])
C, p[0] = madd2(m, 2210141511517208575, p[1], C)
C, p[1] = madd2(m, 7435674573564081700, p[2], C)
u, v = madd1(x[3], x[3], p[3])
C, p[2] = madd2(m, 7239337960414712511, v, C)
var t uint64
t, u, v = madd2sb(x[3], x[4], p[4], u)
C, p[3] = madd2(m, 5412103778470702295, v, C)
_, u, v = madd2s(x[3], x[5], p[5], t, u)
p[5], p[4] = madd3(m, 1873798617647539866, v, C, u)
}
{
// round 4
m := p[0] * 9940570264628428797
C := madd0(m, 13402431016077863595, p[0])
C, p[0] = madd2(m, 2210141511517208575, p[1], C)
C, p[1] = madd2(m, 7435674573564081700, p[2], C)
C, p[2] = madd2(m, 7239337960414712511, p[3], C)
u, v = madd1(x[4], x[4], p[4])
C, p[3] = madd2(m, 5412103778470702295, v, C)
_, u, v = madd2sb(x[4], x[5], p[5], u)
p[5], p[4] = madd3(m, 1873798617647539866, v, C, u)
}
{
// round 5
m := p[0] * 9940570264628428797
C := madd0(m, 13402431016077863595, p[0])
C, z[0] = madd2(m, 2210141511517208575, p[1], C)
C, z[1] = madd2(m, 7435674573564081700, p[2], C)
C, z[2] = madd2(m, 7239337960414712511, p[3], C)
C, z[3] = madd2(m, 5412103778470702295, p[4], C)
u, v = madd1(x[5], x[5], p[5])
z[5], z[4] = madd3(m, 1873798617647539866, v, C, u)
}
// if z > q --> z -= q
// note: this is NOT constant time
if !(z[5] < 1873798617647539866 || (z[5] == 1873798617647539866 && (z[4] < 5412103778470702295 || (z[4] == 5412103778470702295 && (z[3] < 7239337960414712511 || (z[3] == 7239337960414712511 && (z[2] < 7435674573564081700 || (z[2] == 7435674573564081700 && (z[1] < 2210141511517208575 || (z[1] == 2210141511517208575 && (z[0] < 13402431016077863595))))))))))) {
var b uint64
z[0], b = bits.Sub64(z[0], 13402431016077863595, 0)
z[1], b = bits.Sub64(z[1], 2210141511517208575, b)
z[2], b = bits.Sub64(z[2], 7435674573564081700, b)
z[3], b = bits.Sub64(z[3], 7239337960414712511, b)
z[4], b = bits.Sub64(z[4], 5412103778470702295, b)
z[5], _ = bits.Sub64(z[5], 1873798617647539866, b)
}
}
// arith.go
// Copyright 2020 ConsenSys AG
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Code generated by goff DO NOT EDIT
func madd(a, b, t, u, v uint64) (uint64, uint64, uint64) {
var carry uint64
hi, lo := bits.Mul64(a, b)
v, carry = bits.Add64(lo, v, 0)
u, carry = bits.Add64(hi, u, carry)
t, _ = bits.Add64(t, 0, carry)
return t, u, v
}
// madd0 hi = a*b + c (discards lo bits)
func madd0(a, b, c uint64) (hi uint64) {
var carry, lo uint64
hi, lo = bits.Mul64(a, b)
_, carry = bits.Add64(lo, c, 0)
hi, _ = bits.Add64(hi, 0, carry)
return
}
// madd1 hi, lo = a*b + c
func madd1(a, b, c uint64) (hi uint64, lo uint64) {
var carry uint64
hi, lo = bits.Mul64(a, b)
lo, carry = bits.Add64(lo, c, 0)
hi, _ = bits.Add64(hi, 0, carry)
return
}
// madd2 hi, lo = a*b + c + d
func madd2(a, b, c, d uint64) (hi uint64, lo uint64) {
var carry uint64
hi, lo = bits.Mul64(a, b)
c, carry = bits.Add64(c, d, 0)
hi, _ = bits.Add64(hi, 0, carry)
lo, carry = bits.Add64(lo, c, 0)
hi, _ = bits.Add64(hi, 0, carry)
return
}
// madd2s superhi, hi, lo = 2*a*b + c + d + e
func madd2s(a, b, c, d, e uint64) (superhi, hi, lo uint64) {
var carry, sum uint64
hi, lo = bits.Mul64(a, b)
lo, carry = bits.Add64(lo, lo, 0)
hi, superhi = bits.Add64(hi, hi, carry)
sum, carry = bits.Add64(c, e, 0)
hi, _ = bits.Add64(hi, 0, carry)
lo, carry = bits.Add64(lo, sum, 0)
hi, _ = bits.Add64(hi, 0, carry)
hi, _ = bits.Add64(hi, 0, d)
return
}
func madd1s(a, b, d, e uint64) (superhi, hi, lo uint64) {
var carry uint64
hi, lo = bits.Mul64(a, b)
lo, carry = bits.Add64(lo, lo, 0)
hi, superhi = bits.Add64(hi, hi, carry)
lo, carry = bits.Add64(lo, e, 0)
hi, _ = bits.Add64(hi, 0, carry)
hi, _ = bits.Add64(hi, 0, d)
return
}
func madd2sb(a, b, c, e uint64) (superhi, hi, lo uint64) {
var carry, sum uint64
hi, lo = bits.Mul64(a, b)
lo, carry = bits.Add64(lo, lo, 0)
hi, superhi = bits.Add64(hi, hi, carry)
sum, carry = bits.Add64(c, e, 0)
hi, _ = bits.Add64(hi, 0, carry)
lo, carry = bits.Add64(lo, sum, 0)
hi, _ = bits.Add64(hi, 0, carry)
return
}
func madd1sb(a, b, e uint64) (superhi, hi, lo uint64) {
var carry uint64
hi, lo = bits.Mul64(a, b)
lo, carry = bits.Add64(lo, lo, 0)
hi, superhi = bits.Add64(hi, hi, carry)
lo, carry = bits.Add64(lo, e, 0)
hi, _ = bits.Add64(hi, 0, carry)
return
}
func madd3(a, b, c, d, e uint64) (hi uint64, lo uint64) {
var carry uint64
hi, lo = bits.Mul64(a, b)
c, carry = bits.Add64(c, d, 0)
hi, _ = bits.Add64(hi, 0, carry)
lo, carry = bits.Add64(lo, c, 0)
hi, _ = bits.Add64(hi, e, carry)
return
}

2151
vendor/github.com/kilic/bls12-381/arithmetic_x86.s generated vendored Normal file

File diff suppressed because it is too large Load Diff

234
vendor/github.com/kilic/bls12-381/bls12_381.go generated vendored Normal file
View File

@@ -0,0 +1,234 @@
package bls12381
/*
Field Constants
*/
// Base field modulus
// p = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab
// Size of six words
// r = 2 ^ 384
// modulus = p
var modulus = fe{0xb9feffffffffaaab, 0x1eabfffeb153ffff, 0x6730d2a0f6b0f624, 0x64774b84f38512bf, 0x4b1ba7b6434bacd7, 0x1a0111ea397fe69a}
// -p^(-1) mod 2^64
var inp uint64 = 0x89f3fffcfffcfffd
// r mod p
var r1 = &fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493}
// r^2 mod p
var r2 = &fe{
0xf4df1f341c341746, 0x0a76e6a609d104f1, 0x8de5476c4c95b6d5, 0x67eb88a9939d83c0, 0x9a793e85b519952d, 0x11988fe592cae3aa,
}
// -1 + 0 * u
var negativeOne2 = &fe2{
fe{0x43f5fffffffcaaae, 0x32b7fff2ed47fffd, 0x07e83a49a2e99d69, 0xeca8f3318332bb7a, 0xef148d1ea0f4c069, 0x040ab3263eff0206},
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
}
// 2 ^ (-1)
var twoInv = &fe{0x1804000000015554, 0x855000053ab00001, 0x633cb57c253c276f, 0x6e22d1ec31ebb502, 0xd3916126f2d14ca2, 0x17fbb8571a006596}
// (p - 3) / 4
var pMinus3Over4 = bigFromHex("0x680447a8e5ff9a692c6e9ed90d2eb35d91dd2e13ce144afd9cc34a83dac3d8907aaffffac54ffffee7fbfffffffeaaa")
// (p + 1) / 4
var pPlus1Over4 = bigFromHex("0x680447a8e5ff9a692c6e9ed90d2eb35d91dd2e13ce144afd9cc34a83dac3d8907aaffffac54ffffee7fbfffffffeaab")
// (p - 1) / 2
var pMinus1Over2 = bigFromHex("0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b587b120f55ffff58a9ffffdcff7fffffffd555")
// -1
var nonResidue1 = &fe{0x43f5fffffffcaaae, 0x32b7fff2ed47fffd, 0x07e83a49a2e99d69, 0xeca8f3318332bb7a, 0xef148d1ea0f4c069, 0x040ab3263eff0206}
// (1 + 1 * u)
var nonResidue2 = &fe2{
fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493},
fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493},
}
/*
Curve Constants
*/
// b coefficient for G1
var b = &fe{0xaa270000000cfff3, 0x53cc0032fc34000a, 0x478fe97a6b0a807f, 0xb1d37ebee6ba24d7, 0x8ec9733bbf78ab2f, 0x09d645513d83de7e}
// b coefficient for G2
var b2 = &fe2{
fe{0xaa270000000cfff3, 0x53cc0032fc34000a, 0x478fe97a6b0a807f, 0xb1d37ebee6ba24d7, 0x8ec9733bbf78ab2f, 0x09d645513d83de7e},
fe{0xaa270000000cfff3, 0x53cc0032fc34000a, 0x478fe97a6b0a807f, 0xb1d37ebee6ba24d7, 0x8ec9733bbf78ab2f, 0x09d645513d83de7e},
}
// Group order
var q = bigFromHex("0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001")
// G1 cofactor
var cofactorG1 = bigFromHex("0x396c8c005555e1568c00aaab0000aaab")
// G2 cofactor
var cofactorG2 = bigFromHex("5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5")
// Efficient G1 cofactor
var cofactorEFFG1 = bigFromHex("0xd201000000010001")
// Efficient G2 cofactor
var cofactorEFFG2 = bigFromHex("0x0bc69f08f2ee75b3584c6a0ea91b352888e2a8e9145ad7689986ff031508ffe1329c2f178731db956d82bf015d1212b02ec0ec69d7477c1ae954cbc06689f6a359894c0adebbf6b4e8020005aaa95551")
// G1 generator
var g1One = PointG1{
fe{0x5cb38790fd530c16, 0x7817fc679976fff5, 0x154f95c7143ba1c1, 0xf0ae6acdf3d0e747, 0xedce6ecc21dbf440, 0x120177419e0bfb75},
fe{0xbaac93d50ce72271, 0x8c22631a7918fd8e, 0xdd595f13570725ce, 0x51ac582950405194, 0x0e1c8c3fad0059c0, 0x0bbc3efc5008a26a},
fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493},
}
var G1One = g1One
// Negated G1 generator
var g1NegativeOne = PointG1{
fe{0x5cb38790fd530c16, 0x7817fc679976fff5, 0x154f95c7143ba1c1, 0xf0ae6acdf3d0e747, 0xedce6ecc21dbf440, 0x120177419e0bfb75},
fe{0xff526c2af318883a, 0x92899ce4383b0270, 0x89d7738d9fa9d055, 0x12caf35ba344c12a, 0x3cff1b76964b5317, 0x0e44d2ede9774430},
fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493},
}
// G2 generator
var g2One = PointG2{
fe2{
fe{0xf5f28fa202940a10, 0xb3f5fb2687b4961a, 0xa1a893b53e2ae580, 0x9894999d1a3caee9, 0x6f67b7631863366b, 0x058191924350bcd7},
fe{0xa5a9c0759e23f606, 0xaaa0c59dbccd60c3, 0x3bb17e18e2867806, 0x1b1ab6cc8541b367, 0xc2b6ed0ef2158547, 0x11922a097360edf3},
},
fe2{
fe{0x4c730af860494c4a, 0x597cfa1f5e369c5a, 0xe7e6856caa0a635a, 0xbbefb5e96e0d495f, 0x07d3a975f0ef25a2, 0x083fd8e7e80dae5},
fe{0xadc0fc92df64b05d, 0x18aa270a2b1461dc, 0x86adac6a3be4eba0, 0x79495c4ec93da33a, 0xe7175850a43ccaed, 0xb2bc2a163de1bf2},
},
fe2{
fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493},
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
},
}
var G2One = g2One
/*
Frobenious Coeffs
*/
var frobeniusCoeffs2 = [2]fe{
fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493},
fe{0x43f5fffffffcaaae, 0x32b7fff2ed47fffd, 0x07e83a49a2e99d69, 0xeca8f3318332bb7a, 0xef148d1ea0f4c069, 0x040ab3263eff0206},
}
var frobeniusCoeffs61 = [6]fe2{
fe2{
fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493},
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
},
fe2{
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
fe{0xcd03c9e48671f071, 0x5dab22461fcda5d2, 0x587042afd3851b95, 0x8eb60ebe01bacb9e, 0x03f97d6e83d050d2, 0x18f0206554638741},
},
fe2{
fe{0x30f1361b798a64e8, 0xf3b8ddab7ece5a2a, 0x16a8ca3ac61577f7, 0xc26a2ff874fd029b, 0x3636b76660701c6e, 0x051ba4ab241b6160},
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
},
fe2{
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493},
},
fe2{
fe{0xcd03c9e48671f071, 0x5dab22461fcda5d2, 0x587042afd3851b95, 0x8eb60ebe01bacb9e, 0x03f97d6e83d050d2, 0x18f0206554638741},
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
},
fe2{
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
fe{0x30f1361b798a64e8, 0xf3b8ddab7ece5a2a, 0x16a8ca3ac61577f7, 0xc26a2ff874fd029b, 0x3636b76660701c6e, 0x051ba4ab241b6160},
},
}
var frobeniusCoeffs62 = [6]fe2{
fe2{
fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493},
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
},
fe2{
fe{0x890dc9e4867545c3, 0x2af322533285a5d5, 0x50880866309b7e2c, 0xa20d1b8c7e881024, 0x14e4f04fe2db9068, 0x14e56d3f1564853a},
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
},
fe2{
fe{0xcd03c9e48671f071, 0x5dab22461fcda5d2, 0x587042afd3851b95, 0x8eb60ebe01bacb9e, 0x03f97d6e83d050d2, 0x18f0206554638741},
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
},
fe2{
fe{0x43f5fffffffcaaae, 0x32b7fff2ed47fffd, 0x07e83a49a2e99d69, 0xeca8f3318332bb7a, 0xef148d1ea0f4c069, 0x040ab3263eff0206},
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
},
fe2{
fe{0x30f1361b798a64e8, 0xf3b8ddab7ece5a2a, 0x16a8ca3ac61577f7, 0xc26a2ff874fd029b, 0x3636b76660701c6e, 0x051ba4ab241b6160},
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
},
fe2{
fe{0xecfb361b798dba3a, 0xc100ddb891865a2c, 0x0ec08ff1232bda8e, 0xd5c13cc6f1ca4721, 0x47222a47bf7b5c04, 0x0110f184e51c5f59},
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
},
}
var frobeniusCoeffs12 = [12]fe2{
fe2{
fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493},
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
},
fe2{
fe{0x07089552b319d465, 0xc6695f92b50a8313, 0x97e83cccd117228f, 0xa35baecab2dc29ee, 0x1ce393ea5daace4d, 0x08f2220fb0fb66eb},
fe{0xb2f66aad4ce5d646, 0x5842a06bfc497cec, 0xcf4895d42599d394, 0xc11b9cba40a8e8d0, 0x2e3813cbe5a0de89, 0x110eefda88847faf},
},
fe2{
fe{0xecfb361b798dba3a, 0xc100ddb891865a2c, 0x0ec08ff1232bda8e, 0xd5c13cc6f1ca4721, 0x47222a47bf7b5c04, 0x0110f184e51c5f59},
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
},
fe2{
fe{0x3e2f585da55c9ad1, 0x4294213d86c18183, 0x382844c88b623732, 0x92ad2afd19103e18, 0x1d794e4fac7cf0b9, 0x0bd592fc7d825ec8},
fe{0x7bcfa7a25aa30fda, 0xdc17dec12a927e7c, 0x2f088dd86b4ebef1, 0xd1ca2087da74d4a7, 0x2da2596696cebc1d, 0x0e2b7eedbbfd87d2},
},
fe2{
fe{0x30f1361b798a64e8, 0xf3b8ddab7ece5a2a, 0x16a8ca3ac61577f7, 0xc26a2ff874fd029b, 0x3636b76660701c6e, 0x051ba4ab241b6160},
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
},
fe2{
fe{0x3726c30af242c66c, 0x7c2ac1aad1b6fe70, 0xa04007fbba4b14a2, 0xef517c3266341429, 0x0095ba654ed2226b, 0x02e370eccc86f7dd},
fe{0x82d83cf50dbce43f, 0xa2813e53df9d018f, 0xc6f0caa53c65e181, 0x7525cf528d50fe95, 0x4a85ed50f4798a6b, 0x171da0fd6cf8eebd},
},
fe2{
fe{0x43f5fffffffcaaae, 0x32b7fff2ed47fffd, 0x07e83a49a2e99d69, 0xeca8f3318332bb7a, 0xef148d1ea0f4c069, 0x040ab3263eff0206},
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
},
fe2{
fe{0xb2f66aad4ce5d646, 0x5842a06bfc497cec, 0xcf4895d42599d394, 0xc11b9cba40a8e8d0, 0x2e3813cbe5a0de89, 0x110eefda88847faf},
fe{0x07089552b319d465, 0xc6695f92b50a8313, 0x97e83cccd117228f, 0xa35baecab2dc29ee, 0x1ce393ea5daace4d, 0x08f2220fb0fb66eb},
},
fe2{
fe{0xcd03c9e48671f071, 0x5dab22461fcda5d2, 0x587042afd3851b95, 0x8eb60ebe01bacb9e, 0x03f97d6e83d050d2, 0x18f0206554638741},
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
},
fe2{
fe{0x7bcfa7a25aa30fda, 0xdc17dec12a927e7c, 0x2f088dd86b4ebef1, 0xd1ca2087da74d4a7, 0x2da2596696cebc1d, 0x0e2b7eedbbfd87d2},
fe{0x3e2f585da55c9ad1, 0x4294213d86c18183, 0x382844c88b623732, 0x92ad2afd19103e18, 0x1d794e4fac7cf0b9, 0x0bd592fc7d825ec8},
},
fe2{
fe{0x890dc9e4867545c3, 0x2af322533285a5d5, 0x50880866309b7e2c, 0xa20d1b8c7e881024, 0x14e4f04fe2db9068, 0x14e56d3f1564853a},
fe{0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000},
},
fe2{
fe{0x82d83cf50dbce43f, 0xa2813e53df9d018f, 0xc6f0caa53c65e181, 0x7525cf528d50fe95, 0x4a85ed50f4798a6b, 0x171da0fd6cf8eebd},
fe{0x3726c30af242c66c, 0x7c2ac1aad1b6fe70, 0xa04007fbba4b14a2, 0xef517c3266341429, 0x0095ba654ed2226b, 0x02e370eccc86f7dd},
},
}
/*
x
*/
var x = bigFromHex("0xd201000000010000")

338
vendor/github.com/kilic/bls12-381/field_element.go generated vendored Normal file
View File

@@ -0,0 +1,338 @@
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 extention 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 extention 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 extention 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) == -1
}
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 > -1; 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) signBE() bool {
negZ, z := new(fe), new(fe)
fromMont(z, e)
neg(negZ, z)
return negZ.cmp(z) > -1
}
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) signBE() bool {
if !e[1].isZero() {
return e[1].signBE()
}
return e[0].signBE()
}
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])
}

183
vendor/github.com/kilic/bls12-381/fp.go generated vendored Normal file
View File

@@ -0,0 +1,183 @@
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 from64Bytes(in []byte) (*fe, error) {
if len(in) != 64 {
return nil, errors.New("input string should be equal 64 bytes")
}
a0 := make([]byte, 48)
copy(a0[16:48], in[:32])
a1 := make([]byte, 48)
copy(a1[16:48], in[32:])
e0, err := fromBytes(a0)
if err != nil {
return nil, err
}
e1, err := fromBytes(a1)
if err != nil {
return nil, err
}
// F = 2 ^ 256 * R
F := fe{
0x75b3cd7c5ce820f,
0x3ec6ba621c3edb0b,
0x168a13d82bff6bce,
0x87663c4bf8c449d2,
0x15f34c83ddc8d830,
0xf9628b49caa2e85,
}
mul(e0, e0, &F)
add(e1, e1, e0)
return e1, 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)
return
}
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()
}

263
vendor/github.com/kilic/bls12-381/fp12.go generated vendored Normal file
View File

@@ -0,0 +1,263 @@
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])
}
}

245
vendor/github.com/kilic/bls12-381/fp2.go generated vendored Normal file
View File

@@ -0,0 +1,245 @@
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("input string should be larger than 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) fromMont(c, a *fe2) {
fromMont(&c[0], &a[0])
fromMont(&c[1], &a[1])
}
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) conjugate(c, a *fe2) {
c[0].set(&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) frobeniousMap(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) frobeniousMapAssign(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 {
c0, c1 := new(fe), new(fe)
square(c0, &a[0])
square(c1, &a[1])
add(c1, c1, c0)
return isQuadraticNonResidue(c1)
}

342
vendor/github.com/kilic/bls12-381/fp6.go generated vendored Normal file
View File

@@ -0,0 +1,342 @@
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) conjugate(c, a *fe6) {
fp2 := e.fp2
c[0].set(&a[0])
fp2.neg(&c[1], &a[1])
c[0].set(&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.frobeniousMap(&c[0], &a[0], power)
fp2.frobeniousMap(&c[1], &a[1], power)
fp2.frobeniousMap(&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.frobeniousMapAssign(&a[0], power)
fp2.frobeniousMapAssign(&a[1], power)
fp2.frobeniousMapAssign(&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])
}
}

551
vendor/github.com/kilic/bls12-381/g1.go generated vendored Normal file
View File

@@ -0,0 +1,551 @@
package bls12381
import (
"errors"
"math"
"math/big"
)
// PointG1 is type for point in G1.
// PointG1 is both used for Affine and Jacobian point representation.
// If z is equal to one the point is accounted as in affine form.
type PointG1 [3]fe
func (p *PointG1) Set(p2 *PointG1) *PointG1 {
p[0].set(&p2[0])
p[1].set(&p2[1])
p[2].set(&p2[2])
return p
}
func (p *PointG1) Zero() *PointG1 {
p[0].zero()
p[1].one()
p[2].zero()
return p
}
type tempG1 struct {
t [9]*fe
}
// G1 is struct for G1 group.
type G1 struct {
tempG1
}
// NewG1 constructs a new G1 instance.
func NewG1() *G1 {
t := newTempG1()
return &G1{t}
}
func newTempG1() tempG1 {
t := [9]*fe{}
for i := 0; i < 9; i++ {
t[i] = &fe{}
}
return tempG1{t}
}
// Q returns group order in big.Int.
func (g *G1) Q() *big.Int {
return new(big.Int).Set(q)
}
// FromUncompressed expects byte slice larger than 96 bytes and given bytes returns a new point in G1.
// Serialization rules are in line with zcash library. See below for details.
// https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization
// https://docs.rs/bls12_381/0.1.1/bls12_381/notes/serialization/index.html
func (g *G1) FromUncompressed(uncompressed []byte) (*PointG1, error) {
if len(uncompressed) < 96 {
return nil, errors.New("input string should be equal or larger than 96")
}
var in [96]byte
copy(in[:], uncompressed[:96])
if in[0]&(1<<7) != 0 {
return nil, errors.New("input string should be equal or larger than 96")
}
if in[0]&(1<<5) != 0 {
return nil, errors.New("input string should be equal or larger than 96")
}
if in[0]&(1<<6) != 0 {
for i, v := range in {
if (i == 0 && v != 0x40) || (i != 0 && v != 0x00) {
return nil, errors.New("input string should be equal or larger than 96")
}
}
return g.Zero(), nil
}
in[0] &= 0x1f
x, err := fromBytes(in[:48])
if err != nil {
return nil, err
}
y, err := fromBytes(in[48:])
if err != nil {
return nil, err
}
z := new(fe).one()
p := &PointG1{*x, *y, *z}
if !g.IsOnCurve(p) {
return nil, errors.New("input string should be equal or larger than 96")
}
if !g.InCorrectSubgroup(p) {
return nil, errors.New("input string should be equal or larger than 96")
}
return p, nil
}
// ToUncompressed given a G1 point returns bytes in uncompressed (x, y) form of the point.
// Serialization rules are in line with zcash library. See below for details.
// https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization
// https://docs.rs/bls12_381/0.1.1/bls12_381/notes/serialization/index.html
func (g *G1) ToUncompressed(p *PointG1) []byte {
out := make([]byte, 96)
if g.IsZero(p) {
out[0] |= 1 << 6
return out
}
g.Affine(p)
copy(out[:48], toBytes(&p[0]))
copy(out[48:], toBytes(&p[1]))
return out
}
// FromCompressed expects byte slice larger than 96 bytes and given bytes returns a new point in G1.
// Serialization rules are in line with zcash library. See below for details.
// https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization
// https://docs.rs/bls12_381/0.1.1/bls12_381/notes/serialization/index.html
func (g *G1) FromCompressed(compressed []byte) (*PointG1, error) {
if len(compressed) < 48 {
return nil, errors.New("input string should be equal or larger than 48")
}
var in [48]byte
copy(in[:], compressed[:])
if in[0]&(1<<7) == 0 {
return nil, errors.New("compression flag should be set")
}
if in[0]&(1<<6) != 0 {
// in[0] == (1 << 6) + (1 << 7)
for i, v := range in {
if (i == 0 && v != 0xc0) || (i != 0 && v != 0x00) {
return nil, errors.New("input string should be zero when infinity flag is set")
}
}
return g.Zero(), nil
}
a := in[0]&(1<<5) != 0
in[0] &= 0x1f
x, err := fromBytes(in[:])
if err != nil {
return nil, err
}
// solve curve equation
y := &fe{}
square(y, x)
mul(y, y, x)
add(y, y, b)
if ok := sqrt(y, y); !ok {
return nil, errors.New("point is not on curve")
}
if y.signBE() == a {
neg(y, y)
}
z := new(fe).one()
p := &PointG1{*x, *y, *z}
if !g.InCorrectSubgroup(p) {
return nil, errors.New("point is not on correct subgroup")
}
return p, nil
}
// ToCompressed given a G1 point returns bytes in compressed form of the point.
// Serialization rules are in line with zcash library. See below for details.
// https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization
// https://docs.rs/bls12_381/0.1.1/bls12_381/notes/serialization/index.html
func (g *G1) ToCompressed(p *PointG1) []byte {
out := make([]byte, 48)
g.Affine(p)
if g.IsZero(p) {
out[0] |= 1 << 6
} else {
copy(out[:], toBytes(&p[0]))
if !p[1].signBE() {
out[0] |= 1 << 5
}
}
out[0] |= 1 << 7
return out
}
func (g *G1) fromBytesUnchecked(in []byte) (*PointG1, error) {
p0, err := fromBytes(in[:48])
if err != nil {
return nil, err
}
p1, err := fromBytes(in[48:])
if err != nil {
return nil, err
}
p2 := new(fe).one()
return &PointG1{*p0, *p1, *p2}, nil
}
// FromBytes constructs a new point given uncompressed byte input.
// FromBytes does not take zcash flags into account.
// Byte input expected to be larger than 96 bytes.
// First 96 bytes should be concatenation of x and y values.
// Point (0, 0) is considered as infinity.
func (g *G1) FromBytes(in []byte) (*PointG1, error) {
if len(in) < 96 {
return nil, errors.New("input string should be equal or larger than 96")
}
p0, err := fromBytes(in[:48])
if err != nil {
return nil, err
}
p1, err := fromBytes(in[48:])
if err != nil {
return nil, err
}
// check if given input points to infinity
if p0.isZero() && p1.isZero() {
return g.Zero(), nil
}
p2 := new(fe).one()
p := &PointG1{*p0, *p1, *p2}
if !g.IsOnCurve(p) {
return nil, errors.New("point is not on curve")
}
return p, nil
}
// ToBytes serializes a point into bytes in uncompressed form.
// ToBytes does not take zcash flags into account.
// ToBytes returns (0, 0) if point is infinity.
func (g *G1) ToBytes(p *PointG1) []byte {
out := make([]byte, 96)
if g.IsZero(p) {
return out
}
g.Affine(p)
copy(out[:48], toBytes(&p[0]))
copy(out[48:], toBytes(&p[1]))
return out
}
// New creates a new G1 Point which is equal to zero in other words point at infinity.
func (g *G1) New() *PointG1 {
return g.Zero()
}
// Zero returns a new G1 Point which is equal to point at infinity.
func (g *G1) Zero() *PointG1 {
return new(PointG1).Zero()
}
// One returns a new G1 Point which is equal to generator point.
func (g *G1) One() *PointG1 {
p := &PointG1{}
return p.Set(&g1One)
}
// IsZero returns true if given point is equal to zero.
func (g *G1) IsZero(p *PointG1) bool {
return p[2].isZero()
}
// Equal checks if given two G1 point is equal in their affine form.
func (g *G1) Equal(p1, p2 *PointG1) bool {
if g.IsZero(p1) {
return g.IsZero(p2)
}
if g.IsZero(p2) {
return g.IsZero(p1)
}
t := g.t
square(t[0], &p1[2])
square(t[1], &p2[2])
mul(t[2], t[0], &p2[0])
mul(t[3], t[1], &p1[0])
mul(t[0], t[0], &p1[2])
mul(t[1], t[1], &p2[2])
mul(t[1], t[1], &p1[1])
mul(t[0], t[0], &p2[1])
return t[0].equal(t[1]) && t[2].equal(t[3])
}
// InCorrectSubgroup checks whether given point is in correct subgroup.
func (g *G1) InCorrectSubgroup(p *PointG1) bool {
tmp := &PointG1{}
g.MulScalar(tmp, p, q)
return g.IsZero(tmp)
}
// IsOnCurve checks a G1 point is on curve.
func (g *G1) IsOnCurve(p *PointG1) bool {
if g.IsZero(p) {
return true
}
t := g.t
square(t[0], &p[1])
square(t[1], &p[0])
mul(t[1], t[1], &p[0])
square(t[2], &p[2])
square(t[3], t[2])
mul(t[2], t[2], t[3])
mul(t[2], b, t[2])
add(t[1], t[1], t[2])
return t[0].equal(t[1])
}
// IsAffine checks a G1 point whether it is in affine form.
func (g *G1) IsAffine(p *PointG1) bool {
return p[2].isOne()
}
// Add adds two G1 points p1, p2 and assigns the result to point at first argument.
func (g *G1) Affine(p *PointG1) *PointG1 {
if g.IsZero(p) {
return p
}
if !g.IsAffine(p) {
t := g.t
inverse(t[0], &p[2])
square(t[1], t[0])
mul(&p[0], &p[0], t[1])
mul(t[0], t[0], t[1])
mul(&p[1], &p[1], t[0])
p[2].one()
}
return p
}
// Add adds two G1 points p1, p2 and assigns the result to point at first argument.
func (g *G1) Add(r, p1, p2 *PointG1) *PointG1 {
// http://www.hyperelliptic.org/EFD/gp/auto-shortw-jacobian-0.html#addition-add-2007-bl
if g.IsZero(p1) {
return r.Set(p2)
}
if g.IsZero(p2) {
return r.Set(p1)
}
t := g.t
square(t[7], &p1[2])
mul(t[1], &p2[0], t[7])
mul(t[2], &p1[2], t[7])
mul(t[0], &p2[1], t[2])
square(t[8], &p2[2])
mul(t[3], &p1[0], t[8])
mul(t[4], &p2[2], t[8])
mul(t[2], &p1[1], t[4])
if t[1].equal(t[3]) {
if t[0].equal(t[2]) {
return g.Double(r, p1)
} else {
return r.Zero()
}
}
sub(t[1], t[1], t[3])
double(t[4], t[1])
square(t[4], t[4])
mul(t[5], t[1], t[4])
sub(t[0], t[0], t[2])
double(t[0], t[0])
square(t[6], t[0])
sub(t[6], t[6], t[5])
mul(t[3], t[3], t[4])
double(t[4], t[3])
sub(&r[0], t[6], t[4])
sub(t[4], t[3], &r[0])
mul(t[6], t[2], t[5])
double(t[6], t[6])
mul(t[0], t[0], t[4])
sub(&r[1], t[0], t[6])
add(t[0], &p1[2], &p2[2])
square(t[0], t[0])
sub(t[0], t[0], t[7])
sub(t[0], t[0], t[8])
mul(&r[2], t[0], t[1])
return r
}
// Double doubles a G1 point p and assigns the result to the point at first argument.
func (g *G1) Double(r, p *PointG1) *PointG1 {
// http://www.hyperelliptic.org/EFD/gp/auto-shortw-jacobian-0.html#doubling-dbl-2009-l
if g.IsZero(p) {
return r.Set(p)
}
t := g.t
square(t[0], &p[0])
square(t[1], &p[1])
square(t[2], t[1])
add(t[1], &p[0], t[1])
square(t[1], t[1])
sub(t[1], t[1], t[0])
sub(t[1], t[1], t[2])
double(t[1], t[1])
double(t[3], t[0])
add(t[0], t[3], t[0])
square(t[4], t[0])
double(t[3], t[1])
sub(&r[0], t[4], t[3])
sub(t[1], t[1], &r[0])
double(t[2], t[2])
double(t[2], t[2])
double(t[2], t[2])
mul(t[0], t[0], t[1])
sub(t[1], t[0], t[2])
mul(t[0], &p[1], &p[2])
r[1].set(t[1])
double(&r[2], t[0])
return r
}
// Neg negates a G1 point p and assigns the result to the point at first argument.
func (g *G1) Neg(r, p *PointG1) *PointG1 {
r[0].set(&p[0])
r[2].set(&p[2])
neg(&r[1], &p[1])
return r
}
// Sub subtracts two G1 points p1, p2 and assigns the result to point at first argument.
func (g *G1) Sub(c, a, b *PointG1) *PointG1 {
d := &PointG1{}
g.Neg(d, b)
g.Add(c, a, d)
return c
}
// MulScalar multiplies a point by given scalar value in big.Int and assigns the result to point at first argument.
func (g *G1) MulScalar(c, p *PointG1, e *big.Int) *PointG1 {
q, n := &PointG1{}, &PointG1{}
n.Set(p)
l := e.BitLen()
for i := 0; i < l; i++ {
if e.Bit(i) == 1 {
g.Add(q, q, n)
}
g.Double(n, n)
}
return c.Set(q)
}
// ClearCofactor maps given a G1 point to correct subgroup
func (g *G1) ClearCofactor(p *PointG1) {
g.MulScalar(p, p, cofactorEFFG1)
}
// MultiExp calculates multi exponentiation. Given pairs of G1 point and scalar values
// (P_0, e_0), (P_1, e_1), ... (P_n, e_n) calculates r = e_0 * P_0 + e_1 * P_1 + ... + e_n * P_n
// Length of points and scalars are expected to be equal, otherwise an error is returned.
// Result is assigned to point at first argument.
func (g *G1) MultiExp(r *PointG1, points []*PointG1, powers []*big.Int) (*PointG1, error) {
if len(points) != len(powers) {
return nil, errors.New("point and scalar vectors should be in same length")
}
var c uint32 = 3
if len(powers) >= 32 {
c = uint32(math.Ceil(math.Log10(float64(len(powers)))))
}
bucketSize, numBits := (1<<c)-1, uint32(g.Q().BitLen())
windows := make([]*PointG1, numBits/c+1)
bucket := make([]*PointG1, bucketSize)
acc, sum := g.New(), g.New()
for i := 0; i < bucketSize; i++ {
bucket[i] = g.New()
}
mask := (uint64(1) << c) - 1
j := 0
var cur uint32
for cur <= numBits {
acc.Zero()
bucket = make([]*PointG1, (1<<c)-1)
for i := 0; i < len(bucket); i++ {
bucket[i] = g.New()
}
for i := 0; i < len(powers); i++ {
s0 := powers[i].Uint64()
index := uint(s0 & mask)
if index != 0 {
g.Add(bucket[index-1], bucket[index-1], points[i])
}
powers[i] = new(big.Int).Rsh(powers[i], uint(c))
}
sum.Zero()
for i := len(bucket) - 1; i >= 0; i-- {
g.Add(sum, sum, bucket[i])
g.Add(acc, acc, sum)
}
windows[j] = g.New()
windows[j].Set(acc)
j++
cur += c
}
acc.Zero()
for i := len(windows) - 1; i >= 0; i-- {
for j := uint32(0); j < c; j++ {
g.Double(acc, acc)
}
g.Add(acc, acc, windows[i])
}
return r.Set(acc), nil
}
// MapToCurve given a byte slice returns a valid G1 point.
// This mapping function implements the Simplified Shallue-van de Woestijne-Ulas method.
// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06
// Input byte slice should be a valid field element, otherwise an error is returned.
func (g *G1) MapToCurve(in []byte) (*PointG1, error) {
u, err := fromBytes(in)
if err != nil {
return nil, err
}
x, y := swuMapG1(u)
isogenyMapG1(x, y)
one := new(fe).one()
p := &PointG1{*x, *y, *one}
g.ClearCofactor(p)
return g.Affine(p), nil
}
// EncodeToCurve given a message and domain seperator tag returns the hash result
// which is a valid curve point.
// Implementation follows BLS12381G1_XMD:SHA-256_SSWU_NU_ suite at
// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06
func (g *G1) EncodeToCurve(msg, domain []byte) (*PointG1, error) {
hashRes, err := hashToFpXMDSHA256(msg, domain, 1)
if err != nil {
return nil, err
}
u := hashRes[0]
x, y := swuMapG1(u)
isogenyMapG1(x, y)
one := new(fe).one()
p := &PointG1{*x, *y, *one}
g.ClearCofactor(p)
return g.Affine(p), nil
}
// HashToCurve given a message and domain seperator tag returns the hash result
// which is a valid curve point.
// Implementation follows BLS12381G1_XMD:SHA-256_SSWU_RO_ suite at
// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06
func (g *G1) HashToCurve(msg, domain []byte) (*PointG1, error) {
hashRes, err := hashToFpXMDSHA256(msg, domain, 2)
if err != nil {
return nil, err
}
u0, u1 := hashRes[0], hashRes[1]
x0, y0 := swuMapG1(u0)
x1, y1 := swuMapG1(u1)
one := new(fe).one()
p0, p1 := &PointG1{*x0, *y0, *one}, &PointG1{*x1, *y1, *one}
g.Add(p0, p0, p1)
g.Affine(p0)
isogenyMapG1(&p0[0], &p0[1])
g.ClearCofactor(p0)
return g.Affine(p0), nil
}

604
vendor/github.com/kilic/bls12-381/g2.go generated vendored Normal file
View File

@@ -0,0 +1,604 @@
package bls12381
import (
"errors"
"math"
"math/big"
)
// PointG2 is type for point in G2.
// PointG2 is both used for Affine and Jacobian point representation.
// If z is equal to one the point is accounted as in affine form.
type PointG2 [3]fe2
// Set copies valeus of one point to another.
func (p *PointG2) Set(p2 *PointG2) *PointG2 {
p[0].set(&p2[0])
p[1].set(&p2[1])
p[2].set(&p2[2])
return p
}
func (p *PointG2) Zero() *PointG2 {
p[0].zero()
p[1].one()
p[2].zero()
return p
}
type tempG2 struct {
t [9]*fe2
}
// G2 is struct for G2 group.
type G2 struct {
f *fp2
tempG2
}
// NewG2 constructs a new G2 instance.
func NewG2() *G2 {
return newG2(nil)
}
func newG2(f *fp2) *G2 {
if f == nil {
f = newFp2()
}
t := newTempG2()
return &G2{f, t}
}
func newTempG2() tempG2 {
t := [9]*fe2{}
for i := 0; i < 9; i++ {
t[i] = &fe2{}
}
return tempG2{t}
}
// Q returns group order in big.Int.
func (g *G2) Q() *big.Int {
return new(big.Int).Set(q)
}
// FromUncompressed expects byte slice larger than 192 bytes and given bytes returns a new point in G2.
// Serialization rules are in line with zcash library. See below for details.
// https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization
// https://docs.rs/bls12_381/0.1.1/bls12_381/notes/serialization/index.html
func (g *G2) FromUncompressed(uncompressed []byte) (*PointG2, error) {
if len(uncompressed) < 192 {
return nil, errors.New("input string should be equal or larger than 192")
}
var in [192]byte
copy(in[:], uncompressed[:192])
if in[0]&(1<<7) != 0 {
return nil, errors.New("compression flag should be zero")
}
if in[0]&(1<<5) != 0 {
return nil, errors.New("sort flag should be zero")
}
if in[0]&(1<<6) != 0 {
for i, v := range in {
if (i == 0 && v != 0x40) || (i != 0 && v != 0x00) {
return nil, errors.New("input string should be zero when infinity flag is set")
}
}
return g.Zero(), nil
}
in[0] &= 0x1f
x, err := g.f.fromBytes(in[:96])
if err != nil {
return nil, err
}
y, err := g.f.fromBytes(in[96:])
if err != nil {
return nil, err
}
z := new(fe2).one()
p := &PointG2{*x, *y, *z}
if !g.IsOnCurve(p) {
return nil, errors.New("point is not on curve")
}
if !g.InCorrectSubgroup(p) {
return nil, errors.New("point is not on correct subgroup")
}
return p, nil
}
// ToUncompressed given a G2 point returns bytes in uncompressed (x, y) form of the point.
// Serialization rules are in line with zcash library. See below for details.
// https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization
// https://docs.rs/bls12_381/0.1.1/bls12_381/notes/serialization/index.html
func (g *G2) ToUncompressed(p *PointG2) []byte {
out := make([]byte, 192)
g.Affine(p)
if g.IsZero(p) {
out[0] |= 1 << 6
return out
}
copy(out[:96], g.f.toBytes(&p[0]))
copy(out[96:], g.f.toBytes(&p[1]))
return out
}
// FromCompressed expects byte slice larger than 96 bytes and given bytes returns a new point in G2.
// Serialization rules are in line with zcash library. See below for details.
// https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization
// https://docs.rs/bls12_381/0.1.1/bls12_381/notes/serialization/index.html
func (g *G2) FromCompressed(compressed []byte) (*PointG2, error) {
if len(compressed) < 96 {
return nil, errors.New("input string should be equal or larger than 96")
}
var in [96]byte
copy(in[:], compressed[:])
if in[0]&(1<<7) == 0 {
return nil, errors.New("bad compression")
}
if in[0]&(1<<6) != 0 {
// in[0] == (1 << 6) + (1 << 7)
for i, v := range in {
if (i == 0 && v != 0xc0) || (i != 0 && v != 0x00) {
return nil, errors.New("input string should be zero when infinity flag is set")
}
}
return g.Zero(), nil
}
a := in[0]&(1<<5) != 0
in[0] &= 0x1f
x, err := g.f.fromBytes(in[:])
if err != nil {
return nil, err
}
// solve curve equation
y := &fe2{}
g.f.square(y, x)
g.f.mul(y, y, x)
g.f.add(y, y, b2)
if ok := g.f.sqrt(y, y); !ok {
return nil, errors.New("point is not on curve")
}
if y.signBE() == a {
g.f.neg(y, y)
}
z := new(fe2).one()
p := &PointG2{*x, *y, *z}
if !g.InCorrectSubgroup(p) {
return nil, errors.New("point is not on correct subgroup")
}
return p, nil
}
// ToCompressed given a G2 point returns bytes in compressed form of the point.
// Serialization rules are in line with zcash library. See below for details.
// https://github.com/zcash/librustzcash/blob/master/pairing/src/bls12_381/README.md#serialization
// https://docs.rs/bls12_381/0.1.1/bls12_381/notes/serialization/index.html
func (g *G2) ToCompressed(p *PointG2) []byte {
out := make([]byte, 96)
g.Affine(p)
if g.IsZero(p) {
out[0] |= 1 << 6
} else {
copy(out[:], g.f.toBytes(&p[0]))
if !p[1].signBE() {
out[0] |= 1 << 5
}
}
out[0] |= 1 << 7
return out
}
func (g *G2) fromBytesUnchecked(in []byte) (*PointG2, error) {
p0, err := g.f.fromBytes(in[:96])
if err != nil {
return nil, err
}
p1, err := g.f.fromBytes(in[96:])
if err != nil {
return nil, err
}
p2 := new(fe2).one()
return &PointG2{*p0, *p1, *p2}, nil
}
// FromBytes constructs a new point given uncompressed byte input.
// FromBytes does not take zcash flags into account.
// Byte input expected to be larger than 96 bytes.
// First 192 bytes should be concatenation of x and y values
// Point (0, 0) is considered as infinity.
func (g *G2) FromBytes(in []byte) (*PointG2, error) {
if len(in) < 192 {
return nil, errors.New("input string should be equal or larger than 192")
}
p0, err := g.f.fromBytes(in[:96])
if err != nil {
return nil, err
}
p1, err := g.f.fromBytes(in[96:])
if err != nil {
return nil, err
}
// check if given input points to infinity
if p0.isZero() && p1.isZero() {
return g.Zero(), nil
}
p2 := new(fe2).one()
p := &PointG2{*p0, *p1, *p2}
if !g.IsOnCurve(p) {
return nil, errors.New("point is not on curve")
}
return p, nil
}
// ToBytes serializes a point into bytes in uncompressed form,
// does not take zcash flags into account,
// returns (0, 0) if point is infinity.
func (g *G2) ToBytes(p *PointG2) []byte {
out := make([]byte, 192)
if g.IsZero(p) {
return out
}
g.Affine(p)
copy(out[:96], g.f.toBytes(&p[0]))
copy(out[96:], g.f.toBytes(&p[1]))
return out
}
// New creates a new G2 Point which is equal to zero in other words point at infinity.
func (g *G2) New() *PointG2 {
return new(PointG2).Zero()
}
// Zero returns a new G2 Point which is equal to point at infinity.
func (g *G2) Zero() *PointG2 {
return new(PointG2).Zero()
}
// One returns a new G2 Point which is equal to generator point.
func (g *G2) One() *PointG2 {
p := &PointG2{}
return p.Set(&g2One)
}
// IsZero returns true if given point is equal to zero.
func (g *G2) IsZero(p *PointG2) bool {
return p[2].isZero()
}
// Equal checks if given two G2 point is equal in their affine form.
func (g *G2) Equal(p1, p2 *PointG2) bool {
if g.IsZero(p1) {
return g.IsZero(p2)
}
if g.IsZero(p2) {
return g.IsZero(p1)
}
t := g.t
g.f.square(t[0], &p1[2])
g.f.square(t[1], &p2[2])
g.f.mul(t[2], t[0], &p2[0])
g.f.mul(t[3], t[1], &p1[0])
g.f.mul(t[0], t[0], &p1[2])
g.f.mul(t[1], t[1], &p2[2])
g.f.mul(t[1], t[1], &p1[1])
g.f.mul(t[0], t[0], &p2[1])
return t[0].equal(t[1]) && t[2].equal(t[3])
}
// InCorrectSubgroup checks whether given point is in correct subgroup.
func (g *G2) InCorrectSubgroup(p *PointG2) bool {
tmp := &PointG2{}
g.MulScalar(tmp, p, q)
return g.IsZero(tmp)
}
// IsOnCurve checks a G2 point is on curve.
func (g *G2) IsOnCurve(p *PointG2) bool {
if g.IsZero(p) {
return true
}
t := g.t
g.f.square(t[0], &p[1])
g.f.square(t[1], &p[0])
g.f.mul(t[1], t[1], &p[0])
g.f.square(t[2], &p[2])
g.f.square(t[3], t[2])
g.f.mul(t[2], t[2], t[3])
g.f.mul(t[2], b2, t[2])
g.f.add(t[1], t[1], t[2])
return t[0].equal(t[1])
}
// IsAffine checks a G2 point whether it is in affine form.
func (g *G2) IsAffine(p *PointG2) bool {
return p[2].isOne()
}
// Affine calculates affine form of given G2 point.
func (g *G2) Affine(p *PointG2) *PointG2 {
if g.IsZero(p) {
return p
}
if !g.IsAffine(p) {
t := g.t
g.f.inverse(t[0], &p[2])
g.f.square(t[1], t[0])
g.f.mul(&p[0], &p[0], t[1])
g.f.mul(t[0], t[0], t[1])
g.f.mul(&p[1], &p[1], t[0])
p[2].one()
}
return p
}
// Add adds two G2 points p1, p2 and assigns the result to point at first argument.
func (g *G2) Add(r, p1, p2 *PointG2) *PointG2 {
// http://www.hyperelliptic.org/EFD/gp/auto-shortw-jacobian-0.html#addition-add-2007-bl
if g.IsZero(p1) {
return r.Set(p2)
}
if g.IsZero(p2) {
return r.Set(p1)
}
t := g.t
g.f.square(t[7], &p1[2])
g.f.mul(t[1], &p2[0], t[7])
g.f.mul(t[2], &p1[2], t[7])
g.f.mul(t[0], &p2[1], t[2])
g.f.square(t[8], &p2[2])
g.f.mul(t[3], &p1[0], t[8])
g.f.mul(t[4], &p2[2], t[8])
g.f.mul(t[2], &p1[1], t[4])
if t[1].equal(t[3]) {
if t[0].equal(t[2]) {
return g.Double(r, p1)
} else {
return r.Zero()
}
}
g.f.sub(t[1], t[1], t[3])
g.f.double(t[4], t[1])
g.f.square(t[4], t[4])
g.f.mul(t[5], t[1], t[4])
g.f.sub(t[0], t[0], t[2])
g.f.double(t[0], t[0])
g.f.square(t[6], t[0])
g.f.sub(t[6], t[6], t[5])
g.f.mul(t[3], t[3], t[4])
g.f.double(t[4], t[3])
g.f.sub(&r[0], t[6], t[4])
g.f.sub(t[4], t[3], &r[0])
g.f.mul(t[6], t[2], t[5])
g.f.double(t[6], t[6])
g.f.mul(t[0], t[0], t[4])
g.f.sub(&r[1], t[0], t[6])
g.f.add(t[0], &p1[2], &p2[2])
g.f.square(t[0], t[0])
g.f.sub(t[0], t[0], t[7])
g.f.sub(t[0], t[0], t[8])
g.f.mul(&r[2], t[0], t[1])
return r
}
// Double doubles a G2 point p and assigns the result to the point at first argument.
func (g *G2) Double(r, p *PointG2) *PointG2 {
// http://www.hyperelliptic.org/EFD/gp/auto-shortw-jacobian-0.html#doubling-dbl-2009-l
if g.IsZero(p) {
return r.Set(p)
}
t := g.t
g.f.square(t[0], &p[0])
g.f.square(t[1], &p[1])
g.f.square(t[2], t[1])
g.f.add(t[1], &p[0], t[1])
g.f.square(t[1], t[1])
g.f.sub(t[1], t[1], t[0])
g.f.sub(t[1], t[1], t[2])
g.f.double(t[1], t[1])
g.f.double(t[3], t[0])
g.f.add(t[0], t[3], t[0])
g.f.square(t[4], t[0])
g.f.double(t[3], t[1])
g.f.sub(&r[0], t[4], t[3])
g.f.sub(t[1], t[1], &r[0])
g.f.double(t[2], t[2])
g.f.double(t[2], t[2])
g.f.double(t[2], t[2])
g.f.mul(t[0], t[0], t[1])
g.f.sub(t[1], t[0], t[2])
g.f.mul(t[0], &p[1], &p[2])
r[1].set(t[1])
g.f.double(&r[2], t[0])
return r
}
// Neg negates a G2 point p and assigns the result to the point at first argument.
func (g *G2) Neg(r, p *PointG2) *PointG2 {
r[0].set(&p[0])
g.f.neg(&r[1], &p[1])
r[2].set(&p[2])
return r
}
// Sub subtracts two G2 points p1, p2 and assigns the result to point at first argument.
func (g *G2) Sub(c, a, b *PointG2) *PointG2 {
d := &PointG2{}
g.Neg(d, b)
g.Add(c, a, d)
return c
}
// MulScalar multiplies a point by given scalar value in big.Int and assigns the result to point at first argument.
func (g *G2) MulScalar(c, p *PointG2, e *big.Int) *PointG2 {
q, n := &PointG2{}, &PointG2{}
n.Set(p)
l := e.BitLen()
for i := 0; i < l; i++ {
if e.Bit(i) == 1 {
g.Add(q, q, n)
}
g.Double(n, n)
}
return c.Set(q)
}
// ClearCofactor maps given a G2 point to correct subgroup
func (g *G2) ClearCofactor(p *PointG2) *PointG2 {
return g.wnafMul(p, p, cofactorEFFG2)
}
// MultiExp calculates multi exponentiation. Given pairs of G2 point and scalar values
// (P_0, e_0), (P_1, e_1), ... (P_n, e_n) calculates r = e_0 * P_0 + e_1 * P_1 + ... + e_n * P_n
// Length of points and scalars are expected to be equal, otherwise an error is returned.
// Result is assigned to point at first argument.
func (g *G2) MultiExp(r *PointG2, points []*PointG2, powers []*big.Int) (*PointG2, error) {
if len(points) != len(powers) {
return nil, errors.New("point and scalar vectors should be in same length")
}
var c uint32 = 3
if len(powers) >= 32 {
c = uint32(math.Ceil(math.Log10(float64(len(powers)))))
}
bucketSize, numBits := (1<<c)-1, uint32(g.Q().BitLen())
windows := make([]*PointG2, numBits/c+1)
bucket := make([]*PointG2, bucketSize)
acc, sum := g.New(), g.New()
for i := 0; i < bucketSize; i++ {
bucket[i] = g.New()
}
mask := (uint64(1) << c) - 1
j := 0
var cur uint32
for cur <= numBits {
acc.Zero()
bucket = make([]*PointG2, (1<<c)-1)
for i := 0; i < len(bucket); i++ {
bucket[i] = g.New()
}
for i := 0; i < len(powers); i++ {
s0 := powers[i].Uint64()
index := uint(s0 & mask)
if index != 0 {
g.Add(bucket[index-1], bucket[index-1], points[i])
}
powers[i] = new(big.Int).Rsh(powers[i], uint(c))
}
sum.Zero()
for i := len(bucket) - 1; i >= 0; i-- {
g.Add(sum, sum, bucket[i])
g.Add(acc, acc, sum)
}
windows[j] = g.New()
windows[j].Set(acc)
j++
cur += c
}
acc.Zero()
for i := len(windows) - 1; i >= 0; i-- {
for j := uint32(0); j < c; j++ {
g.Double(acc, acc)
}
g.Add(acc, acc, windows[i])
}
return r.Set(acc), nil
}
func (g *G2) wnafMul(c, p *PointG2, e *big.Int) *PointG2 {
windowSize := uint(6)
precompTable := make([]*PointG2, (1 << (windowSize - 1)))
for i := 0; i < len(precompTable); i++ {
precompTable[i] = g.New()
}
var indexForPositive uint64 = (1 << (windowSize - 2))
precompTable[indexForPositive].Set(p)
g.Neg(precompTable[indexForPositive-1], p)
doubled, precomp := g.New(), g.New()
g.Double(doubled, p)
precomp.Set(p)
for i := uint64(1); i < indexForPositive; i++ {
g.Add(precomp, precomp, doubled)
precompTable[indexForPositive+i].Set(precomp)
g.Neg(precompTable[indexForPositive-1-i], precomp)
}
wnaf := wnaf(e, windowSize)
q := g.Zero()
found := false
var idx uint64
for i := len(wnaf) - 1; i >= 0; i-- {
if found {
g.Double(q, q)
}
if wnaf[i] != 0 {
found = true
if wnaf[i] > 0 {
idx = uint64(wnaf[i] >> 1)
g.Add(q, q, precompTable[indexForPositive+idx])
} else {
idx = uint64(((0 - wnaf[i]) >> 1))
g.Add(q, q, precompTable[indexForPositive-1-idx])
}
}
}
return c.Set(q)
}
// MapToCurve given a byte slice returns a valid G2 point.
// This mapping function implements the Simplified Shallue-van de Woestijne-Ulas method.
// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-05#section-6.6.2
// Input byte slice should be a valid field element, otherwise an error is returned.
func (g *G2) MapToCurve(in []byte) (*PointG2, error) {
fp2 := g.f
u, err := fp2.fromBytes(in)
if err != nil {
return nil, err
}
x, y := swuMapG2(fp2, u)
isogenyMapG2(fp2, x, y)
z := new(fe2).one()
q := &PointG2{*x, *y, *z}
g.ClearCofactor(q)
return g.Affine(q), nil
}
// EncodeToCurve given a message and domain seperator tag returns the hash result
// which is a valid curve point.
// Implementation follows BLS12381G1_XMD:SHA-256_SSWU_NU_ suite at
// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06
func (g *G2) EncodeToCurve(msg, domain []byte) (*PointG2, error) {
hashRes, err := hashToFpXMDSHA256(msg, domain, 2)
if err != nil {
return nil, err
}
fp2 := g.f
u := &fe2{*hashRes[0], *hashRes[1]}
x, y := swuMapG2(fp2, u)
isogenyMapG2(fp2, x, y)
z := new(fe2).one()
q := &PointG2{*x, *y, *z}
g.ClearCofactor(q)
return g.Affine(q), nil
}
// HashToCurve given a message and domain seperator tag returns the hash result
// which is a valid curve point.
// Implementation follows BLS12381G1_XMD:SHA-256_SSWU_RO_ suite at
// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06
func (g *G2) HashToCurve(msg, domain []byte) (*PointG2, error) {
hashRes, err := hashToFpXMDSHA256(msg, domain, 4)
if err != nil {
return nil, err
}
fp2 := g.f
u0, u1 := &fe2{*hashRes[0], *hashRes[1]}, &fe2{*hashRes[2], *hashRes[3]}
x0, y0 := swuMapG2(fp2, u0)
x1, y1 := swuMapG2(fp2, u1)
z0 := new(fe2).one()
z1 := new(fe2).one()
p0, p1 := &PointG2{*x0, *y0, *z0}, &PointG2{*x1, *y1, *z1}
g.Add(p0, p0, p1)
g.Affine(p0)
isogenyMapG2(fp2, &p0[0], &p0[1])
g.ClearCofactor(p0)
return g.Affine(p0), nil
}

106
vendor/github.com/kilic/bls12-381/gt.go generated vendored Normal file
View File

@@ -0,0 +1,106 @@
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
}
// Set copies given value into the destination
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)
}

70
vendor/github.com/kilic/bls12-381/hash_to_field.go generated vendored Normal file
View File

@@ -0,0 +1,70 @@
package bls12381
import (
"crypto/sha256"
"errors"
)
func hashToFpXMDSHA256(msg []byte, domain []byte, count int) ([]*fe, error) {
randBytes, err := expandMsgSHA256XMD(msg, domain, count*64)
if err != nil {
return nil, err
}
els := make([]*fe, count)
for i := 0; i < count; i++ {
els[i], err = from64Bytes(randBytes[i*64 : (i+1)*64])
if err != nil {
return nil, err
}
}
return els, nil
}
func expandMsgSHA256XMD(msg []byte, domain []byte, outLen int) ([]byte, error) {
h := sha256.New()
domainLen := uint8(len(domain))
if domainLen > 255 {
return nil, errors.New("invalid domain length")
}
// DST_prime = DST || I2OSP(len(DST), 1)
// b_0 = H(Z_pad || msg || l_i_b_str || I2OSP(0, 1) || DST_prime)
_, _ = h.Write(make([]byte, h.BlockSize()))
_, _ = h.Write(msg)
_, _ = h.Write([]byte{uint8(outLen >> 8), uint8(outLen)})
_, _ = h.Write([]byte{0})
_, _ = h.Write(domain)
_, _ = h.Write([]byte{domainLen})
b0 := h.Sum(nil)
// b_1 = H(b_0 || I2OSP(1, 1) || DST_prime)
h.Reset()
_, _ = h.Write(b0)
_, _ = h.Write([]byte{1})
_, _ = h.Write(domain)
_, _ = h.Write([]byte{domainLen})
b1 := h.Sum(nil)
// b_i = H(strxor(b_0, b_(i - 1)) || I2OSP(i, 1) || DST_prime)
ell := (outLen + h.Size() - 1) / h.Size()
bi := b1
out := make([]byte, outLen)
for i := 1; i < ell; i++ {
h.Reset()
// b_i = H(strxor(b_0, b_(i - 1)) || I2OSP(i, 1) || DST_prime)
tmp := make([]byte, h.Size())
for j := 0; j < h.Size(); j++ {
tmp[j] = b0[j] ^ bi[j]
}
_, _ = h.Write(tmp)
_, _ = h.Write([]byte{1 + uint8(i)})
_, _ = h.Write(domain)
_, _ = h.Write([]byte{domainLen})
// b_1 || ... || b_(ell - 1)
copy(out[(i-1)*h.Size():i*h.Size()], bi[:])
bi = h.Sum(nil)
}
// b_ell
copy(out[(ell-1)*h.Size():], bi[:])
return out[:outLen], nil
}

211
vendor/github.com/kilic/bls12-381/isogeny.go generated vendored Normal file
View File

@@ -0,0 +1,211 @@
package bls12381
// isogenyMapG1 applies 11-isogeny map for BLS12-381 G1 defined at draft-irtf-cfrg-hash-to-curve-06.
func isogenyMapG1(x, y *fe) {
// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#appendix-C.2
params := isogenyConstansG1
degree := 15
xNum, xDen, yNum, yDen := new(fe), new(fe), new(fe), new(fe)
xNum.set(params[0][degree])
xDen.set(params[1][degree])
yNum.set(params[2][degree])
yDen.set(params[3][degree])
for i := degree - 1; i >= 0; i-- {
mul(xNum, xNum, x)
mul(xDen, xDen, x)
mul(yNum, yNum, x)
mul(yDen, yDen, x)
add(xNum, xNum, params[0][i])
add(xDen, xDen, params[1][i])
add(yNum, yNum, params[2][i])
add(yDen, yDen, params[3][i])
}
inverse(xDen, xDen)
inverse(yDen, yDen)
mul(xNum, xNum, xDen)
mul(yNum, yNum, yDen)
mul(yNum, yNum, y)
x.set(xNum)
y.set(yNum)
}
// isogenyMapG2 applies 11-isogeny map for BLS12-381 G1 defined at draft-irtf-cfrg-hash-to-curve-06.
func isogenyMapG2(e *fp2, x, y *fe2) {
if e == nil {
e = newFp2()
}
// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#appendix-C.2
params := isogenyConstantsG2
degree := 3
xNum := new(fe2).set(params[0][degree])
xDen := new(fe2).set(params[1][degree])
yNum := new(fe2).set(params[2][degree])
yDen := new(fe2).set(params[3][degree])
for i := degree - 1; i >= 0; i-- {
e.mul(xNum, xNum, x)
e.mul(xDen, xDen, x)
e.mul(yNum, yNum, x)
e.mul(yDen, yDen, x)
e.add(xNum, xNum, params[0][i])
e.add(xDen, xDen, params[1][i])
e.add(yNum, yNum, params[2][i])
e.add(yDen, yDen, params[3][i])
}
e.inverse(xDen, xDen)
e.inverse(yDen, yDen)
e.mul(xNum, xNum, xDen)
e.mul(yNum, yNum, yDen)
e.mul(yNum, yNum, y)
x.set(xNum)
y.set(yNum)
}
var isogenyConstansG1 = [4][16]*fe{
[16]*fe{
&fe{0x4d18b6f3af00131c, 0x19fa219793fee28c, 0x3f2885f1467f19ae, 0x23dcea34f2ffb304, 0xd15b58d2ffc00054, 0x0913be200a20bef4},
&fe{0x898985385cdbbd8b, 0x3c79e43cc7d966aa, 0x1597e193f4cd233a, 0x8637ef1e4d6623ad, 0x11b22deed20d827b, 0x07097bc5998784ad},
&fe{0xa542583a480b664b, 0xfc7169c026e568c6, 0x5ba2ef314ed8b5a6, 0x5b5491c05102f0e7, 0xdf6e99707d2a0079, 0x0784151ed7605524},
&fe{0x494e212870f72741, 0xab9be52fbda43021, 0x26f5577994e34c3d, 0x049dfee82aefbd60, 0x65dadd7828505289, 0x0e93d431ea011aeb},
&fe{0x90ee774bd6a74d45, 0x7ada1c8a41bfb185, 0x0f1a8953b325f464, 0x104c24211be4805c, 0x169139d319ea7a8f, 0x09f20ead8e532bf6},
&fe{0x6ddd93e2f43626b7, 0xa5482c9aa1ccd7bd, 0x143245631883f4bd, 0x2e0a94ccf77ec0db, 0xb0282d480e56489f, 0x18f4bfcbb4368929},
&fe{0x23c5f0c953402dfd, 0x7a43ff6958ce4fe9, 0x2c390d3d2da5df63, 0xd0df5c98e1f9d70f, 0xffd89869a572b297, 0x1277ffc72f25e8fe},
&fe{0x79f4f0490f06a8a6, 0x85f894a88030fd81, 0x12da3054b18b6410, 0xe2a57f6505880d65, 0xbba074f260e400f1, 0x08b76279f621d028},
&fe{0xe67245ba78d5b00b, 0x8456ba9a1f186475, 0x7888bff6e6b33bb4, 0xe21585b9a30f86cb, 0x05a69cdcef55feee, 0x09e699dd9adfa5ac},
&fe{0x0de5c357bff57107, 0x0a0db4ae6b1a10b2, 0xe256bb67b3b3cd8d, 0x8ad456574e9db24f, 0x0443915f50fd4179, 0x098c4bf7de8b6375},
&fe{0xe6b0617e7dd929c7, 0xfe6e37d442537375, 0x1dafdeda137a489e, 0xe4efd1ad3f767ceb, 0x4a51d8667f0fe1cf, 0x054fdf4bbf1d821c},
&fe{0x72db2a50658d767b, 0x8abf91faa257b3d5, 0xe969d6833764ab47, 0x464170142a1009eb, 0xb14f01aadb30be2f, 0x18ae6a856f40715d},
&fe{0, 0, 0, 0, 0, 0},
&fe{0, 0, 0, 0, 0, 0},
&fe{0, 0, 0, 0, 0, 0},
&fe{0, 0, 0, 0, 0, 0},
},
[16]*fe{
&fe{0xb962a077fdb0f945, 0xa6a9740fefda13a0, 0xc14d568c3ed6c544, 0xb43fc37b908b133e, 0x9c0b3ac929599016, 0x0165aa6c93ad115f},
&fe{0x23279a3ba506c1d9, 0x92cfca0a9465176a, 0x3b294ab13755f0ff, 0x116dda1c5070ae93, 0xed4530924cec2045, 0x083383d6ed81f1ce},
&fe{0x9885c2a6449fecfc, 0x4a2b54ccd37733f0, 0x17da9ffd8738c142, 0xa0fba72732b3fafd, 0xff364f36e54b6812, 0x0f29c13c660523e2},
&fe{0xe349cc118278f041, 0xd487228f2f3204fb, 0xc9d325849ade5150, 0x43a92bd69c15c2df, 0x1c2c7844bc417be4, 0x12025184f407440c},
&fe{0x587f65ae6acb057b, 0x1444ef325140201f, 0xfbf995e71270da49, 0xccda066072436a42, 0x7408904f0f186bb2, 0x13b93c63edf6c015},
&fe{0xfb918622cd141920, 0x4a4c64423ecaddb4, 0x0beb232927f7fb26, 0x30f94df6f83a3dc2, 0xaeedd424d780f388, 0x06cc402dd594bbeb},
&fe{0xd41f761151b23f8f, 0x32a92465435719b3, 0x64f436e888c62cb9, 0xdf70a9a1f757c6e4, 0x6933a38d5b594c81, 0x0c6f7f7237b46606},
&fe{0x693c08747876c8f7, 0x22c9850bf9cf80f0, 0x8e9071dab950c124, 0x89bc62d61c7baf23, 0xbc6be2d8dad57c23, 0x17916987aa14a122},
&fe{0x1be3ff439c1316fd, 0x9965243a7571dfa7, 0xc7f7f62962f5cd81, 0x32c6aa9af394361c, 0xbbc2ee18e1c227f4, 0x0c102cbac531bb34},
&fe{0x997614c97bacbf07, 0x61f86372b99192c0, 0x5b8c95fc14353fc3, 0xca2b066c2a87492f, 0x16178f5bbf698711, 0x12a6dcd7f0f4e0e8},
&fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493},
&fe{0, 0, 0, 0, 0, 0},
&fe{0, 0, 0, 0, 0, 0},
&fe{0, 0, 0, 0, 0, 0},
&fe{0, 0, 0, 0, 0, 0},
&fe{0, 0, 0, 0, 0, 0},
},
[16]*fe{
&fe{0x2b567ff3e2837267, 0x1d4d9e57b958a767, 0xce028fea04bd7373, 0xcc31a30a0b6cd3df, 0x7d7b18a682692693, 0x0d300744d42a0310},
&fe{0x99c2555fa542493f, 0xfe7f53cc4874f878, 0x5df0608b8f97608a, 0x14e03832052b49c8, 0x706326a6957dd5a4, 0x0a8dadd9c2414555},
&fe{0x13d942922a5cf63a, 0x357e33e36e261e7d, 0xcf05a27c8456088d, 0x0000bd1de7ba50f0, 0x83d0c7532f8c1fde, 0x13f70bf38bbf2905},
&fe{0x5c57fd95bfafbdbb, 0x28a359a65e541707, 0x3983ceb4f6360b6d, 0xafe19ff6f97e6d53, 0xb3468f4550192bf7, 0x0bb6cde49d8ba257},
&fe{0x590b62c7ff8a513f, 0x314b4ce372cacefd, 0x6bef32ce94b8a800, 0x6ddf84a095713d5f, 0x64eace4cb0982191, 0x0386213c651b888d},
&fe{0xa5310a31111bbcdd, 0xa14ac0f5da148982, 0xf9ad9cc95423d2e9, 0xaa6ec095283ee4a7, 0xcf5b1f022e1c9107, 0x01fddf5aed881793},
&fe{0x65a572b0d7a7d950, 0xe25c2d8183473a19, 0xc2fcebe7cb877dbd, 0x05b2d36c769a89b0, 0xba12961be86e9efb, 0x07eb1b29c1dfde1f},
&fe{0x93e09572f7c4cd24, 0x364e929076795091, 0x8569467e68af51b5, 0xa47da89439f5340f, 0xf4fa918082e44d64, 0x0ad52ba3e6695a79},
&fe{0x911429844e0d5f54, 0xd03f51a3516bb233, 0x3d587e5640536e66, 0xfa86d2a3a9a73482, 0xa90ed5adf1ed5537, 0x149c9c326a5e7393},
&fe{0x462bbeb03c12921a, 0xdc9af5fa0a274a17, 0x9a558ebde836ebed, 0x649ef8f11a4fae46, 0x8100e1652b3cdc62, 0x1862bd62c291dacb},
&fe{0x05c9b8ca89f12c26, 0x0194160fa9b9ac4f, 0x6a643d5a6879fa2c, 0x14665bdd8846e19d, 0xbb1d0d53af3ff6bf, 0x12c7e1c3b28962e5},
&fe{0xb55ebf900b8a3e17, 0xfedc77ec1a9201c4, 0x1f07db10ea1a4df4, 0x0dfbd15dc41a594d, 0x389547f2334a5391, 0x02419f98165871a4},
&fe{0xb416af000745fc20, 0x8e563e9d1ea6d0f5, 0x7c763e17763a0652, 0x01458ef0159ebbef, 0x8346fe421f96bb13, 0x0d2d7b829ce324d2},
&fe{0x93096bb538d64615, 0x6f2a2619951d823a, 0x8f66b3ea59514fa4, 0xf563e63704f7092f, 0x724b136c4cf2d9fa, 0x046959cfcfd0bf49},
&fe{0xea748d4b6e405346, 0x91e9079c2c02d58f, 0x41064965946d9b59, 0xa06731f1d2bbe1ee, 0x07f897e267a33f1b, 0x1017290919210e5f},
&fe{0x872aa6c17d985097, 0xeecc53161264562a, 0x07afe37afff55002, 0x54759078e5be6838, 0xc4b92d15db8acca8, 0x106d87d1b51d13b9},
},
[16]*fe{
&fe{0xeb6c359d47e52b1c, 0x18ef5f8a10634d60, 0xddfa71a0889d5b7e, 0x723e71dcc5fc1323, 0x52f45700b70d5c69, 0x0a8b981ee47691f1},
&fe{0x616a3c4f5535b9fb, 0x6f5f037395dbd911, 0xf25f4cc5e35c65da, 0x3e50dffea3c62658, 0x6a33dca523560776, 0x0fadeff77b6bfe3e},
&fe{0x2be9b66df470059c, 0x24a2c159a3d36742, 0x115dbe7ad10c2a37, 0xb6634a652ee5884d, 0x04fe8bb2b8d81af4, 0x01c2a7a256fe9c41},
&fe{0xf27bf8ef3b75a386, 0x898b367476c9073f, 0x24482e6b8c2f4e5f, 0xc8e0bbd6fe110806, 0x59b0c17f7631448a, 0x11037cd58b3dbfbd},
&fe{0x31c7912ea267eec6, 0x1dbf6f1c5fcdb700, 0xd30d4fe3ba86fdb1, 0x3cae528fbee9a2a4, 0xb1cce69b6aa9ad9a, 0x044393bb632d94fb},
&fe{0xc66ef6efeeb5c7e8, 0x9824c289dd72bb55, 0x71b1a4d2f119981d, 0x104fc1aafb0919cc, 0x0e49df01d942a628, 0x096c3a09773272d4},
&fe{0x9abc11eb5fadeff4, 0x32dca50a885728f0, 0xfb1fa3721569734c, 0xc4b76271ea6506b3, 0xd466a75599ce728e, 0x0c81d4645f4cb6ed},
&fe{0x4199f10e5b8be45b, 0xda64e495b1e87930, 0xcb353efe9b33e4ff, 0x9e9efb24aa6424c6, 0xf08d33680a237465, 0x0d3378023e4c7406},
&fe{0x7eb4ae92ec74d3a5, 0xc341b4aa9fac3497, 0x5be603899e907687, 0x03bfd9cca75cbdeb, 0x564c2935a96bfa93, 0x0ef3c33371e2fdb5},
&fe{0x7ee91fd449f6ac2e, 0xe5d5bd5cb9357a30, 0x773a8ca5196b1380, 0xd0fda172174ed023, 0x6cb95e0fa776aead, 0x0d22d5a40cec7cff},
&fe{0xf727e09285fd8519, 0xdc9d55a83017897b, 0x7549d8bd057894ae, 0x178419613d90d8f8, 0xfce95ebdeb5b490a, 0x0467ffaef23fc49e},
&fe{0xc1769e6a7c385f1b, 0x79bc930deac01c03, 0x5461c75a23ede3b5, 0x6e20829e5c230c45, 0x828e0f1e772a53cd, 0x116aefa749127bff},
&fe{0x101c10bf2744c10a, 0xbbf18d053a6a3154, 0xa0ecf39ef026f602, 0xfc009d4996dc5153, 0xb9000209d5bd08d3, 0x189e5fe4470cd73c},
&fe{0x7ebd546ca1575ed2, 0xe47d5a981d081b55, 0x57b2b625b6d4ca21, 0xb0a1ba04228520cc, 0x98738983c2107ff3, 0x13dddbc4799d81d6},
&fe{0x09319f2e39834935, 0x039e952cbdb05c21, 0x55ba77a9a2f76493, 0xfd04e3dfc6086467, 0xfb95832e7d78742e, 0x0ef9c24eccaf5e0e},
&fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493},
},
}
var isogenyConstantsG2 = [4][4]*fe2{
[4]*fe2{
&fe2{
fe{0x47f671c71ce05e62, 0x06dd57071206393e, 0x7c80cd2af3fd71a2, 0x048103ea9e6cd062, 0xc54516acc8d037f6, 0x13808f550920ea41},
fe{0x47f671c71ce05e62, 0x06dd57071206393e, 0x7c80cd2af3fd71a2, 0x048103ea9e6cd062, 0xc54516acc8d037f6, 0x13808f550920ea41},
},
&fe2{
fe{0, 0, 0, 0, 0, 0},
fe{0x5fe55555554c71d0, 0x873fffdd236aaaa3, 0x6a6b4619b26ef918, 0x21c2888408874945, 0x2836cda7028cabc5, 0x0ac73310a7fd5abd},
},
&fe2{
fe{0x0a0c5555555971c3, 0xdb0c00101f9eaaae, 0xb1fb2f941d797997, 0xd3960742ef416e1c, 0xb70040e2c20556f4, 0x149d7861e581393b},
fe{0xaff2aaaaaaa638e8, 0x439fffee91b55551, 0xb535a30cd9377c8c, 0x90e144420443a4a2, 0x941b66d3814655e2, 0x0563998853fead5e},
},
&fe2{
fe{0x40aac71c71c725ed, 0x190955557a84e38e, 0xd817050a8f41abc3, 0xd86485d4c87f6fb1, 0x696eb479f885d059, 0x198e1a74328002d2},
fe{0, 0, 0, 0, 0, 0},
},
},
[4]*fe2{
&fe2{
fe{0, 0, 0, 0, 0, 0},
fe{0x1f3affffff13ab97, 0xf25bfc611da3ff3e, 0xca3757cb3819b208, 0x3e6427366f8cec18, 0x03977bc86095b089, 0x04f69db13f39a952},
},
&fe2{
fe{0x447600000027552e, 0xdcb8009a43480020, 0x6f7ee9ce4a6e8b59, 0xb10330b7c0a95bc6, 0x6140b1fcfb1e54b7, 0x0381be097f0bb4e1},
fe{0x7588ffffffd8557d, 0x41f3ff646e0bffdf, 0xf7b1e8d2ac426aca, 0xb3741acd32dbb6f8, 0xe9daf5b9482d581f, 0x167f53e0ba7431b8},
},
&fe2{
fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493},
fe{0, 0, 0, 0, 0, 0},
},
&fe2{
fe{0, 0, 0, 0, 0, 0},
fe{0, 0, 0, 0, 0, 0},
},
},
[4]*fe2{
&fe2{
fe{0x96d8f684bdfc77be, 0xb530e4f43b66d0e2, 0x184a88ff379652fd, 0x57cb23ecfae804e1, 0x0fd2e39eada3eba9, 0x08c8055e31c5d5c3},
fe{0x96d8f684bdfc77be, 0xb530e4f43b66d0e2, 0x184a88ff379652fd, 0x57cb23ecfae804e1, 0x0fd2e39eada3eba9, 0x08c8055e31c5d5c3},
},
&fe2{
fe{0, 0, 0, 0, 0, 0},
fe{0xbf0a71c71c91b406, 0x4d6d55d28b7638fd, 0x9d82f98e5f205aee, 0xa27aa27b1d1a18d5, 0x02c3b2b2d2938e86, 0x0c7d13420b09807f},
},
&fe2{
fe{0xd7f9555555531c74, 0x21cffff748daaaa8, 0x5a9ad1866c9bbe46, 0x4870a2210221d251, 0x4a0db369c0a32af1, 0x02b1ccc429ff56af},
fe{0xe205aaaaaaac8e37, 0xfcdc000768795556, 0x0c96011a8a1537dd, 0x1c06a963f163406e, 0x010df44c82a881e6, 0x174f45260f808feb},
},
&fe2{
fe{0xa470bda12f67f35c, 0xc0fe38e23327b425, 0xc9d3d0f2c6f0678d, 0x1c55c9935b5a982e, 0x27f6c0e2f0746764, 0x117c5e6e28aa9054},
fe{0, 0, 0, 0, 0, 0},
},
},
[4]*fe2{
&fe2{
fe{0x0162fffffa765adf, 0x8f7bea480083fb75, 0x561b3c2259e93611, 0x11e19fc1a9c875d5, 0xca713efc00367660, 0x03c6a03d41da1151},
fe{0x0162fffffa765adf, 0x8f7bea480083fb75, 0x561b3c2259e93611, 0x11e19fc1a9c875d5, 0xca713efc00367660, 0x03c6a03d41da1151},
},
&fe2{
fe{0, 0, 0, 0, 0, 0},
fe{0x5db0fffffd3b02c5, 0xd713f52358ebfdba, 0x5ea60761a84d161a, 0xbb2c75a34ea6c44a, 0x0ac6735921c1119b, 0x0ee3d913bdacfbf6},
},
&fe2{
fe{0x66b10000003affc5, 0xcb1400e764ec0030, 0xa73e5eb56fa5d106, 0x8984c913a0fe09a9, 0x11e10afb78ad7f13, 0x05429d0e3e918f52},
fe{0x534dffffffc4aae6, 0x5397ff174c67ffcf, 0xbff273eb870b251d, 0xdaf2827152870915, 0x393a9cbaca9e2dc3, 0x14be74dbfaee5748},
},
&fe2{
fe{0x760900000002fffd, 0xebf4000bc40c0002, 0x5f48985753c758ba, 0x77ce585370525745, 0x5c071a97a256ec6d, 0x15f65ec3fa80e493},
fe{0, 0, 0, 0, 0, 0},
},
},
}

266
vendor/github.com/kilic/bls12-381/pairing.go generated vendored Normal file
View File

@@ -0,0 +1,266 @@
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
}
// NewEngine creates new pairing engine insteace.
func NewEngine() *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 := int(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()
}

142
vendor/github.com/kilic/bls12-381/swu.go generated vendored Normal file
View File

@@ -0,0 +1,142 @@
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},
},
}

13
vendor/github.com/kilic/bls12-381/utils.go generated vendored Normal file
View File

@@ -0,0 +1,13 @@
package bls12381
import (
"math/big"
)
func bigFromHex(hex string) *big.Int {
if len(hex) > 1 && hex[:2] == "0x" {
hex = hex[2:]
}
n, _ := new(big.Int).SetString(hex, 16)
return n
}

35
vendor/github.com/kilic/bls12-381/wnaf.go generated vendored Normal file
View File

@@ -0,0 +1,35 @@
package bls12381
import (
"math/big"
)
func wnaf(e0 *big.Int, window uint) []int64 {
e := new(big.Int).Set(e0)
zero := big.NewInt(0)
if e.Cmp(zero) == 0 {
return []int64{}
}
max := int64(1 << window)
midpoint := int64(1 << (window - 1))
modulusMask := uint64(1<<window) - 1
var out []int64
for e.Cmp(zero) != 0 {
var z int64
if e.Bit(0)&1 == 1 {
maskedBits := int64(e.Uint64() & modulusMask)
if maskedBits > midpoint {
z = maskedBits - max
e.Add(e, new(big.Int).SetInt64(0-z))
} else {
z = maskedBits
e.Sub(e, new(big.Int).SetInt64(z))
}
} else {
z = 0
}
out = append(out, z)
e.Rsh(e, 1)
}
return out
}