2
vendor/github.com/kilic/bls12-381/.gitignore
generated
vendored
Normal file
2
vendor/github.com/kilic/bls12-381/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*.out
|
||||
eip2537
|
||||
202
vendor/github.com/kilic/bls12-381/LICENSE
generated
vendored
Normal file
202
vendor/github.com/kilic/bls12-381/LICENSE
generated
vendored
Normal 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
30
vendor/github.com/kilic/bls12-381/README.md
generated
vendored
Normal 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
66
vendor/github.com/kilic/bls12-381/arithmetic_decl.go
generated
vendored
Normal 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)
|
||||
566
vendor/github.com/kilic/bls12-381/arithmetic_fallback.go
generated
vendored
Normal file
566
vendor/github.com/kilic/bls12-381/arithmetic_fallback.go
generated
vendored
Normal 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
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
234
vendor/github.com/kilic/bls12-381/bls12_381.go
generated
vendored
Normal 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
338
vendor/github.com/kilic/bls12-381/field_element.go
generated
vendored
Normal 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
183
vendor/github.com/kilic/bls12-381/fp.go
generated
vendored
Normal 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
263
vendor/github.com/kilic/bls12-381/fp12.go
generated
vendored
Normal 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
245
vendor/github.com/kilic/bls12-381/fp2.go
generated
vendored
Normal 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
342
vendor/github.com/kilic/bls12-381/fp6.go
generated
vendored
Normal 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
551
vendor/github.com/kilic/bls12-381/g1.go
generated
vendored
Normal 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
604
vendor/github.com/kilic/bls12-381/g2.go
generated
vendored
Normal 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
106
vendor/github.com/kilic/bls12-381/gt.go
generated
vendored
Normal 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 >{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
70
vendor/github.com/kilic/bls12-381/hash_to_field.go
generated
vendored
Normal 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
211
vendor/github.com/kilic/bls12-381/isogeny.go
generated
vendored
Normal 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
266
vendor/github.com/kilic/bls12-381/pairing.go
generated
vendored
Normal 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
142
vendor/github.com/kilic/bls12-381/swu.go
generated
vendored
Normal 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
13
vendor/github.com/kilic/bls12-381/utils.go
generated
vendored
Normal 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
35
vendor/github.com/kilic/bls12-381/wnaf.go
generated
vendored
Normal 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
|
||||
}
|
||||
Reference in New Issue
Block a user