diff --git a/crypto/bn256/LICENSE b/crypto/bn256/LICENSE deleted file mode 100644 index 634e0cb2c3..0000000000 --- a/crypto/bn256/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -Copyright (c) 2012 The Go Authors. All rights reserved. -Copyright (c) 2018 Péter Szilágyi. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/crypto/bn256/bn256_fast.go b/crypto/bn256/bn256_fast.go index ac519d3016..1e118588c5 100644 --- a/crypto/bn256/bn256_fast.go +++ b/crypto/bn256/bn256_fast.go @@ -2,13 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be found // in the LICENSE file. +//go:build amd64 || arm64 // +build amd64 arm64 // Package bn256 implements the Optimal Ate pairing over a 256-bit Barreto-Naehrig curve. package bn256 import ( - bn256cf "github.com/dominant-strategies/go-quai/crypto/bn256/cloudflare" + bn256cf "github.com/dominant-strategies/bn256" ) // G1 is an abstract cyclic group. The zero value is suitable for use as the diff --git a/crypto/bn256/bn256_slow.go b/crypto/bn256/bn256_slow.go deleted file mode 100644 index c29194087a..0000000000 --- a/crypto/bn256/bn256_slow.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2018 Péter Szilágyi. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be found -// in the LICENSE file. - -// +build !amd64,!arm64 - -// Package bn256 implements the Optimal Ate pairing over a 256-bit Barreto-Naehrig curve. -package bn256 - -import bn256 "github.com/dominant-strategies/go-quai/crypto/bn256/google" - -// G1 is an abstract cyclic group. The zero value is suitable for use as the -// output of an operation, but cannot be used as an input. -type G1 = bn256.G1 - -// G2 is an abstract cyclic group. The zero value is suitable for use as the -// output of an operation, but cannot be used as an input. -type G2 = bn256.G2 - -// PairingCheck calculates the Optimal Ate pairing for a set of points. -func PairingCheck(a []*G1, b []*G2) bool { - return bn256.PairingCheck(a, b) -} diff --git a/crypto/bn256/cloudflare/LICENSE b/crypto/bn256/cloudflare/LICENSE deleted file mode 100644 index 6a66aea5ea..0000000000 --- a/crypto/bn256/cloudflare/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/crypto/bn256/cloudflare/bn256.go b/crypto/bn256/cloudflare/bn256.go deleted file mode 100644 index 4f607af2ad..0000000000 --- a/crypto/bn256/cloudflare/bn256.go +++ /dev/null @@ -1,495 +0,0 @@ -// Package bn256 implements a particular bilinear group at the 128-bit security -// level. -// -// Bilinear groups are the basis of many of the new cryptographic protocols that -// have been proposed over the past decade. They consist of a triplet of groups -// (G₁, G₂ and GT) such that there exists a function e(g₁ˣ,g₂ʸ)=gTˣʸ (where gₓ -// is a generator of the respective group). That function is called a pairing -// function. -// -// This package specifically implements the Optimal Ate pairing over a 256-bit -// Barreto-Naehrig curve as described in -// http://cryptojedi.org/papers/dclxvi-20100714.pdf. Its output is not -// compatible with the implementation described in that paper, as different -// parameters are chosen. -// -// (This package previously claimed to operate at a 128-bit security level. -// However, recent improvements in attacks mean that is no longer true. See -// https://moderncrypto.org/mail-archive/curves/2016/000740.html.) -package bn256 - -import ( - "crypto/rand" - "errors" - "io" - "math/big" -) - -func randomK(r io.Reader) (k *big.Int, err error) { - for { - k, err = rand.Int(r, Order) - if err != nil || k.Sign() > 0 { - return - } - } -} - -// G1 is an abstract cyclic group. The zero value is suitable for use as the -// output of an operation, but cannot be used as an input. -type G1 struct { - p *curvePoint -} - -// RandomG1 returns x and g₁ˣ where x is a random, non-zero number read from r. -func RandomG1(r io.Reader) (*big.Int, *G1, error) { - k, err := randomK(r) - if err != nil { - return nil, nil, err - } - - return k, new(G1).ScalarBaseMult(k), nil -} - -func (g *G1) String() string { - return "bn256.G1" + g.p.String() -} - -// ScalarBaseMult sets e to g*k where g is the generator of the group and then -// returns e. -func (e *G1) ScalarBaseMult(k *big.Int) *G1 { - if e.p == nil { - e.p = &curvePoint{} - } - e.p.Mul(curveGen, k) - return e -} - -// ScalarMult sets e to a*k and then returns e. -func (e *G1) ScalarMult(a *G1, k *big.Int) *G1 { - if e.p == nil { - e.p = &curvePoint{} - } - e.p.Mul(a.p, k) - return e -} - -// Add sets e to a+b and then returns e. -func (e *G1) Add(a, b *G1) *G1 { - if e.p == nil { - e.p = &curvePoint{} - } - e.p.Add(a.p, b.p) - return e -} - -// Neg sets e to -a and then returns e. -func (e *G1) Neg(a *G1) *G1 { - if e.p == nil { - e.p = &curvePoint{} - } - e.p.Neg(a.p) - return e -} - -// Set sets e to a and then returns e. -func (e *G1) Set(a *G1) *G1 { - if e.p == nil { - e.p = &curvePoint{} - } - e.p.Set(a.p) - return e -} - -// Marshal converts e to a byte slice. -func (e *G1) Marshal() []byte { - // Each value is a 256-bit number. - const numBytes = 256 / 8 - - if e.p == nil { - e.p = &curvePoint{} - } - - e.p.MakeAffine() - ret := make([]byte, numBytes*2) - if e.p.IsInfinity() { - return ret - } - temp := &gfP{} - - montDecode(temp, &e.p.x) - temp.Marshal(ret) - montDecode(temp, &e.p.y) - temp.Marshal(ret[numBytes:]) - - return ret -} - -// Unmarshal sets e to the result of converting the output of Marshal back into -// a group element and then returns e. -func (e *G1) Unmarshal(m []byte) ([]byte, error) { - // Each value is a 256-bit number. - const numBytes = 256 / 8 - if len(m) < 2*numBytes { - return nil, errors.New("bn256: not enough data") - } - // Unmarshal the points and check their caps - if e.p == nil { - e.p = &curvePoint{} - } else { - e.p.x, e.p.y = gfP{0}, gfP{0} - } - var err error - if err = e.p.x.Unmarshal(m); err != nil { - return nil, err - } - if err = e.p.y.Unmarshal(m[numBytes:]); err != nil { - return nil, err - } - // Encode into Montgomery form and ensure it's on the curve - montEncode(&e.p.x, &e.p.x) - montEncode(&e.p.y, &e.p.y) - - zero := gfP{0} - if e.p.x == zero && e.p.y == zero { - // This is the point at infinity. - e.p.y = *newGFp(1) - e.p.z = gfP{0} - e.p.t = gfP{0} - } else { - e.p.z = *newGFp(1) - e.p.t = *newGFp(1) - - if !e.p.IsOnCurve() { - return nil, errors.New("bn256: malformed point") - } - } - return m[2*numBytes:], nil -} - -// G2 is an abstract cyclic group. The zero value is suitable for use as the -// output of an operation, but cannot be used as an input. -type G2 struct { - p *twistPoint -} - -// RandomG2 returns x and g₂ˣ where x is a random, non-zero number read from r. -func RandomG2(r io.Reader) (*big.Int, *G2, error) { - k, err := randomK(r) - if err != nil { - return nil, nil, err - } - - return k, new(G2).ScalarBaseMult(k), nil -} - -func (e *G2) String() string { - return "bn256.G2" + e.p.String() -} - -// ScalarBaseMult sets e to g*k where g is the generator of the group and then -// returns out. -func (e *G2) ScalarBaseMult(k *big.Int) *G2 { - if e.p == nil { - e.p = &twistPoint{} - } - e.p.Mul(twistGen, k) - return e -} - -// ScalarMult sets e to a*k and then returns e. -func (e *G2) ScalarMult(a *G2, k *big.Int) *G2 { - if e.p == nil { - e.p = &twistPoint{} - } - e.p.Mul(a.p, k) - return e -} - -// Add sets e to a+b and then returns e. -func (e *G2) Add(a, b *G2) *G2 { - if e.p == nil { - e.p = &twistPoint{} - } - e.p.Add(a.p, b.p) - return e -} - -// Neg sets e to -a and then returns e. -func (e *G2) Neg(a *G2) *G2 { - if e.p == nil { - e.p = &twistPoint{} - } - e.p.Neg(a.p) - return e -} - -// Set sets e to a and then returns e. -func (e *G2) Set(a *G2) *G2 { - if e.p == nil { - e.p = &twistPoint{} - } - e.p.Set(a.p) - return e -} - -// Marshal converts e into a byte slice. -func (e *G2) Marshal() []byte { - // Each value is a 256-bit number. - const numBytes = 256 / 8 - - if e.p == nil { - e.p = &twistPoint{} - } - - e.p.MakeAffine() - ret := make([]byte, numBytes*4) - if e.p.IsInfinity() { - return ret - } - temp := &gfP{} - - montDecode(temp, &e.p.x.x) - temp.Marshal(ret) - montDecode(temp, &e.p.x.y) - temp.Marshal(ret[numBytes:]) - montDecode(temp, &e.p.y.x) - temp.Marshal(ret[2*numBytes:]) - montDecode(temp, &e.p.y.y) - temp.Marshal(ret[3*numBytes:]) - - return ret -} - -// Unmarshal sets e to the result of converting the output of Marshal back into -// a group element and then returns e. -func (e *G2) Unmarshal(m []byte) ([]byte, error) { - // Each value is a 256-bit number. - const numBytes = 256 / 8 - if len(m) < 4*numBytes { - return nil, errors.New("bn256: not enough data") - } - // Unmarshal the points and check their caps - if e.p == nil { - e.p = &twistPoint{} - } - var err error - if err = e.p.x.x.Unmarshal(m); err != nil { - return nil, err - } - if err = e.p.x.y.Unmarshal(m[numBytes:]); err != nil { - return nil, err - } - if err = e.p.y.x.Unmarshal(m[2*numBytes:]); err != nil { - return nil, err - } - if err = e.p.y.y.Unmarshal(m[3*numBytes:]); err != nil { - return nil, err - } - // Encode into Montgomery form and ensure it's on the curve - montEncode(&e.p.x.x, &e.p.x.x) - montEncode(&e.p.x.y, &e.p.x.y) - montEncode(&e.p.y.x, &e.p.y.x) - montEncode(&e.p.y.y, &e.p.y.y) - - if e.p.x.IsZero() && e.p.y.IsZero() { - // This is the point at infinity. - e.p.y.SetOne() - e.p.z.SetZero() - e.p.t.SetZero() - } else { - e.p.z.SetOne() - e.p.t.SetOne() - - if !e.p.IsOnCurve() { - return nil, errors.New("bn256: malformed point") - } - } - return m[4*numBytes:], nil -} - -// GT is an abstract cyclic group. The zero value is suitable for use as the -// output of an operation, but cannot be used as an input. -type GT struct { - p *gfP12 -} - -// Pair calculates an Optimal Ate pairing. -func Pair(g1 *G1, g2 *G2) *GT { - return >{optimalAte(g2.p, g1.p)} -} - -// PairingCheck calculates the Optimal Ate pairing for a set of points. -func PairingCheck(a []*G1, b []*G2) bool { - acc := new(gfP12) - acc.SetOne() - - for i := 0; i < len(a); i++ { - if a[i].p.IsInfinity() || b[i].p.IsInfinity() { - continue - } - acc.Mul(acc, miller(b[i].p, a[i].p)) - } - return finalExponentiation(acc).IsOne() -} - -// Miller applies Miller's algorithm, which is a bilinear function from the -// source groups to F_p^12. Miller(g1, g2).Finalize() is equivalent to Pair(g1, -// g2). -func Miller(g1 *G1, g2 *G2) *GT { - return >{miller(g2.p, g1.p)} -} - -func (g *GT) String() string { - return "bn256.GT" + g.p.String() -} - -// ScalarMult sets e to a*k and then returns e. -func (e *GT) ScalarMult(a *GT, k *big.Int) *GT { - if e.p == nil { - e.p = &gfP12{} - } - e.p.Exp(a.p, k) - return e -} - -// Add sets e to a+b and then returns e. -func (e *GT) Add(a, b *GT) *GT { - if e.p == nil { - e.p = &gfP12{} - } - e.p.Mul(a.p, b.p) - return e -} - -// Neg sets e to -a and then returns e. -func (e *GT) Neg(a *GT) *GT { - if e.p == nil { - e.p = &gfP12{} - } - e.p.Conjugate(a.p) - return e -} - -// Set sets e to a and then returns e. -func (e *GT) Set(a *GT) *GT { - if e.p == nil { - e.p = &gfP12{} - } - e.p.Set(a.p) - return e -} - -// Finalize is a linear function from F_p^12 to GT. -func (e *GT) Finalize() *GT { - ret := finalExponentiation(e.p) - e.p.Set(ret) - return e -} - -// Marshal converts e into a byte slice. -func (e *GT) Marshal() []byte { - // Each value is a 256-bit number. - const numBytes = 256 / 8 - - if e.p == nil { - e.p = &gfP12{} - e.p.SetOne() - } - - ret := make([]byte, numBytes*12) - temp := &gfP{} - - montDecode(temp, &e.p.x.x.x) - temp.Marshal(ret) - montDecode(temp, &e.p.x.x.y) - temp.Marshal(ret[numBytes:]) - montDecode(temp, &e.p.x.y.x) - temp.Marshal(ret[2*numBytes:]) - montDecode(temp, &e.p.x.y.y) - temp.Marshal(ret[3*numBytes:]) - montDecode(temp, &e.p.x.z.x) - temp.Marshal(ret[4*numBytes:]) - montDecode(temp, &e.p.x.z.y) - temp.Marshal(ret[5*numBytes:]) - montDecode(temp, &e.p.y.x.x) - temp.Marshal(ret[6*numBytes:]) - montDecode(temp, &e.p.y.x.y) - temp.Marshal(ret[7*numBytes:]) - montDecode(temp, &e.p.y.y.x) - temp.Marshal(ret[8*numBytes:]) - montDecode(temp, &e.p.y.y.y) - temp.Marshal(ret[9*numBytes:]) - montDecode(temp, &e.p.y.z.x) - temp.Marshal(ret[10*numBytes:]) - montDecode(temp, &e.p.y.z.y) - temp.Marshal(ret[11*numBytes:]) - - return ret -} - -// Unmarshal sets e to the result of converting the output of Marshal back into -// a group element and then returns e. -func (e *GT) Unmarshal(m []byte) ([]byte, error) { - // Each value is a 256-bit number. - const numBytes = 256 / 8 - - if len(m) < 12*numBytes { - return nil, errors.New("bn256: not enough data") - } - - if e.p == nil { - e.p = &gfP12{} - } - - var err error - if err = e.p.x.x.x.Unmarshal(m); err != nil { - return nil, err - } - if err = e.p.x.x.y.Unmarshal(m[numBytes:]); err != nil { - return nil, err - } - if err = e.p.x.y.x.Unmarshal(m[2*numBytes:]); err != nil { - return nil, err - } - if err = e.p.x.y.y.Unmarshal(m[3*numBytes:]); err != nil { - return nil, err - } - if err = e.p.x.z.x.Unmarshal(m[4*numBytes:]); err != nil { - return nil, err - } - if err = e.p.x.z.y.Unmarshal(m[5*numBytes:]); err != nil { - return nil, err - } - if err = e.p.y.x.x.Unmarshal(m[6*numBytes:]); err != nil { - return nil, err - } - if err = e.p.y.x.y.Unmarshal(m[7*numBytes:]); err != nil { - return nil, err - } - if err = e.p.y.y.x.Unmarshal(m[8*numBytes:]); err != nil { - return nil, err - } - if err = e.p.y.y.y.Unmarshal(m[9*numBytes:]); err != nil { - return nil, err - } - if err = e.p.y.z.x.Unmarshal(m[10*numBytes:]); err != nil { - return nil, err - } - if err = e.p.y.z.y.Unmarshal(m[11*numBytes:]); err != nil { - return nil, err - } - montEncode(&e.p.x.x.x, &e.p.x.x.x) - montEncode(&e.p.x.x.y, &e.p.x.x.y) - montEncode(&e.p.x.y.x, &e.p.x.y.x) - montEncode(&e.p.x.y.y, &e.p.x.y.y) - montEncode(&e.p.x.z.x, &e.p.x.z.x) - montEncode(&e.p.x.z.y, &e.p.x.z.y) - montEncode(&e.p.y.x.x, &e.p.y.x.x) - montEncode(&e.p.y.x.y, &e.p.y.x.y) - montEncode(&e.p.y.y.x, &e.p.y.y.x) - montEncode(&e.p.y.y.y, &e.p.y.y.y) - montEncode(&e.p.y.z.x, &e.p.y.z.x) - montEncode(&e.p.y.z.y, &e.p.y.z.y) - - return m[12*numBytes:], nil -} diff --git a/crypto/bn256/cloudflare/bn256_test.go b/crypto/bn256/cloudflare/bn256_test.go deleted file mode 100644 index 0c8016d86c..0000000000 --- a/crypto/bn256/cloudflare/bn256_test.go +++ /dev/null @@ -1,116 +0,0 @@ -package bn256 - -import ( - "bytes" - "crypto/rand" - "testing" -) - -func TestG1Marshal(t *testing.T) { - _, Ga, err := RandomG1(rand.Reader) - if err != nil { - t.Fatal(err) - } - ma := Ga.Marshal() - - Gb := new(G1) - _, err = Gb.Unmarshal(ma) - if err != nil { - t.Fatal(err) - } - mb := Gb.Marshal() - - if !bytes.Equal(ma, mb) { - t.Fatal("bytes are different") - } -} - -func TestG2Marshal(t *testing.T) { - _, Ga, err := RandomG2(rand.Reader) - if err != nil { - t.Fatal(err) - } - ma := Ga.Marshal() - - Gb := new(G2) - _, err = Gb.Unmarshal(ma) - if err != nil { - t.Fatal(err) - } - mb := Gb.Marshal() - - if !bytes.Equal(ma, mb) { - t.Fatal("bytes are different") - } -} - -func TestBilinearity(t *testing.T) { - for i := 0; i < 2; i++ { - a, p1, _ := RandomG1(rand.Reader) - b, p2, _ := RandomG2(rand.Reader) - e1 := Pair(p1, p2) - - e2 := Pair(&G1{curveGen}, &G2{twistGen}) - e2.ScalarMult(e2, a) - e2.ScalarMult(e2, b) - - if *e1.p != *e2.p { - t.Fatalf("bad pairing result: %s", e1) - } - } -} - -func TestTripartiteDiffieHellman(t *testing.T) { - a, _ := rand.Int(rand.Reader, Order) - b, _ := rand.Int(rand.Reader, Order) - c, _ := rand.Int(rand.Reader, Order) - - pa, pb, pc := new(G1), new(G1), new(G1) - qa, qb, qc := new(G2), new(G2), new(G2) - - pa.Unmarshal(new(G1).ScalarBaseMult(a).Marshal()) - qa.Unmarshal(new(G2).ScalarBaseMult(a).Marshal()) - pb.Unmarshal(new(G1).ScalarBaseMult(b).Marshal()) - qb.Unmarshal(new(G2).ScalarBaseMult(b).Marshal()) - pc.Unmarshal(new(G1).ScalarBaseMult(c).Marshal()) - qc.Unmarshal(new(G2).ScalarBaseMult(c).Marshal()) - - k1 := Pair(pb, qc) - k1.ScalarMult(k1, a) - k1Bytes := k1.Marshal() - - k2 := Pair(pc, qa) - k2.ScalarMult(k2, b) - k2Bytes := k2.Marshal() - - k3 := Pair(pa, qb) - k3.ScalarMult(k3, c) - k3Bytes := k3.Marshal() - - if !bytes.Equal(k1Bytes, k2Bytes) || !bytes.Equal(k2Bytes, k3Bytes) { - t.Errorf("keys didn't agree") - } -} - -func BenchmarkG1(b *testing.B) { - x, _ := rand.Int(rand.Reader, Order) - b.ResetTimer() - - for i := 0; i < b.N; i++ { - new(G1).ScalarBaseMult(x) - } -} - -func BenchmarkG2(b *testing.B) { - x, _ := rand.Int(rand.Reader, Order) - b.ResetTimer() - - for i := 0; i < b.N; i++ { - new(G2).ScalarBaseMult(x) - } -} -func BenchmarkPairing(b *testing.B) { - for i := 0; i < b.N; i++ { - Pair(&G1{curveGen}, &G2{twistGen}) - } -} diff --git a/crypto/bn256/cloudflare/constants.go b/crypto/bn256/cloudflare/constants.go deleted file mode 100644 index f7d2c7c001..0000000000 --- a/crypto/bn256/cloudflare/constants.go +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package bn256 - -import ( - "math/big" -) - -func bigFromBase10(s string) *big.Int { - n, _ := new(big.Int).SetString(s, 10) - return n -} - -// u is the BN parameter. -var u = bigFromBase10("4965661367192848881") - -// Order is the number of elements in both G₁ and G₂: 36u⁴+36u³+18u²+6u+1. -// Needs to be highly 2-adic for efficient SNARK key and proof generation. -// Order - 1 = 2^28 * 3^2 * 13 * 29 * 983 * 11003 * 237073 * 405928799 * 1670836401704629 * 13818364434197438864469338081. -// Refer to https://eprint.iacr.org/2013/879.pdf and https://eprint.iacr.org/2013/507.pdf for more information on these parameters. -var Order = bigFromBase10("21888242871839275222246405745257275088548364400416034343698204186575808495617") - -// P is a prime over which we form a basic field: 36u⁴+36u³+24u²+6u+1. -var P = bigFromBase10("21888242871839275222246405745257275088696311157297823662689037894645226208583") - -// p2 is p, represented as little-endian 64-bit words. -var p2 = [4]uint64{0x3c208c16d87cfd47, 0x97816a916871ca8d, 0xb85045b68181585d, 0x30644e72e131a029} - -// np is the negative inverse of p, mod 2^256. -var np = [4]uint64{0x87d20782e4866389, 0x9ede7d651eca6ac9, 0xd8afcbd01833da80, 0xf57a22b791888c6b} - -// rN1 is R^-1 where R = 2^256 mod p. -var rN1 = &gfP{0xed84884a014afa37, 0xeb2022850278edf8, 0xcf63e9cfb74492d9, 0x2e67157159e5c639} - -// r2 is R^2 where R = 2^256 mod p. -var r2 = &gfP{0xf32cfc5b538afa89, 0xb5e71911d44501fb, 0x47ab1eff0a417ff6, 0x06d89f71cab8351f} - -// r3 is R^3 where R = 2^256 mod p. -var r3 = &gfP{0xb1cd6dafda1530df, 0x62f210e6a7283db6, 0xef7f0b0c0ada0afb, 0x20fd6e902d592544} - -// xiToPMinus1Over6 is ξ^((p-1)/6) where ξ = i+9. -var xiToPMinus1Over6 = &gfP2{gfP{0xa222ae234c492d72, 0xd00f02a4565de15b, 0xdc2ff3a253dfc926, 0x10a75716b3899551}, gfP{0xaf9ba69633144907, 0xca6b1d7387afb78a, 0x11bded5ef08a2087, 0x02f34d751a1f3a7c}} - -// xiToPMinus1Over3 is ξ^((p-1)/3) where ξ = i+9. -var xiToPMinus1Over3 = &gfP2{gfP{0x6e849f1ea0aa4757, 0xaa1c7b6d89f89141, 0xb6e713cdfae0ca3a, 0x26694fbb4e82ebc3}, gfP{0xb5773b104563ab30, 0x347f91c8a9aa6454, 0x7a007127242e0991, 0x1956bcd8118214ec}} - -// xiToPMinus1Over2 is ξ^((p-1)/2) where ξ = i+9. -var xiToPMinus1Over2 = &gfP2{gfP{0xa1d77ce45ffe77c7, 0x07affd117826d1db, 0x6d16bd27bb7edc6b, 0x2c87200285defecc}, gfP{0xe4bbdd0c2936b629, 0xbb30f162e133bacb, 0x31a9d1b6f9645366, 0x253570bea500f8dd}} - -// xiToPSquaredMinus1Over3 is ξ^((p²-1)/3) where ξ = i+9. -var xiToPSquaredMinus1Over3 = &gfP{0x3350c88e13e80b9c, 0x7dce557cdb5e56b9, 0x6001b4b8b615564a, 0x2682e617020217e0} - -// xiTo2PSquaredMinus2Over3 is ξ^((2p²-2)/3) where ξ = i+9 (a cubic root of unity, mod p). -var xiTo2PSquaredMinus2Over3 = &gfP{0x71930c11d782e155, 0xa6bb947cffbe3323, 0xaa303344d4741444, 0x2c3b3f0d26594943} - -// xiToPSquaredMinus1Over6 is ξ^((1p²-1)/6) where ξ = i+9 (a cubic root of -1, mod p). -var xiToPSquaredMinus1Over6 = &gfP{0xca8d800500fa1bf2, 0xf0c5d61468b39769, 0x0e201271ad0d4418, 0x04290f65bad856e6} - -// xiTo2PMinus2Over3 is ξ^((2p-2)/3) where ξ = i+9. -var xiTo2PMinus2Over3 = &gfP2{gfP{0x5dddfd154bd8c949, 0x62cb29a5a4445b60, 0x37bc870a0c7dd2b9, 0x24830a9d3171f0fd}, gfP{0x7361d77f843abe92, 0xa5bb2bd3273411fb, 0x9c941f314b3e2399, 0x15df9cddbb9fd3ec}} diff --git a/crypto/bn256/cloudflare/curve.go b/crypto/bn256/cloudflare/curve.go deleted file mode 100644 index 18e9b38f3f..0000000000 --- a/crypto/bn256/cloudflare/curve.go +++ /dev/null @@ -1,238 +0,0 @@ -package bn256 - -import ( - "math/big" -) - -// curvePoint implements the elliptic curve y²=x³+3. Points are kept in Jacobian -// form and t=z² when valid. G₁ is the set of points of this curve on GF(p). -type curvePoint struct { - x, y, z, t gfP -} - -var curveB = newGFp(3) - -// curveGen is the generator of G₁. -var curveGen = &curvePoint{ - x: *newGFp(1), - y: *newGFp(2), - z: *newGFp(1), - t: *newGFp(1), -} - -func (c *curvePoint) String() string { - c.MakeAffine() - x, y := &gfP{}, &gfP{} - montDecode(x, &c.x) - montDecode(y, &c.y) - return "(" + x.String() + ", " + y.String() + ")" -} - -func (c *curvePoint) Set(a *curvePoint) { - c.x.Set(&a.x) - c.y.Set(&a.y) - c.z.Set(&a.z) - c.t.Set(&a.t) -} - -// IsOnCurve returns true iff c is on the curve. -func (c *curvePoint) IsOnCurve() bool { - c.MakeAffine() - if c.IsInfinity() { - return true - } - - y2, x3 := &gfP{}, &gfP{} - gfpMul(y2, &c.y, &c.y) - gfpMul(x3, &c.x, &c.x) - gfpMul(x3, x3, &c.x) - gfpAdd(x3, x3, curveB) - - return *y2 == *x3 -} - -func (c *curvePoint) SetInfinity() { - c.x = gfP{0} - c.y = *newGFp(1) - c.z = gfP{0} - c.t = gfP{0} -} - -func (c *curvePoint) IsInfinity() bool { - return c.z == gfP{0} -} - -func (c *curvePoint) Add(a, b *curvePoint) { - if a.IsInfinity() { - c.Set(b) - return - } - if b.IsInfinity() { - c.Set(a) - return - } - - // See http://hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/addition/add-2007-bl.op3 - - // Normalize the points by replacing a = [x1:y1:z1] and b = [x2:y2:z2] - // by [u1:s1:z1·z2] and [u2:s2:z1·z2] - // where u1 = x1·z2², s1 = y1·z2³ and u1 = x2·z1², s2 = y2·z1³ - z12, z22 := &gfP{}, &gfP{} - gfpMul(z12, &a.z, &a.z) - gfpMul(z22, &b.z, &b.z) - - u1, u2 := &gfP{}, &gfP{} - gfpMul(u1, &a.x, z22) - gfpMul(u2, &b.x, z12) - - t, s1 := &gfP{}, &gfP{} - gfpMul(t, &b.z, z22) - gfpMul(s1, &a.y, t) - - s2 := &gfP{} - gfpMul(t, &a.z, z12) - gfpMul(s2, &b.y, t) - - // Compute x = (2h)²(s²-u1-u2) - // where s = (s2-s1)/(u2-u1) is the slope of the line through - // (u1,s1) and (u2,s2). The extra factor 2h = 2(u2-u1) comes from the value of z below. - // This is also: - // 4(s2-s1)² - 4h²(u1+u2) = 4(s2-s1)² - 4h³ - 4h²(2u1) - // = r² - j - 2v - // with the notations below. - h := &gfP{} - gfpSub(h, u2, u1) - xEqual := *h == gfP{0} - - gfpAdd(t, h, h) - // i = 4h² - i := &gfP{} - gfpMul(i, t, t) - // j = 4h³ - j := &gfP{} - gfpMul(j, h, i) - - gfpSub(t, s2, s1) - yEqual := *t == gfP{0} - if xEqual && yEqual { - c.Double(a) - return - } - r := &gfP{} - gfpAdd(r, t, t) - - v := &gfP{} - gfpMul(v, u1, i) - - // t4 = 4(s2-s1)² - t4, t6 := &gfP{}, &gfP{} - gfpMul(t4, r, r) - gfpAdd(t, v, v) - gfpSub(t6, t4, j) - - gfpSub(&c.x, t6, t) - - // Set y = -(2h)³(s1 + s*(x/4h²-u1)) - // This is also - // y = - 2·s1·j - (s2-s1)(2x - 2i·u1) = r(v-x) - 2·s1·j - gfpSub(t, v, &c.x) // t7 - gfpMul(t4, s1, j) // t8 - gfpAdd(t6, t4, t4) // t9 - gfpMul(t4, r, t) // t10 - gfpSub(&c.y, t4, t6) - - // Set z = 2(u2-u1)·z1·z2 = 2h·z1·z2 - gfpAdd(t, &a.z, &b.z) // t11 - gfpMul(t4, t, t) // t12 - gfpSub(t, t4, z12) // t13 - gfpSub(t4, t, z22) // t14 - gfpMul(&c.z, t4, h) -} - -func (c *curvePoint) Double(a *curvePoint) { - // See http://hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/doubling/dbl-2009-l.op3 - A, B, C := &gfP{}, &gfP{}, &gfP{} - gfpMul(A, &a.x, &a.x) - gfpMul(B, &a.y, &a.y) - gfpMul(C, B, B) - - t, t2 := &gfP{}, &gfP{} - gfpAdd(t, &a.x, B) - gfpMul(t2, t, t) - gfpSub(t, t2, A) - gfpSub(t2, t, C) - - d, e, f := &gfP{}, &gfP{}, &gfP{} - gfpAdd(d, t2, t2) - gfpAdd(t, A, A) - gfpAdd(e, t, A) - gfpMul(f, e, e) - - gfpAdd(t, d, d) - gfpSub(&c.x, f, t) - - gfpAdd(t, C, C) - gfpAdd(t2, t, t) - gfpAdd(t, t2, t2) - gfpSub(&c.y, d, &c.x) - gfpMul(t2, e, &c.y) - gfpSub(&c.y, t2, t) - - gfpMul(t, &a.y, &a.z) - gfpAdd(&c.z, t, t) -} - -func (c *curvePoint) Mul(a *curvePoint, scalar *big.Int) { - precomp := [1 << 2]*curvePoint{nil, {}, {}, {}} - precomp[1].Set(a) - precomp[2].Set(a) - gfpMul(&precomp[2].x, &precomp[2].x, xiTo2PSquaredMinus2Over3) - precomp[3].Add(precomp[1], precomp[2]) - - multiScalar := curveLattice.Multi(scalar) - - sum := &curvePoint{} - sum.SetInfinity() - t := &curvePoint{} - - for i := len(multiScalar) - 1; i >= 0; i-- { - t.Double(sum) - if multiScalar[i] == 0 { - sum.Set(t) - } else { - sum.Add(t, precomp[multiScalar[i]]) - } - } - c.Set(sum) -} - -func (c *curvePoint) MakeAffine() { - if c.z == *newGFp(1) { - return - } else if c.z == *newGFp(0) { - c.x = gfP{0} - c.y = *newGFp(1) - c.t = gfP{0} - return - } - - zInv := &gfP{} - zInv.Invert(&c.z) - - t, zInv2 := &gfP{}, &gfP{} - gfpMul(t, &c.y, zInv) - gfpMul(zInv2, zInv, zInv) - - gfpMul(&c.x, &c.x, zInv2) - gfpMul(&c.y, t, zInv2) - - c.z = *newGFp(1) - c.t = *newGFp(1) -} - -func (c *curvePoint) Neg(a *curvePoint) { - c.x.Set(&a.x) - gfpNeg(&c.y, &a.y) - c.z.Set(&a.z) - c.t = gfP{0} -} diff --git a/crypto/bn256/cloudflare/example_test.go b/crypto/bn256/cloudflare/example_test.go deleted file mode 100644 index 6c285995cb..0000000000 --- a/crypto/bn256/cloudflare/example_test.go +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package bn256 - -import ( - "crypto/rand" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestExamplePair(t *testing.T) { - // This implements the tripartite Diffie-Hellman algorithm from "A One - // Round Protocol for Tripartite Diffie-Hellman", A. Joux. - // http://www.springerlink.com/content/cddc57yyva0hburb/fulltext.pdf - - // Each of three parties, a, b and c, generate a private value. - a, _ := rand.Int(rand.Reader, Order) - b, _ := rand.Int(rand.Reader, Order) - c, _ := rand.Int(rand.Reader, Order) - - // Then each party calculates g₁ and g₂ times their private value. - pa := new(G1).ScalarBaseMult(a) - qa := new(G2).ScalarBaseMult(a) - - pb := new(G1).ScalarBaseMult(b) - qb := new(G2).ScalarBaseMult(b) - - pc := new(G1).ScalarBaseMult(c) - qc := new(G2).ScalarBaseMult(c) - - // Now each party exchanges its public values with the other two and - // all parties can calculate the shared key. - k1 := Pair(pb, qc) - k1.ScalarMult(k1, a) - - k2 := Pair(pc, qa) - k2.ScalarMult(k2, b) - - k3 := Pair(pa, qb) - k3.ScalarMult(k3, c) - - // k1, k2 and k3 will all be equal. - - require.Equal(t, k1, k2) - require.Equal(t, k1, k3) - - require.Equal(t, len(np), 4) //Avoid gometalinter varcheck err on np -} diff --git a/crypto/bn256/cloudflare/gfp.go b/crypto/bn256/cloudflare/gfp.go deleted file mode 100644 index e8e84e7b3b..0000000000 --- a/crypto/bn256/cloudflare/gfp.go +++ /dev/null @@ -1,81 +0,0 @@ -package bn256 - -import ( - "errors" - "fmt" -) - -type gfP [4]uint64 - -func newGFp(x int64) (out *gfP) { - if x >= 0 { - out = &gfP{uint64(x)} - } else { - out = &gfP{uint64(-x)} - gfpNeg(out, out) - } - - montEncode(out, out) - return out -} - -func (e *gfP) String() string { - return fmt.Sprintf("%16.16x%16.16x%16.16x%16.16x", e[3], e[2], e[1], e[0]) -} - -func (e *gfP) Set(f *gfP) { - e[0] = f[0] - e[1] = f[1] - e[2] = f[2] - e[3] = f[3] -} - -func (e *gfP) Invert(f *gfP) { - bits := [4]uint64{0x3c208c16d87cfd45, 0x97816a916871ca8d, 0xb85045b68181585d, 0x30644e72e131a029} - - sum, power := &gfP{}, &gfP{} - sum.Set(rN1) - power.Set(f) - - for word := 0; word < 4; word++ { - for bit := uint(0); bit < 64; bit++ { - if (bits[word]>>bit)&1 == 1 { - gfpMul(sum, sum, power) - } - gfpMul(power, power, power) - } - } - - gfpMul(sum, sum, r3) - e.Set(sum) -} - -func (e *gfP) Marshal(out []byte) { - for w := uint(0); w < 4; w++ { - for b := uint(0); b < 8; b++ { - out[8*w+b] = byte(e[3-w] >> (56 - 8*b)) - } - } -} - -func (e *gfP) Unmarshal(in []byte) error { - // Unmarshal the bytes into little endian form - for w := uint(0); w < 4; w++ { - for b := uint(0); b < 8; b++ { - e[3-w] += uint64(in[8*w+b]) << (56 - 8*b) - } - } - // Ensure the point respects the curve modulus - for i := 3; i >= 0; i-- { - if e[i] < p2[i] { - return nil - } - if e[i] > p2[i] { - return errors.New("bn256: coordinate exceeds modulus") - } - } - return errors.New("bn256: coordinate equals modulus") -} - -func montEncode(c, a *gfP) { gfpMul(c, a, r2) } -func montDecode(c, a *gfP) { gfpMul(c, a, &gfP{1}) } diff --git a/crypto/bn256/cloudflare/gfp12.go b/crypto/bn256/cloudflare/gfp12.go deleted file mode 100644 index 93fb368a7b..0000000000 --- a/crypto/bn256/cloudflare/gfp12.go +++ /dev/null @@ -1,160 +0,0 @@ -package bn256 - -// For details of the algorithms used, see "Multiplication and Squaring on -// Pairing-Friendly Fields, Devegili et al. -// http://eprint.iacr.org/2006/471.pdf. - -import ( - "math/big" -) - -// gfP12 implements the field of size p¹² as a quadratic extension of gfP6 -// where ω²=τ. -type gfP12 struct { - x, y gfP6 // value is xω + y -} - -func (e *gfP12) String() string { - return "(" + e.x.String() + "," + e.y.String() + ")" -} - -func (e *gfP12) Set(a *gfP12) *gfP12 { - e.x.Set(&a.x) - e.y.Set(&a.y) - return e -} - -func (e *gfP12) SetZero() *gfP12 { - e.x.SetZero() - e.y.SetZero() - return e -} - -func (e *gfP12) SetOne() *gfP12 { - e.x.SetZero() - e.y.SetOne() - return e -} - -func (e *gfP12) IsZero() bool { - return e.x.IsZero() && e.y.IsZero() -} - -func (e *gfP12) IsOne() bool { - return e.x.IsZero() && e.y.IsOne() -} - -func (e *gfP12) Conjugate(a *gfP12) *gfP12 { - e.x.Neg(&a.x) - e.y.Set(&a.y) - return e -} - -func (e *gfP12) Neg(a *gfP12) *gfP12 { - e.x.Neg(&a.x) - e.y.Neg(&a.y) - return e -} - -// Frobenius computes (xω+y)^p = x^p ω·ξ^((p-1)/6) + y^p -func (e *gfP12) Frobenius(a *gfP12) *gfP12 { - e.x.Frobenius(&a.x) - e.y.Frobenius(&a.y) - e.x.MulScalar(&e.x, xiToPMinus1Over6) - return e -} - -// FrobeniusP2 computes (xω+y)^p² = x^p² ω·ξ^((p²-1)/6) + y^p² -func (e *gfP12) FrobeniusP2(a *gfP12) *gfP12 { - e.x.FrobeniusP2(&a.x) - e.x.MulGFP(&e.x, xiToPSquaredMinus1Over6) - e.y.FrobeniusP2(&a.y) - return e -} - -func (e *gfP12) FrobeniusP4(a *gfP12) *gfP12 { - e.x.FrobeniusP4(&a.x) - e.x.MulGFP(&e.x, xiToPSquaredMinus1Over3) - e.y.FrobeniusP4(&a.y) - return e -} - -func (e *gfP12) Add(a, b *gfP12) *gfP12 { - e.x.Add(&a.x, &b.x) - e.y.Add(&a.y, &b.y) - return e -} - -func (e *gfP12) Sub(a, b *gfP12) *gfP12 { - e.x.Sub(&a.x, &b.x) - e.y.Sub(&a.y, &b.y) - return e -} - -func (e *gfP12) Mul(a, b *gfP12) *gfP12 { - tx := (&gfP6{}).Mul(&a.x, &b.y) - t := (&gfP6{}).Mul(&b.x, &a.y) - tx.Add(tx, t) - - ty := (&gfP6{}).Mul(&a.y, &b.y) - t.Mul(&a.x, &b.x).MulTau(t) - - e.x.Set(tx) - e.y.Add(ty, t) - return e -} - -func (e *gfP12) MulScalar(a *gfP12, b *gfP6) *gfP12 { - e.x.Mul(&e.x, b) - e.y.Mul(&e.y, b) - return e -} - -func (c *gfP12) Exp(a *gfP12, power *big.Int) *gfP12 { - sum := (&gfP12{}).SetOne() - t := &gfP12{} - - for i := power.BitLen() - 1; i >= 0; i-- { - t.Square(sum) - if power.Bit(i) != 0 { - sum.Mul(t, a) - } else { - sum.Set(t) - } - } - - c.Set(sum) - return c -} - -func (e *gfP12) Square(a *gfP12) *gfP12 { - // Complex squaring algorithm - v0 := (&gfP6{}).Mul(&a.x, &a.y) - - t := (&gfP6{}).MulTau(&a.x) - t.Add(&a.y, t) - ty := (&gfP6{}).Add(&a.x, &a.y) - ty.Mul(ty, t).Sub(ty, v0) - t.MulTau(v0) - ty.Sub(ty, t) - - e.x.Add(v0, v0) - e.y.Set(ty) - return e -} - -func (e *gfP12) Invert(a *gfP12) *gfP12 { - // See "Implementing cryptographic pairings", M. Scott, section 3.2. - // ftp://136.206.11.249/pub/crypto/pairings.pdf - t1, t2 := &gfP6{}, &gfP6{} - - t1.Square(&a.x) - t2.Square(&a.y) - t1.MulTau(t1).Sub(t2, t1) - t2.Invert(t1) - - e.x.Neg(&a.x) - e.y.Set(&a.y) - e.MulScalar(e, t2) - return e -} diff --git a/crypto/bn256/cloudflare/gfp2.go b/crypto/bn256/cloudflare/gfp2.go deleted file mode 100644 index 90a89e8b47..0000000000 --- a/crypto/bn256/cloudflare/gfp2.go +++ /dev/null @@ -1,156 +0,0 @@ -package bn256 - -// For details of the algorithms used, see "Multiplication and Squaring on -// Pairing-Friendly Fields, Devegili et al. -// http://eprint.iacr.org/2006/471.pdf. - -// gfP2 implements a field of size p² as a quadratic extension of the base field -// where i²=-1. -type gfP2 struct { - x, y gfP // value is xi+y. -} - -func gfP2Decode(in *gfP2) *gfP2 { - out := &gfP2{} - montDecode(&out.x, &in.x) - montDecode(&out.y, &in.y) - return out -} - -func (e *gfP2) String() string { - return "(" + e.x.String() + ", " + e.y.String() + ")" -} - -func (e *gfP2) Set(a *gfP2) *gfP2 { - e.x.Set(&a.x) - e.y.Set(&a.y) - return e -} - -func (e *gfP2) SetZero() *gfP2 { - e.x = gfP{0} - e.y = gfP{0} - return e -} - -func (e *gfP2) SetOne() *gfP2 { - e.x = gfP{0} - e.y = *newGFp(1) - return e -} - -func (e *gfP2) IsZero() bool { - zero := gfP{0} - return e.x == zero && e.y == zero -} - -func (e *gfP2) IsOne() bool { - zero, one := gfP{0}, *newGFp(1) - return e.x == zero && e.y == one -} - -func (e *gfP2) Conjugate(a *gfP2) *gfP2 { - e.y.Set(&a.y) - gfpNeg(&e.x, &a.x) - return e -} - -func (e *gfP2) Neg(a *gfP2) *gfP2 { - gfpNeg(&e.x, &a.x) - gfpNeg(&e.y, &a.y) - return e -} - -func (e *gfP2) Add(a, b *gfP2) *gfP2 { - gfpAdd(&e.x, &a.x, &b.x) - gfpAdd(&e.y, &a.y, &b.y) - return e -} - -func (e *gfP2) Sub(a, b *gfP2) *gfP2 { - gfpSub(&e.x, &a.x, &b.x) - gfpSub(&e.y, &a.y, &b.y) - return e -} - -// See "Multiplication and Squaring in Pairing-Friendly Fields", -// http://eprint.iacr.org/2006/471.pdf -func (e *gfP2) Mul(a, b *gfP2) *gfP2 { - tx, t := &gfP{}, &gfP{} - gfpMul(tx, &a.x, &b.y) - gfpMul(t, &b.x, &a.y) - gfpAdd(tx, tx, t) - - ty := &gfP{} - gfpMul(ty, &a.y, &b.y) - gfpMul(t, &a.x, &b.x) - gfpSub(ty, ty, t) - - e.x.Set(tx) - e.y.Set(ty) - return e -} - -func (e *gfP2) MulScalar(a *gfP2, b *gfP) *gfP2 { - gfpMul(&e.x, &a.x, b) - gfpMul(&e.y, &a.y, b) - return e -} - -// MulXi sets e=ξa where ξ=i+9 and then returns e. -func (e *gfP2) MulXi(a *gfP2) *gfP2 { - // (xi+y)(i+9) = (9x+y)i+(9y-x) - tx := &gfP{} - gfpAdd(tx, &a.x, &a.x) - gfpAdd(tx, tx, tx) - gfpAdd(tx, tx, tx) - gfpAdd(tx, tx, &a.x) - - gfpAdd(tx, tx, &a.y) - - ty := &gfP{} - gfpAdd(ty, &a.y, &a.y) - gfpAdd(ty, ty, ty) - gfpAdd(ty, ty, ty) - gfpAdd(ty, ty, &a.y) - - gfpSub(ty, ty, &a.x) - - e.x.Set(tx) - e.y.Set(ty) - return e -} - -func (e *gfP2) Square(a *gfP2) *gfP2 { - // Complex squaring algorithm: - // (xi+y)² = (x+y)(y-x) + 2*i*x*y - tx, ty := &gfP{}, &gfP{} - gfpSub(tx, &a.y, &a.x) - gfpAdd(ty, &a.x, &a.y) - gfpMul(ty, tx, ty) - - gfpMul(tx, &a.x, &a.y) - gfpAdd(tx, tx, tx) - - e.x.Set(tx) - e.y.Set(ty) - return e -} - -func (e *gfP2) Invert(a *gfP2) *gfP2 { - // See "Implementing cryptographic pairings", M. Scott, section 3.2. - // ftp://136.206.11.249/pub/crypto/pairings.pdf - t1, t2 := &gfP{}, &gfP{} - gfpMul(t1, &a.x, &a.x) - gfpMul(t2, &a.y, &a.y) - gfpAdd(t1, t1, t2) - - inv := &gfP{} - inv.Invert(t1) - - gfpNeg(t1, &a.x) - - gfpMul(&e.x, t1, inv) - gfpMul(&e.y, &a.y, inv) - return e -} diff --git a/crypto/bn256/cloudflare/gfp6.go b/crypto/bn256/cloudflare/gfp6.go deleted file mode 100644 index a42734911c..0000000000 --- a/crypto/bn256/cloudflare/gfp6.go +++ /dev/null @@ -1,213 +0,0 @@ -package bn256 - -// For details of the algorithms used, see "Multiplication and Squaring on -// Pairing-Friendly Fields, Devegili et al. -// http://eprint.iacr.org/2006/471.pdf. - -// gfP6 implements the field of size p⁶ as a cubic extension of gfP2 where τ³=ξ -// and ξ=i+9. -type gfP6 struct { - x, y, z gfP2 // value is xτ² + yτ + z -} - -func (e *gfP6) String() string { - return "(" + e.x.String() + ", " + e.y.String() + ", " + e.z.String() + ")" -} - -func (e *gfP6) Set(a *gfP6) *gfP6 { - e.x.Set(&a.x) - e.y.Set(&a.y) - e.z.Set(&a.z) - return e -} - -func (e *gfP6) SetZero() *gfP6 { - e.x.SetZero() - e.y.SetZero() - e.z.SetZero() - return e -} - -func (e *gfP6) SetOne() *gfP6 { - e.x.SetZero() - e.y.SetZero() - e.z.SetOne() - return e -} - -func (e *gfP6) IsZero() bool { - return e.x.IsZero() && e.y.IsZero() && e.z.IsZero() -} - -func (e *gfP6) IsOne() bool { - return e.x.IsZero() && e.y.IsZero() && e.z.IsOne() -} - -func (e *gfP6) Neg(a *gfP6) *gfP6 { - e.x.Neg(&a.x) - e.y.Neg(&a.y) - e.z.Neg(&a.z) - return e -} - -func (e *gfP6) Frobenius(a *gfP6) *gfP6 { - e.x.Conjugate(&a.x) - e.y.Conjugate(&a.y) - e.z.Conjugate(&a.z) - - e.x.Mul(&e.x, xiTo2PMinus2Over3) - e.y.Mul(&e.y, xiToPMinus1Over3) - return e -} - -// FrobeniusP2 computes (xτ²+yτ+z)^(p²) = xτ^(2p²) + yτ^(p²) + z -func (e *gfP6) FrobeniusP2(a *gfP6) *gfP6 { - // τ^(2p²) = τ²τ^(2p²-2) = τ²ξ^((2p²-2)/3) - e.x.MulScalar(&a.x, xiTo2PSquaredMinus2Over3) - // τ^(p²) = ττ^(p²-1) = τξ^((p²-1)/3) - e.y.MulScalar(&a.y, xiToPSquaredMinus1Over3) - e.z.Set(&a.z) - return e -} - -func (e *gfP6) FrobeniusP4(a *gfP6) *gfP6 { - e.x.MulScalar(&a.x, xiToPSquaredMinus1Over3) - e.y.MulScalar(&a.y, xiTo2PSquaredMinus2Over3) - e.z.Set(&a.z) - return e -} - -func (e *gfP6) Add(a, b *gfP6) *gfP6 { - e.x.Add(&a.x, &b.x) - e.y.Add(&a.y, &b.y) - e.z.Add(&a.z, &b.z) - return e -} - -func (e *gfP6) Sub(a, b *gfP6) *gfP6 { - e.x.Sub(&a.x, &b.x) - e.y.Sub(&a.y, &b.y) - e.z.Sub(&a.z, &b.z) - return e -} - -func (e *gfP6) Mul(a, b *gfP6) *gfP6 { - // "Multiplication and Squaring on Pairing-Friendly Fields" - // Section 4, Karatsuba method. - // http://eprint.iacr.org/2006/471.pdf - v0 := (&gfP2{}).Mul(&a.z, &b.z) - v1 := (&gfP2{}).Mul(&a.y, &b.y) - v2 := (&gfP2{}).Mul(&a.x, &b.x) - - t0 := (&gfP2{}).Add(&a.x, &a.y) - t1 := (&gfP2{}).Add(&b.x, &b.y) - tz := (&gfP2{}).Mul(t0, t1) - tz.Sub(tz, v1).Sub(tz, v2).MulXi(tz).Add(tz, v0) - - t0.Add(&a.y, &a.z) - t1.Add(&b.y, &b.z) - ty := (&gfP2{}).Mul(t0, t1) - t0.MulXi(v2) - ty.Sub(ty, v0).Sub(ty, v1).Add(ty, t0) - - t0.Add(&a.x, &a.z) - t1.Add(&b.x, &b.z) - tx := (&gfP2{}).Mul(t0, t1) - tx.Sub(tx, v0).Add(tx, v1).Sub(tx, v2) - - e.x.Set(tx) - e.y.Set(ty) - e.z.Set(tz) - return e -} - -func (e *gfP6) MulScalar(a *gfP6, b *gfP2) *gfP6 { - e.x.Mul(&a.x, b) - e.y.Mul(&a.y, b) - e.z.Mul(&a.z, b) - return e -} - -func (e *gfP6) MulGFP(a *gfP6, b *gfP) *gfP6 { - e.x.MulScalar(&a.x, b) - e.y.MulScalar(&a.y, b) - e.z.MulScalar(&a.z, b) - return e -} - -// MulTau computes τ·(aτ²+bτ+c) = bτ²+cτ+aξ -func (e *gfP6) MulTau(a *gfP6) *gfP6 { - tz := (&gfP2{}).MulXi(&a.x) - ty := (&gfP2{}).Set(&a.y) - - e.y.Set(&a.z) - e.x.Set(ty) - e.z.Set(tz) - return e -} - -func (e *gfP6) Square(a *gfP6) *gfP6 { - v0 := (&gfP2{}).Square(&a.z) - v1 := (&gfP2{}).Square(&a.y) - v2 := (&gfP2{}).Square(&a.x) - - c0 := (&gfP2{}).Add(&a.x, &a.y) - c0.Square(c0).Sub(c0, v1).Sub(c0, v2).MulXi(c0).Add(c0, v0) - - c1 := (&gfP2{}).Add(&a.y, &a.z) - c1.Square(c1).Sub(c1, v0).Sub(c1, v1) - xiV2 := (&gfP2{}).MulXi(v2) - c1.Add(c1, xiV2) - - c2 := (&gfP2{}).Add(&a.x, &a.z) - c2.Square(c2).Sub(c2, v0).Add(c2, v1).Sub(c2, v2) - - e.x.Set(c2) - e.y.Set(c1) - e.z.Set(c0) - return e -} - -func (e *gfP6) Invert(a *gfP6) *gfP6 { - // See "Implementing cryptographic pairings", M. Scott, section 3.2. - // ftp://136.206.11.249/pub/crypto/pairings.pdf - - // Here we can give a short explanation of how it works: let j be a cubic root of - // unity in GF(p²) so that 1+j+j²=0. - // Then (xτ² + yτ + z)(xj²τ² + yjτ + z)(xjτ² + yj²τ + z) - // = (xτ² + yτ + z)(Cτ²+Bτ+A) - // = (x³ξ²+y³ξ+z³-3ξxyz) = F is an element of the base field (the norm). - // - // On the other hand (xj²τ² + yjτ + z)(xjτ² + yj²τ + z) - // = τ²(y²-ξxz) + τ(ξx²-yz) + (z²-ξxy) - // - // So that's why A = (z²-ξxy), B = (ξx²-yz), C = (y²-ξxz) - t1 := (&gfP2{}).Mul(&a.x, &a.y) - t1.MulXi(t1) - - A := (&gfP2{}).Square(&a.z) - A.Sub(A, t1) - - B := (&gfP2{}).Square(&a.x) - B.MulXi(B) - t1.Mul(&a.y, &a.z) - B.Sub(B, t1) - - C := (&gfP2{}).Square(&a.y) - t1.Mul(&a.x, &a.z) - C.Sub(C, t1) - - F := (&gfP2{}).Mul(C, &a.y) - F.MulXi(F) - t1.Mul(A, &a.z) - F.Add(F, t1) - t1.Mul(B, &a.x).MulXi(t1) - F.Add(F, t1) - - F.Invert(F) - - e.x.Mul(C, F) - e.y.Mul(B, F) - e.z.Mul(A, F) - return e -} diff --git a/crypto/bn256/cloudflare/gfp_amd64.s b/crypto/bn256/cloudflare/gfp_amd64.s deleted file mode 100644 index bdb4ffb787..0000000000 --- a/crypto/bn256/cloudflare/gfp_amd64.s +++ /dev/null @@ -1,129 +0,0 @@ -// +build amd64,!generic - -#define storeBlock(a0,a1,a2,a3, r) \ - MOVQ a0, 0+r \ - MOVQ a1, 8+r \ - MOVQ a2, 16+r \ - MOVQ a3, 24+r - -#define loadBlock(r, a0,a1,a2,a3) \ - MOVQ 0+r, a0 \ - MOVQ 8+r, a1 \ - MOVQ 16+r, a2 \ - MOVQ 24+r, a3 - -#define gfpCarry(a0,a1,a2,a3,a4, b0,b1,b2,b3,b4) \ - \ // b = a-p - MOVQ a0, b0 \ - MOVQ a1, b1 \ - MOVQ a2, b2 \ - MOVQ a3, b3 \ - MOVQ a4, b4 \ - \ - SUBQ ·p2+0(SB), b0 \ - SBBQ ·p2+8(SB), b1 \ - SBBQ ·p2+16(SB), b2 \ - SBBQ ·p2+24(SB), b3 \ - SBBQ $0, b4 \ - \ - \ // if b is negative then return a - \ // else return b - CMOVQCC b0, a0 \ - CMOVQCC b1, a1 \ - CMOVQCC b2, a2 \ - CMOVQCC b3, a3 - -#include "mul_amd64.h" -#include "mul_bmi2_amd64.h" - -TEXT ·gfpNeg(SB),0,$0-16 - MOVQ ·p2+0(SB), R8 - MOVQ ·p2+8(SB), R9 - MOVQ ·p2+16(SB), R10 - MOVQ ·p2+24(SB), R11 - - MOVQ a+8(FP), DI - SUBQ 0(DI), R8 - SBBQ 8(DI), R9 - SBBQ 16(DI), R10 - SBBQ 24(DI), R11 - - MOVQ $0, AX - gfpCarry(R8,R9,R10,R11,AX, R12,R13,R14,R15,BX) - - MOVQ c+0(FP), DI - storeBlock(R8,R9,R10,R11, 0(DI)) - RET - -TEXT ·gfpAdd(SB),0,$0-24 - MOVQ a+8(FP), DI - MOVQ b+16(FP), SI - - loadBlock(0(DI), R8,R9,R10,R11) - MOVQ $0, R12 - - ADDQ 0(SI), R8 - ADCQ 8(SI), R9 - ADCQ 16(SI), R10 - ADCQ 24(SI), R11 - ADCQ $0, R12 - - gfpCarry(R8,R9,R10,R11,R12, R13,R14,R15,AX,BX) - - MOVQ c+0(FP), DI - storeBlock(R8,R9,R10,R11, 0(DI)) - RET - -TEXT ·gfpSub(SB),0,$0-24 - MOVQ a+8(FP), DI - MOVQ b+16(FP), SI - - loadBlock(0(DI), R8,R9,R10,R11) - - MOVQ ·p2+0(SB), R12 - MOVQ ·p2+8(SB), R13 - MOVQ ·p2+16(SB), R14 - MOVQ ·p2+24(SB), R15 - MOVQ $0, AX - - SUBQ 0(SI), R8 - SBBQ 8(SI), R9 - SBBQ 16(SI), R10 - SBBQ 24(SI), R11 - - CMOVQCC AX, R12 - CMOVQCC AX, R13 - CMOVQCC AX, R14 - CMOVQCC AX, R15 - - ADDQ R12, R8 - ADCQ R13, R9 - ADCQ R14, R10 - ADCQ R15, R11 - - MOVQ c+0(FP), DI - storeBlock(R8,R9,R10,R11, 0(DI)) - RET - -TEXT ·gfpMul(SB),0,$160-24 - MOVQ a+8(FP), DI - MOVQ b+16(FP), SI - - // Jump to a slightly different implementation if MULX isn't supported. - CMPB ·hasBMI2(SB), $0 - JE nobmi2Mul - - mulBMI2(0(DI),8(DI),16(DI),24(DI), 0(SI)) - storeBlock( R8, R9,R10,R11, 0(SP)) - storeBlock(R12,R13,R14,R15, 32(SP)) - gfpReduceBMI2() - JMP end - -nobmi2Mul: - mul(0(DI),8(DI),16(DI),24(DI), 0(SI), 0(SP)) - gfpReduce(0(SP)) - -end: - MOVQ c+0(FP), DI - storeBlock(R12,R13,R14,R15, 0(DI)) - RET diff --git a/crypto/bn256/cloudflare/gfp_arm64.s b/crypto/bn256/cloudflare/gfp_arm64.s deleted file mode 100644 index c65e80168c..0000000000 --- a/crypto/bn256/cloudflare/gfp_arm64.s +++ /dev/null @@ -1,113 +0,0 @@ -// +build arm64,!generic - -#define storeBlock(a0,a1,a2,a3, r) \ - MOVD a0, 0+r \ - MOVD a1, 8+r \ - MOVD a2, 16+r \ - MOVD a3, 24+r - -#define loadBlock(r, a0,a1,a2,a3) \ - MOVD 0+r, a0 \ - MOVD 8+r, a1 \ - MOVD 16+r, a2 \ - MOVD 24+r, a3 - -#define loadModulus(p0,p1,p2,p3) \ - MOVD ·p2+0(SB), p0 \ - MOVD ·p2+8(SB), p1 \ - MOVD ·p2+16(SB), p2 \ - MOVD ·p2+24(SB), p3 - -#include "mul_arm64.h" - -TEXT ·gfpNeg(SB),0,$0-16 - MOVD a+8(FP), R0 - loadBlock(0(R0), R1,R2,R3,R4) - loadModulus(R5,R6,R7,R8) - - SUBS R1, R5, R1 - SBCS R2, R6, R2 - SBCS R3, R7, R3 - SBCS R4, R8, R4 - - SUBS R5, R1, R5 - SBCS R6, R2, R6 - SBCS R7, R3, R7 - SBCS R8, R4, R8 - - CSEL CS, R5, R1, R1 - CSEL CS, R6, R2, R2 - CSEL CS, R7, R3, R3 - CSEL CS, R8, R4, R4 - - MOVD c+0(FP), R0 - storeBlock(R1,R2,R3,R4, 0(R0)) - RET - -TEXT ·gfpAdd(SB),0,$0-24 - MOVD a+8(FP), R0 - loadBlock(0(R0), R1,R2,R3,R4) - MOVD b+16(FP), R0 - loadBlock(0(R0), R5,R6,R7,R8) - loadModulus(R9,R10,R11,R12) - MOVD ZR, R0 - - ADDS R5, R1 - ADCS R6, R2 - ADCS R7, R3 - ADCS R8, R4 - ADCS ZR, R0 - - SUBS R9, R1, R5 - SBCS R10, R2, R6 - SBCS R11, R3, R7 - SBCS R12, R4, R8 - SBCS ZR, R0, R0 - - CSEL CS, R5, R1, R1 - CSEL CS, R6, R2, R2 - CSEL CS, R7, R3, R3 - CSEL CS, R8, R4, R4 - - MOVD c+0(FP), R0 - storeBlock(R1,R2,R3,R4, 0(R0)) - RET - -TEXT ·gfpSub(SB),0,$0-24 - MOVD a+8(FP), R0 - loadBlock(0(R0), R1,R2,R3,R4) - MOVD b+16(FP), R0 - loadBlock(0(R0), R5,R6,R7,R8) - loadModulus(R9,R10,R11,R12) - - SUBS R5, R1 - SBCS R6, R2 - SBCS R7, R3 - SBCS R8, R4 - - CSEL CS, ZR, R9, R9 - CSEL CS, ZR, R10, R10 - CSEL CS, ZR, R11, R11 - CSEL CS, ZR, R12, R12 - - ADDS R9, R1 - ADCS R10, R2 - ADCS R11, R3 - ADCS R12, R4 - - MOVD c+0(FP), R0 - storeBlock(R1,R2,R3,R4, 0(R0)) - RET - -TEXT ·gfpMul(SB),0,$0-24 - MOVD a+8(FP), R0 - loadBlock(0(R0), R1,R2,R3,R4) - MOVD b+16(FP), R0 - loadBlock(0(R0), R5,R6,R7,R8) - - mul(R9,R10,R11,R12,R13,R14,R15,R16) - gfpReduce() - - MOVD c+0(FP), R0 - storeBlock(R1,R2,R3,R4, 0(R0)) - RET diff --git a/crypto/bn256/cloudflare/gfp_decl.go b/crypto/bn256/cloudflare/gfp_decl.go deleted file mode 100644 index fdea5c11a5..0000000000 --- a/crypto/bn256/cloudflare/gfp_decl.go +++ /dev/null @@ -1,25 +0,0 @@ -// +build amd64,!generic arm64,!generic - -package bn256 - -// This file contains forward declarations for the architecture-specific -// assembly implementations of these functions, provided that they exist. - -import ( - "golang.org/x/sys/cpu" -) - -//nolint:varcheck -var hasBMI2 = cpu.X86.HasBMI2 - -// go:noescape -func gfpNeg(c, a *gfP) - -//go:noescape -func gfpAdd(c, a, b *gfP) - -//go:noescape -func gfpSub(c, a, b *gfP) - -//go:noescape -func gfpMul(c, a, b *gfP) diff --git a/crypto/bn256/cloudflare/gfp_generic.go b/crypto/bn256/cloudflare/gfp_generic.go deleted file mode 100644 index 8e6be95961..0000000000 --- a/crypto/bn256/cloudflare/gfp_generic.go +++ /dev/null @@ -1,173 +0,0 @@ -// +build !amd64,!arm64 generic - -package bn256 - -func gfpCarry(a *gfP, head uint64) { - b := &gfP{} - - var carry uint64 - for i, pi := range p2 { - ai := a[i] - bi := ai - pi - carry - b[i] = bi - carry = (pi&^ai | (pi|^ai)&bi) >> 63 - } - carry = carry &^ head - - // If b is negative, then return a. - // Else return b. - carry = -carry - ncarry := ^carry - for i := 0; i < 4; i++ { - a[i] = (a[i] & carry) | (b[i] & ncarry) - } -} - -func gfpNeg(c, a *gfP) { - var carry uint64 - for i, pi := range p2 { - ai := a[i] - ci := pi - ai - carry - c[i] = ci - carry = (ai&^pi | (ai|^pi)&ci) >> 63 - } - gfpCarry(c, 0) -} - -func gfpAdd(c, a, b *gfP) { - var carry uint64 - for i, ai := range a { - bi := b[i] - ci := ai + bi + carry - c[i] = ci - carry = (ai&bi | (ai|bi)&^ci) >> 63 - } - gfpCarry(c, carry) -} - -func gfpSub(c, a, b *gfP) { - t := &gfP{} - - var carry uint64 - for i, pi := range p2 { - bi := b[i] - ti := pi - bi - carry - t[i] = ti - carry = (bi&^pi | (bi|^pi)&ti) >> 63 - } - - carry = 0 - for i, ai := range a { - ti := t[i] - ci := ai + ti + carry - c[i] = ci - carry = (ai&ti | (ai|ti)&^ci) >> 63 - } - gfpCarry(c, carry) -} - -func mul(a, b [4]uint64) [8]uint64 { - const ( - mask16 uint64 = 0x0000ffff - mask32 uint64 = 0xffffffff - ) - - var buff [32]uint64 - for i, ai := range a { - a0, a1, a2, a3 := ai&mask16, (ai>>16)&mask16, (ai>>32)&mask16, ai>>48 - - for j, bj := range b { - b0, b2 := bj&mask32, bj>>32 - - off := 4 * (i + j) - buff[off+0] += a0 * b0 - buff[off+1] += a1 * b0 - buff[off+2] += a2*b0 + a0*b2 - buff[off+3] += a3*b0 + a1*b2 - buff[off+4] += a2 * b2 - buff[off+5] += a3 * b2 - } - } - - for i := uint(1); i < 4; i++ { - shift := 16 * i - - var head, carry uint64 - for j := uint(0); j < 8; j++ { - block := 4 * j - - xi := buff[block] - yi := (buff[block+i] << shift) + head - zi := xi + yi + carry - buff[block] = zi - carry = (xi&yi | (xi|yi)&^zi) >> 63 - - head = buff[block+i] >> (64 - shift) - } - } - - return [8]uint64{buff[0], buff[4], buff[8], buff[12], buff[16], buff[20], buff[24], buff[28]} -} - -func halfMul(a, b [4]uint64) [4]uint64 { - const ( - mask16 uint64 = 0x0000ffff - mask32 uint64 = 0xffffffff - ) - - var buff [18]uint64 - for i, ai := range a { - a0, a1, a2, a3 := ai&mask16, (ai>>16)&mask16, (ai>>32)&mask16, ai>>48 - - for j, bj := range b { - if i+j > 3 { - break - } - b0, b2 := bj&mask32, bj>>32 - - off := 4 * (i + j) - buff[off+0] += a0 * b0 - buff[off+1] += a1 * b0 - buff[off+2] += a2*b0 + a0*b2 - buff[off+3] += a3*b0 + a1*b2 - buff[off+4] += a2 * b2 - buff[off+5] += a3 * b2 - } - } - - for i := uint(1); i < 4; i++ { - shift := 16 * i - - var head, carry uint64 - for j := uint(0); j < 4; j++ { - block := 4 * j - - xi := buff[block] - yi := (buff[block+i] << shift) + head - zi := xi + yi + carry - buff[block] = zi - carry = (xi&yi | (xi|yi)&^zi) >> 63 - - head = buff[block+i] >> (64 - shift) - } - } - - return [4]uint64{buff[0], buff[4], buff[8], buff[12]} -} - -func gfpMul(c, a, b *gfP) { - T := mul(*a, *b) - m := halfMul([4]uint64{T[0], T[1], T[2], T[3]}, np) - t := mul([4]uint64{m[0], m[1], m[2], m[3]}, p2) - - var carry uint64 - for i, Ti := range T { - ti := t[i] - zi := Ti + ti + carry - T[i] = zi - carry = (Ti&ti | (Ti|ti)&^zi) >> 63 - } - - *c = gfP{T[4], T[5], T[6], T[7]} - gfpCarry(c, carry) -} diff --git a/crypto/bn256/cloudflare/gfp_test.go b/crypto/bn256/cloudflare/gfp_test.go deleted file mode 100644 index 16ab2a8410..0000000000 --- a/crypto/bn256/cloudflare/gfp_test.go +++ /dev/null @@ -1,60 +0,0 @@ -package bn256 - -import ( - "testing" -) - -// Tests that negation works the same way on both assembly-optimized and pure Go -// implementation. -func TestGFpNeg(t *testing.T) { - n := &gfP{0x0123456789abcdef, 0xfedcba9876543210, 0xdeadbeefdeadbeef, 0xfeebdaedfeebdaed} - w := &gfP{0xfedcba9876543211, 0x0123456789abcdef, 0x2152411021524110, 0x0114251201142512} - h := &gfP{} - - gfpNeg(h, n) - if *h != *w { - t.Errorf("negation mismatch: have %#x, want %#x", *h, *w) - } -} - -// Tests that addition works the same way on both assembly-optimized and pure Go -// implementation. -func TestGFpAdd(t *testing.T) { - a := &gfP{0x0123456789abcdef, 0xfedcba9876543210, 0xdeadbeefdeadbeef, 0xfeebdaedfeebdaed} - b := &gfP{0xfedcba9876543210, 0x0123456789abcdef, 0xfeebdaedfeebdaed, 0xdeadbeefdeadbeef} - w := &gfP{0xc3df73e9278302b8, 0x687e956e978e3572, 0x254954275c18417f, 0xad354b6afc67f9b4} - h := &gfP{} - - gfpAdd(h, a, b) - if *h != *w { - t.Errorf("addition mismatch: have %#x, want %#x", *h, *w) - } -} - -// Tests that subtraction works the same way on both assembly-optimized and pure Go -// implementation. -func TestGFpSub(t *testing.T) { - a := &gfP{0x0123456789abcdef, 0xfedcba9876543210, 0xdeadbeefdeadbeef, 0xfeebdaedfeebdaed} - b := &gfP{0xfedcba9876543210, 0x0123456789abcdef, 0xfeebdaedfeebdaed, 0xdeadbeefdeadbeef} - w := &gfP{0x02468acf13579bdf, 0xfdb97530eca86420, 0xdfc1e401dfc1e402, 0x203e1bfe203e1bfd} - h := &gfP{} - - gfpSub(h, a, b) - if *h != *w { - t.Errorf("subtraction mismatch: have %#x, want %#x", *h, *w) - } -} - -// Tests that multiplication works the same way on both assembly-optimized and pure Go -// implementation. -func TestGFpMul(t *testing.T) { - a := &gfP{0x0123456789abcdef, 0xfedcba9876543210, 0xdeadbeefdeadbeef, 0xfeebdaedfeebdaed} - b := &gfP{0xfedcba9876543210, 0x0123456789abcdef, 0xfeebdaedfeebdaed, 0xdeadbeefdeadbeef} - w := &gfP{0xcbcbd377f7ad22d3, 0x3b89ba5d849379bf, 0x87b61627bd38b6d2, 0xc44052a2a0e654b2} - h := &gfP{} - - gfpMul(h, a, b) - if *h != *w { - t.Errorf("multiplication mismatch: have %#x, want %#x", *h, *w) - } -} diff --git a/crypto/bn256/cloudflare/lattice.go b/crypto/bn256/cloudflare/lattice.go deleted file mode 100644 index f9ace4d9fc..0000000000 --- a/crypto/bn256/cloudflare/lattice.go +++ /dev/null @@ -1,115 +0,0 @@ -package bn256 - -import ( - "math/big" -) - -var half = new(big.Int).Rsh(Order, 1) - -var curveLattice = &lattice{ - vectors: [][]*big.Int{ - {bigFromBase10("147946756881789319000765030803803410728"), bigFromBase10("147946756881789319010696353538189108491")}, - {bigFromBase10("147946756881789319020627676272574806254"), bigFromBase10("-147946756881789318990833708069417712965")}, - }, - inverse: []*big.Int{ - bigFromBase10("147946756881789318990833708069417712965"), - bigFromBase10("147946756881789319010696353538189108491"), - }, - det: bigFromBase10("43776485743678550444492811490514550177096728800832068687396408373151616991234"), -} - -var targetLattice = &lattice{ - vectors: [][]*big.Int{ - {bigFromBase10("9931322734385697761"), bigFromBase10("9931322734385697761"), bigFromBase10("9931322734385697763"), bigFromBase10("9931322734385697764")}, - {bigFromBase10("4965661367192848881"), bigFromBase10("4965661367192848881"), bigFromBase10("4965661367192848882"), bigFromBase10("-9931322734385697762")}, - {bigFromBase10("-9931322734385697762"), bigFromBase10("-4965661367192848881"), bigFromBase10("4965661367192848881"), bigFromBase10("-4965661367192848882")}, - {bigFromBase10("9931322734385697763"), bigFromBase10("-4965661367192848881"), bigFromBase10("-4965661367192848881"), bigFromBase10("-4965661367192848881")}, - }, - inverse: []*big.Int{ - bigFromBase10("734653495049373973658254490726798021314063399421879442165"), - bigFromBase10("147946756881789319000765030803803410728"), - bigFromBase10("-147946756881789319005730692170996259609"), - bigFromBase10("1469306990098747947464455738335385361643788813749140841702"), - }, - det: new(big.Int).Set(Order), -} - -type lattice struct { - vectors [][]*big.Int - inverse []*big.Int - det *big.Int -} - -// decompose takes a scalar mod Order as input and finds a short, positive decomposition of it wrt to the lattice basis. -func (l *lattice) decompose(k *big.Int) []*big.Int { - n := len(l.inverse) - - // Calculate closest vector in lattice to with Babai's rounding. - c := make([]*big.Int, n) - for i := 0; i < n; i++ { - c[i] = new(big.Int).Mul(k, l.inverse[i]) - round(c[i], l.det) - } - - // Transform vectors according to c and subtract . - out := make([]*big.Int, n) - temp := new(big.Int) - - for i := 0; i < n; i++ { - out[i] = new(big.Int) - - for j := 0; j < n; j++ { - temp.Mul(c[j], l.vectors[j][i]) - out[i].Add(out[i], temp) - } - - out[i].Neg(out[i]) - out[i].Add(out[i], l.vectors[0][i]).Add(out[i], l.vectors[0][i]) - } - out[0].Add(out[0], k) - - return out -} - -func (l *lattice) Precompute(add func(i, j uint)) { - n := uint(len(l.vectors)) - total := uint(1) << n - - for i := uint(0); i < n; i++ { - for j := uint(0); j < total; j++ { - if (j>>i)&1 == 1 { - add(i, j) - } - } - } -} - -func (l *lattice) Multi(scalar *big.Int) []uint8 { - decomp := l.decompose(scalar) - - maxLen := 0 - for _, x := range decomp { - if x.BitLen() > maxLen { - maxLen = x.BitLen() - } - } - - out := make([]uint8, maxLen) - for j, x := range decomp { - for i := 0; i < maxLen; i++ { - out[i] += uint8(x.Bit(i)) << uint(j) - } - } - - return out -} - -// round sets num to num/denom rounded to the nearest integer. -func round(num, denom *big.Int) { - r := new(big.Int) - num.DivMod(num, denom, r) - - if r.Cmp(half) == 1 { - num.Add(num, big.NewInt(1)) - } -} diff --git a/crypto/bn256/cloudflare/lattice_test.go b/crypto/bn256/cloudflare/lattice_test.go deleted file mode 100644 index 4d52ad9b27..0000000000 --- a/crypto/bn256/cloudflare/lattice_test.go +++ /dev/null @@ -1,29 +0,0 @@ -package bn256 - -import ( - "crypto/rand" - - "testing" -) - -func TestLatticeReduceCurve(t *testing.T) { - k, _ := rand.Int(rand.Reader, Order) - ks := curveLattice.decompose(k) - - if ks[0].BitLen() > 130 || ks[1].BitLen() > 130 { - t.Fatal("reduction too large") - } else if ks[0].Sign() < 0 || ks[1].Sign() < 0 { - t.Fatal("reduction must be positive") - } -} - -func TestLatticeReduceTarget(t *testing.T) { - k, _ := rand.Int(rand.Reader, Order) - ks := targetLattice.decompose(k) - - if ks[0].BitLen() > 66 || ks[1].BitLen() > 66 || ks[2].BitLen() > 66 || ks[3].BitLen() > 66 { - t.Fatal("reduction too large") - } else if ks[0].Sign() < 0 || ks[1].Sign() < 0 || ks[2].Sign() < 0 || ks[3].Sign() < 0 { - t.Fatal("reduction must be positive") - } -} diff --git a/crypto/bn256/cloudflare/main_test.go b/crypto/bn256/cloudflare/main_test.go deleted file mode 100644 index c0c85457be..0000000000 --- a/crypto/bn256/cloudflare/main_test.go +++ /dev/null @@ -1,71 +0,0 @@ -package bn256 - -import ( - "testing" - - "crypto/rand" -) - -func TestRandomG2Marshal(t *testing.T) { - for i := 0; i < 10; i++ { - n, g2, err := RandomG2(rand.Reader) - if err != nil { - t.Error(err) - continue - } - t.Logf("%v: %x\n", n, g2.Marshal()) - } -} - -func TestPairings(t *testing.T) { - a1 := new(G1).ScalarBaseMult(bigFromBase10("1")) - a2 := new(G1).ScalarBaseMult(bigFromBase10("2")) - a37 := new(G1).ScalarBaseMult(bigFromBase10("37")) - an1 := new(G1).ScalarBaseMult(bigFromBase10("21888242871839275222246405745257275088548364400416034343698204186575808495616")) - - b0 := new(G2).ScalarBaseMult(bigFromBase10("0")) - b1 := new(G2).ScalarBaseMult(bigFromBase10("1")) - b2 := new(G2).ScalarBaseMult(bigFromBase10("2")) - b27 := new(G2).ScalarBaseMult(bigFromBase10("27")) - b999 := new(G2).ScalarBaseMult(bigFromBase10("999")) - bn1 := new(G2).ScalarBaseMult(bigFromBase10("21888242871839275222246405745257275088548364400416034343698204186575808495616")) - - p1 := Pair(a1, b1) - pn1 := Pair(a1, bn1) - np1 := Pair(an1, b1) - if pn1.String() != np1.String() { - t.Error("Pairing mismatch: e(a, -b) != e(-a, b)") - } - if !PairingCheck([]*G1{a1, an1}, []*G2{b1, b1}) { - t.Error("MultiAte check gave false negative!") - } - p0 := new(GT).Add(p1, pn1) - p0_2 := Pair(a1, b0) - if p0.String() != p0_2.String() { - t.Error("Pairing mismatch: e(a, b) * e(a, -b) != 1") - } - p0_3 := new(GT).ScalarMult(p1, bigFromBase10("21888242871839275222246405745257275088548364400416034343698204186575808495617")) - if p0.String() != p0_3.String() { - t.Error("Pairing mismatch: e(a, b) has wrong order") - } - p2 := Pair(a2, b1) - p2_2 := Pair(a1, b2) - p2_3 := new(GT).ScalarMult(p1, bigFromBase10("2")) - if p2.String() != p2_2.String() { - t.Error("Pairing mismatch: e(a, b * 2) != e(a * 2, b)") - } - if p2.String() != p2_3.String() { - t.Error("Pairing mismatch: e(a, b * 2) != e(a, b) ** 2") - } - if p2.String() == p1.String() { - t.Error("Pairing is degenerate!") - } - if PairingCheck([]*G1{a1, a1}, []*G2{b1, b1}) { - t.Error("MultiAte check gave false positive!") - } - p999 := Pair(a37, b27) - p999_2 := Pair(a1, b999) - if p999.String() != p999_2.String() { - t.Error("Pairing mismatch: e(a * 37, b * 27) != e(a, b * 999)") - } -} diff --git a/crypto/bn256/cloudflare/mul_amd64.h b/crypto/bn256/cloudflare/mul_amd64.h deleted file mode 100644 index bab5da8313..0000000000 --- a/crypto/bn256/cloudflare/mul_amd64.h +++ /dev/null @@ -1,181 +0,0 @@ -#define mul(a0,a1,a2,a3, rb, stack) \ - MOVQ a0, AX \ - MULQ 0+rb \ - MOVQ AX, R8 \ - MOVQ DX, R9 \ - MOVQ a0, AX \ - MULQ 8+rb \ - ADDQ AX, R9 \ - ADCQ $0, DX \ - MOVQ DX, R10 \ - MOVQ a0, AX \ - MULQ 16+rb \ - ADDQ AX, R10 \ - ADCQ $0, DX \ - MOVQ DX, R11 \ - MOVQ a0, AX \ - MULQ 24+rb \ - ADDQ AX, R11 \ - ADCQ $0, DX \ - MOVQ DX, R12 \ - \ - storeBlock(R8,R9,R10,R11, 0+stack) \ - MOVQ R12, 32+stack \ - \ - MOVQ a1, AX \ - MULQ 0+rb \ - MOVQ AX, R8 \ - MOVQ DX, R9 \ - MOVQ a1, AX \ - MULQ 8+rb \ - ADDQ AX, R9 \ - ADCQ $0, DX \ - MOVQ DX, R10 \ - MOVQ a1, AX \ - MULQ 16+rb \ - ADDQ AX, R10 \ - ADCQ $0, DX \ - MOVQ DX, R11 \ - MOVQ a1, AX \ - MULQ 24+rb \ - ADDQ AX, R11 \ - ADCQ $0, DX \ - MOVQ DX, R12 \ - \ - ADDQ 8+stack, R8 \ - ADCQ 16+stack, R9 \ - ADCQ 24+stack, R10 \ - ADCQ 32+stack, R11 \ - ADCQ $0, R12 \ - storeBlock(R8,R9,R10,R11, 8+stack) \ - MOVQ R12, 40+stack \ - \ - MOVQ a2, AX \ - MULQ 0+rb \ - MOVQ AX, R8 \ - MOVQ DX, R9 \ - MOVQ a2, AX \ - MULQ 8+rb \ - ADDQ AX, R9 \ - ADCQ $0, DX \ - MOVQ DX, R10 \ - MOVQ a2, AX \ - MULQ 16+rb \ - ADDQ AX, R10 \ - ADCQ $0, DX \ - MOVQ DX, R11 \ - MOVQ a2, AX \ - MULQ 24+rb \ - ADDQ AX, R11 \ - ADCQ $0, DX \ - MOVQ DX, R12 \ - \ - ADDQ 16+stack, R8 \ - ADCQ 24+stack, R9 \ - ADCQ 32+stack, R10 \ - ADCQ 40+stack, R11 \ - ADCQ $0, R12 \ - storeBlock(R8,R9,R10,R11, 16+stack) \ - MOVQ R12, 48+stack \ - \ - MOVQ a3, AX \ - MULQ 0+rb \ - MOVQ AX, R8 \ - MOVQ DX, R9 \ - MOVQ a3, AX \ - MULQ 8+rb \ - ADDQ AX, R9 \ - ADCQ $0, DX \ - MOVQ DX, R10 \ - MOVQ a3, AX \ - MULQ 16+rb \ - ADDQ AX, R10 \ - ADCQ $0, DX \ - MOVQ DX, R11 \ - MOVQ a3, AX \ - MULQ 24+rb \ - ADDQ AX, R11 \ - ADCQ $0, DX \ - MOVQ DX, R12 \ - \ - ADDQ 24+stack, R8 \ - ADCQ 32+stack, R9 \ - ADCQ 40+stack, R10 \ - ADCQ 48+stack, R11 \ - ADCQ $0, R12 \ - storeBlock(R8,R9,R10,R11, 24+stack) \ - MOVQ R12, 56+stack - -#define gfpReduce(stack) \ - \ // m = (T * N') mod R, store m in R8:R9:R10:R11 - MOVQ ·np+0(SB), AX \ - MULQ 0+stack \ - MOVQ AX, R8 \ - MOVQ DX, R9 \ - MOVQ ·np+0(SB), AX \ - MULQ 8+stack \ - ADDQ AX, R9 \ - ADCQ $0, DX \ - MOVQ DX, R10 \ - MOVQ ·np+0(SB), AX \ - MULQ 16+stack \ - ADDQ AX, R10 \ - ADCQ $0, DX \ - MOVQ DX, R11 \ - MOVQ ·np+0(SB), AX \ - MULQ 24+stack \ - ADDQ AX, R11 \ - \ - MOVQ ·np+8(SB), AX \ - MULQ 0+stack \ - MOVQ AX, R12 \ - MOVQ DX, R13 \ - MOVQ ·np+8(SB), AX \ - MULQ 8+stack \ - ADDQ AX, R13 \ - ADCQ $0, DX \ - MOVQ DX, R14 \ - MOVQ ·np+8(SB), AX \ - MULQ 16+stack \ - ADDQ AX, R14 \ - \ - ADDQ R12, R9 \ - ADCQ R13, R10 \ - ADCQ R14, R11 \ - \ - MOVQ ·np+16(SB), AX \ - MULQ 0+stack \ - MOVQ AX, R12 \ - MOVQ DX, R13 \ - MOVQ ·np+16(SB), AX \ - MULQ 8+stack \ - ADDQ AX, R13 \ - \ - ADDQ R12, R10 \ - ADCQ R13, R11 \ - \ - MOVQ ·np+24(SB), AX \ - MULQ 0+stack \ - ADDQ AX, R11 \ - \ - storeBlock(R8,R9,R10,R11, 64+stack) \ - \ - \ // m * N - mul(·p2+0(SB),·p2+8(SB),·p2+16(SB),·p2+24(SB), 64+stack, 96+stack) \ - \ - \ // Add the 512-bit intermediate to m*N - loadBlock(96+stack, R8,R9,R10,R11) \ - loadBlock(128+stack, R12,R13,R14,R15) \ - \ - MOVQ $0, AX \ - ADDQ 0+stack, R8 \ - ADCQ 8+stack, R9 \ - ADCQ 16+stack, R10 \ - ADCQ 24+stack, R11 \ - ADCQ 32+stack, R12 \ - ADCQ 40+stack, R13 \ - ADCQ 48+stack, R14 \ - ADCQ 56+stack, R15 \ - ADCQ $0, AX \ - \ - gfpCarry(R12,R13,R14,R15,AX, R8,R9,R10,R11,BX) diff --git a/crypto/bn256/cloudflare/mul_arm64.h b/crypto/bn256/cloudflare/mul_arm64.h deleted file mode 100644 index d405eb8f72..0000000000 --- a/crypto/bn256/cloudflare/mul_arm64.h +++ /dev/null @@ -1,133 +0,0 @@ -#define mul(c0,c1,c2,c3,c4,c5,c6,c7) \ - MUL R1, R5, c0 \ - UMULH R1, R5, c1 \ - MUL R1, R6, R0 \ - ADDS R0, c1 \ - UMULH R1, R6, c2 \ - MUL R1, R7, R0 \ - ADCS R0, c2 \ - UMULH R1, R7, c3 \ - MUL R1, R8, R0 \ - ADCS R0, c3 \ - UMULH R1, R8, c4 \ - ADCS ZR, c4 \ - \ - MUL R2, R5, R1 \ - UMULH R2, R5, R26 \ - MUL R2, R6, R0 \ - ADDS R0, R26 \ - UMULH R2, R6, R27 \ - MUL R2, R7, R0 \ - ADCS R0, R27 \ - UMULH R2, R7, R29 \ - MUL R2, R8, R0 \ - ADCS R0, R29 \ - UMULH R2, R8, c5 \ - ADCS ZR, c5 \ - ADDS R1, c1 \ - ADCS R26, c2 \ - ADCS R27, c3 \ - ADCS R29, c4 \ - ADCS ZR, c5 \ - \ - MUL R3, R5, R1 \ - UMULH R3, R5, R26 \ - MUL R3, R6, R0 \ - ADDS R0, R26 \ - UMULH R3, R6, R27 \ - MUL R3, R7, R0 \ - ADCS R0, R27 \ - UMULH R3, R7, R29 \ - MUL R3, R8, R0 \ - ADCS R0, R29 \ - UMULH R3, R8, c6 \ - ADCS ZR, c6 \ - ADDS R1, c2 \ - ADCS R26, c3 \ - ADCS R27, c4 \ - ADCS R29, c5 \ - ADCS ZR, c6 \ - \ - MUL R4, R5, R1 \ - UMULH R4, R5, R26 \ - MUL R4, R6, R0 \ - ADDS R0, R26 \ - UMULH R4, R6, R27 \ - MUL R4, R7, R0 \ - ADCS R0, R27 \ - UMULH R4, R7, R29 \ - MUL R4, R8, R0 \ - ADCS R0, R29 \ - UMULH R4, R8, c7 \ - ADCS ZR, c7 \ - ADDS R1, c3 \ - ADCS R26, c4 \ - ADCS R27, c5 \ - ADCS R29, c6 \ - ADCS ZR, c7 - -#define gfpReduce() \ - \ // m = (T * N') mod R, store m in R1:R2:R3:R4 - MOVD ·np+0(SB), R17 \ - MOVD ·np+8(SB), R25 \ - MOVD ·np+16(SB), R19 \ - MOVD ·np+24(SB), R20 \ - \ - MUL R9, R17, R1 \ - UMULH R9, R17, R2 \ - MUL R9, R25, R0 \ - ADDS R0, R2 \ - UMULH R9, R25, R3 \ - MUL R9, R19, R0 \ - ADCS R0, R3 \ - UMULH R9, R19, R4 \ - MUL R9, R20, R0 \ - ADCS R0, R4 \ - \ - MUL R10, R17, R21 \ - UMULH R10, R17, R22 \ - MUL R10, R25, R0 \ - ADDS R0, R22 \ - UMULH R10, R25, R23 \ - MUL R10, R19, R0 \ - ADCS R0, R23 \ - ADDS R21, R2 \ - ADCS R22, R3 \ - ADCS R23, R4 \ - \ - MUL R11, R17, R21 \ - UMULH R11, R17, R22 \ - MUL R11, R25, R0 \ - ADDS R0, R22 \ - ADDS R21, R3 \ - ADCS R22, R4 \ - \ - MUL R12, R17, R21 \ - ADDS R21, R4 \ - \ - \ // m * N - loadModulus(R5,R6,R7,R8) \ - mul(R17,R25,R19,R20,R21,R22,R23,R24) \ - \ - \ // Add the 512-bit intermediate to m*N - MOVD ZR, R0 \ - ADDS R9, R17 \ - ADCS R10, R25 \ - ADCS R11, R19 \ - ADCS R12, R20 \ - ADCS R13, R21 \ - ADCS R14, R22 \ - ADCS R15, R23 \ - ADCS R16, R24 \ - ADCS ZR, R0 \ - \ - \ // Our output is R21:R22:R23:R24. Reduce mod p if necessary. - SUBS R5, R21, R10 \ - SBCS R6, R22, R11 \ - SBCS R7, R23, R12 \ - SBCS R8, R24, R13 \ - \ - CSEL CS, R10, R21, R1 \ - CSEL CS, R11, R22, R2 \ - CSEL CS, R12, R23, R3 \ - CSEL CS, R13, R24, R4 diff --git a/crypto/bn256/cloudflare/mul_bmi2_amd64.h b/crypto/bn256/cloudflare/mul_bmi2_amd64.h deleted file mode 100644 index 71ad0499af..0000000000 --- a/crypto/bn256/cloudflare/mul_bmi2_amd64.h +++ /dev/null @@ -1,112 +0,0 @@ -#define mulBMI2(a0,a1,a2,a3, rb) \ - MOVQ a0, DX \ - MOVQ $0, R13 \ - MULXQ 0+rb, R8, R9 \ - MULXQ 8+rb, AX, R10 \ - ADDQ AX, R9 \ - MULXQ 16+rb, AX, R11 \ - ADCQ AX, R10 \ - MULXQ 24+rb, AX, R12 \ - ADCQ AX, R11 \ - ADCQ $0, R12 \ - ADCQ $0, R13 \ - \ - MOVQ a1, DX \ - MOVQ $0, R14 \ - MULXQ 0+rb, AX, BX \ - ADDQ AX, R9 \ - ADCQ BX, R10 \ - MULXQ 16+rb, AX, BX \ - ADCQ AX, R11 \ - ADCQ BX, R12 \ - ADCQ $0, R13 \ - MULXQ 8+rb, AX, BX \ - ADDQ AX, R10 \ - ADCQ BX, R11 \ - MULXQ 24+rb, AX, BX \ - ADCQ AX, R12 \ - ADCQ BX, R13 \ - ADCQ $0, R14 \ - \ - MOVQ a2, DX \ - MOVQ $0, R15 \ - MULXQ 0+rb, AX, BX \ - ADDQ AX, R10 \ - ADCQ BX, R11 \ - MULXQ 16+rb, AX, BX \ - ADCQ AX, R12 \ - ADCQ BX, R13 \ - ADCQ $0, R14 \ - MULXQ 8+rb, AX, BX \ - ADDQ AX, R11 \ - ADCQ BX, R12 \ - MULXQ 24+rb, AX, BX \ - ADCQ AX, R13 \ - ADCQ BX, R14 \ - ADCQ $0, R15 \ - \ - MOVQ a3, DX \ - MULXQ 0+rb, AX, BX \ - ADDQ AX, R11 \ - ADCQ BX, R12 \ - MULXQ 16+rb, AX, BX \ - ADCQ AX, R13 \ - ADCQ BX, R14 \ - ADCQ $0, R15 \ - MULXQ 8+rb, AX, BX \ - ADDQ AX, R12 \ - ADCQ BX, R13 \ - MULXQ 24+rb, AX, BX \ - ADCQ AX, R14 \ - ADCQ BX, R15 - -#define gfpReduceBMI2() \ - \ // m = (T * N') mod R, store m in R8:R9:R10:R11 - MOVQ ·np+0(SB), DX \ - MULXQ 0(SP), R8, R9 \ - MULXQ 8(SP), AX, R10 \ - ADDQ AX, R9 \ - MULXQ 16(SP), AX, R11 \ - ADCQ AX, R10 \ - MULXQ 24(SP), AX, BX \ - ADCQ AX, R11 \ - \ - MOVQ ·np+8(SB), DX \ - MULXQ 0(SP), AX, BX \ - ADDQ AX, R9 \ - ADCQ BX, R10 \ - MULXQ 16(SP), AX, BX \ - ADCQ AX, R11 \ - MULXQ 8(SP), AX, BX \ - ADDQ AX, R10 \ - ADCQ BX, R11 \ - \ - MOVQ ·np+16(SB), DX \ - MULXQ 0(SP), AX, BX \ - ADDQ AX, R10 \ - ADCQ BX, R11 \ - MULXQ 8(SP), AX, BX \ - ADDQ AX, R11 \ - \ - MOVQ ·np+24(SB), DX \ - MULXQ 0(SP), AX, BX \ - ADDQ AX, R11 \ - \ - storeBlock(R8,R9,R10,R11, 64(SP)) \ - \ - \ // m * N - mulBMI2(·p2+0(SB),·p2+8(SB),·p2+16(SB),·p2+24(SB), 64(SP)) \ - \ - \ // Add the 512-bit intermediate to m*N - MOVQ $0, AX \ - ADDQ 0(SP), R8 \ - ADCQ 8(SP), R9 \ - ADCQ 16(SP), R10 \ - ADCQ 24(SP), R11 \ - ADCQ 32(SP), R12 \ - ADCQ 40(SP), R13 \ - ADCQ 48(SP), R14 \ - ADCQ 56(SP), R15 \ - ADCQ $0, AX \ - \ - gfpCarry(R12,R13,R14,R15,AX, R8,R9,R10,R11,BX) diff --git a/crypto/bn256/cloudflare/optate.go b/crypto/bn256/cloudflare/optate.go deleted file mode 100644 index b71e50e3a2..0000000000 --- a/crypto/bn256/cloudflare/optate.go +++ /dev/null @@ -1,271 +0,0 @@ -package bn256 - -func lineFunctionAdd(r, p *twistPoint, q *curvePoint, r2 *gfP2) (a, b, c *gfP2, rOut *twistPoint) { - // See the mixed addition algorithm from "Faster Computation of the - // Tate Pairing", http://arxiv.org/pdf/0904.0854v3.pdf - B := (&gfP2{}).Mul(&p.x, &r.t) - - D := (&gfP2{}).Add(&p.y, &r.z) - D.Square(D).Sub(D, r2).Sub(D, &r.t).Mul(D, &r.t) - - H := (&gfP2{}).Sub(B, &r.x) - I := (&gfP2{}).Square(H) - - E := (&gfP2{}).Add(I, I) - E.Add(E, E) - - J := (&gfP2{}).Mul(H, E) - - L1 := (&gfP2{}).Sub(D, &r.y) - L1.Sub(L1, &r.y) - - V := (&gfP2{}).Mul(&r.x, E) - - rOut = &twistPoint{} - rOut.x.Square(L1).Sub(&rOut.x, J).Sub(&rOut.x, V).Sub(&rOut.x, V) - - rOut.z.Add(&r.z, H).Square(&rOut.z).Sub(&rOut.z, &r.t).Sub(&rOut.z, I) - - t := (&gfP2{}).Sub(V, &rOut.x) - t.Mul(t, L1) - t2 := (&gfP2{}).Mul(&r.y, J) - t2.Add(t2, t2) - rOut.y.Sub(t, t2) - - rOut.t.Square(&rOut.z) - - t.Add(&p.y, &rOut.z).Square(t).Sub(t, r2).Sub(t, &rOut.t) - - t2.Mul(L1, &p.x) - t2.Add(t2, t2) - a = (&gfP2{}).Sub(t2, t) - - c = (&gfP2{}).MulScalar(&rOut.z, &q.y) - c.Add(c, c) - - b = (&gfP2{}).Neg(L1) - b.MulScalar(b, &q.x).Add(b, b) - - return -} - -func lineFunctionDouble(r *twistPoint, q *curvePoint) (a, b, c *gfP2, rOut *twistPoint) { - // See the doubling algorithm for a=0 from "Faster Computation of the - // Tate Pairing", http://arxiv.org/pdf/0904.0854v3.pdf - A := (&gfP2{}).Square(&r.x) - B := (&gfP2{}).Square(&r.y) - C := (&gfP2{}).Square(B) - - D := (&gfP2{}).Add(&r.x, B) - D.Square(D).Sub(D, A).Sub(D, C).Add(D, D) - - E := (&gfP2{}).Add(A, A) - E.Add(E, A) - - G := (&gfP2{}).Square(E) - - rOut = &twistPoint{} - rOut.x.Sub(G, D).Sub(&rOut.x, D) - - rOut.z.Add(&r.y, &r.z).Square(&rOut.z).Sub(&rOut.z, B).Sub(&rOut.z, &r.t) - - rOut.y.Sub(D, &rOut.x).Mul(&rOut.y, E) - t := (&gfP2{}).Add(C, C) - t.Add(t, t).Add(t, t) - rOut.y.Sub(&rOut.y, t) - - rOut.t.Square(&rOut.z) - - t.Mul(E, &r.t).Add(t, t) - b = (&gfP2{}).Neg(t) - b.MulScalar(b, &q.x) - - a = (&gfP2{}).Add(&r.x, E) - a.Square(a).Sub(a, A).Sub(a, G) - t.Add(B, B).Add(t, t) - a.Sub(a, t) - - c = (&gfP2{}).Mul(&rOut.z, &r.t) - c.Add(c, c).MulScalar(c, &q.y) - - return -} - -func mulLine(ret *gfP12, a, b, c *gfP2) { - a2 := &gfP6{} - a2.y.Set(a) - a2.z.Set(b) - a2.Mul(a2, &ret.x) - t3 := (&gfP6{}).MulScalar(&ret.y, c) - - t := (&gfP2{}).Add(b, c) - t2 := &gfP6{} - t2.y.Set(a) - t2.z.Set(t) - ret.x.Add(&ret.x, &ret.y) - - ret.y.Set(t3) - - ret.x.Mul(&ret.x, t2).Sub(&ret.x, a2).Sub(&ret.x, &ret.y) - a2.MulTau(a2) - ret.y.Add(&ret.y, a2) -} - -// sixuPlus2NAF is 6u+2 in non-adjacent form. -var sixuPlus2NAF = []int8{0, 0, 0, 1, 0, 1, 0, -1, 0, 0, 1, -1, 0, 0, 1, 0, - 0, 1, 1, 0, -1, 0, 0, 1, 0, -1, 0, 0, 0, 0, 1, 1, - 1, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 1, - 1, 0, 0, -1, 0, 0, 0, 1, 1, 0, -1, 0, 0, 1, 0, 1, 1} - -// miller implements the Miller loop for calculating the Optimal Ate pairing. -// See algorithm 1 from http://cryptojedi.org/papers/dclxvi-20100714.pdf -func miller(q *twistPoint, p *curvePoint) *gfP12 { - ret := (&gfP12{}).SetOne() - - aAffine := &twistPoint{} - aAffine.Set(q) - aAffine.MakeAffine() - - bAffine := &curvePoint{} - bAffine.Set(p) - bAffine.MakeAffine() - - minusA := &twistPoint{} - minusA.Neg(aAffine) - - r := &twistPoint{} - r.Set(aAffine) - - r2 := (&gfP2{}).Square(&aAffine.y) - - for i := len(sixuPlus2NAF) - 1; i > 0; i-- { - a, b, c, newR := lineFunctionDouble(r, bAffine) - if i != len(sixuPlus2NAF)-1 { - ret.Square(ret) - } - - mulLine(ret, a, b, c) - r = newR - - switch sixuPlus2NAF[i-1] { - case 1: - a, b, c, newR = lineFunctionAdd(r, aAffine, bAffine, r2) - case -1: - a, b, c, newR = lineFunctionAdd(r, minusA, bAffine, r2) - default: - continue - } - - mulLine(ret, a, b, c) - r = newR - } - - // In order to calculate Q1 we have to convert q from the sextic twist - // to the full GF(p^12) group, apply the Frobenius there, and convert - // back. - // - // The twist isomorphism is (x', y') -> (xω², yω³). If we consider just - // x for a moment, then after applying the Frobenius, we have x̄ω^(2p) - // where x̄ is the conjugate of x. If we are going to apply the inverse - // isomorphism we need a value with a single coefficient of ω² so we - // rewrite this as x̄ω^(2p-2)ω². ξ⁶ = ω and, due to the construction of - // p, 2p-2 is a multiple of six. Therefore we can rewrite as - // x̄ξ^((p-1)/3)ω² and applying the inverse isomorphism eliminates the - // ω². - // - // A similar argument can be made for the y value. - - q1 := &twistPoint{} - q1.x.Conjugate(&aAffine.x).Mul(&q1.x, xiToPMinus1Over3) - q1.y.Conjugate(&aAffine.y).Mul(&q1.y, xiToPMinus1Over2) - q1.z.SetOne() - q1.t.SetOne() - - // For Q2 we are applying the p² Frobenius. The two conjugations cancel - // out and we are left only with the factors from the isomorphism. In - // the case of x, we end up with a pure number which is why - // xiToPSquaredMinus1Over3 is ∈ GF(p). With y we get a factor of -1. We - // ignore this to end up with -Q2. - - minusQ2 := &twistPoint{} - minusQ2.x.MulScalar(&aAffine.x, xiToPSquaredMinus1Over3) - minusQ2.y.Set(&aAffine.y) - minusQ2.z.SetOne() - minusQ2.t.SetOne() - - r2.Square(&q1.y) - a, b, c, newR := lineFunctionAdd(r, q1, bAffine, r2) - mulLine(ret, a, b, c) - r = newR - - r2.Square(&minusQ2.y) - a, b, c, newR = lineFunctionAdd(r, minusQ2, bAffine, r2) - mulLine(ret, a, b, c) - r = newR - - return ret -} - -// finalExponentiation computes the (p¹²-1)/Order-th power of an element of -// GF(p¹²) to obtain an element of GT (steps 13-15 of algorithm 1 from -// http://cryptojedi.org/papers/dclxvi-20100714.pdf) -func finalExponentiation(in *gfP12) *gfP12 { - t1 := &gfP12{} - - // This is the p^6-Frobenius - t1.x.Neg(&in.x) - t1.y.Set(&in.y) - - inv := &gfP12{} - inv.Invert(in) - t1.Mul(t1, inv) - - t2 := (&gfP12{}).FrobeniusP2(t1) - t1.Mul(t1, t2) - - fp := (&gfP12{}).Frobenius(t1) - fp2 := (&gfP12{}).FrobeniusP2(t1) - fp3 := (&gfP12{}).Frobenius(fp2) - - fu := (&gfP12{}).Exp(t1, u) - fu2 := (&gfP12{}).Exp(fu, u) - fu3 := (&gfP12{}).Exp(fu2, u) - - y3 := (&gfP12{}).Frobenius(fu) - fu2p := (&gfP12{}).Frobenius(fu2) - fu3p := (&gfP12{}).Frobenius(fu3) - y2 := (&gfP12{}).FrobeniusP2(fu2) - - y0 := &gfP12{} - y0.Mul(fp, fp2).Mul(y0, fp3) - - y1 := (&gfP12{}).Conjugate(t1) - y5 := (&gfP12{}).Conjugate(fu2) - y3.Conjugate(y3) - y4 := (&gfP12{}).Mul(fu, fu2p) - y4.Conjugate(y4) - - y6 := (&gfP12{}).Mul(fu3, fu3p) - y6.Conjugate(y6) - - t0 := (&gfP12{}).Square(y6) - t0.Mul(t0, y4).Mul(t0, y5) - t1.Mul(y3, y5).Mul(t1, t0) - t0.Mul(t0, y2) - t1.Square(t1).Mul(t1, t0).Square(t1) - t0.Mul(t1, y1) - t1.Mul(t1, y0) - t0.Square(t0).Mul(t0, t1) - - return t0 -} - -func optimalAte(a *twistPoint, b *curvePoint) *gfP12 { - e := miller(a, b) - ret := finalExponentiation(e) - - if a.IsInfinity() || b.IsInfinity() { - ret.SetOne() - } - return ret -} diff --git a/crypto/bn256/cloudflare/twist.go b/crypto/bn256/cloudflare/twist.go deleted file mode 100644 index 0c2f80d4ed..0000000000 --- a/crypto/bn256/cloudflare/twist.go +++ /dev/null @@ -1,204 +0,0 @@ -package bn256 - -import ( - "math/big" -) - -// twistPoint implements the elliptic curve y²=x³+3/ξ over GF(p²). Points are -// kept in Jacobian form and t=z² when valid. The group G₂ is the set of -// n-torsion points of this curve over GF(p²) (where n = Order) -type twistPoint struct { - x, y, z, t gfP2 -} - -var twistB = &gfP2{ - gfP{0x38e7ecccd1dcff67, 0x65f0b37d93ce0d3e, 0xd749d0dd22ac00aa, 0x0141b9ce4a688d4d}, - gfP{0x3bf938e377b802a8, 0x020b1b273633535d, 0x26b7edf049755260, 0x2514c6324384a86d}, -} - -// twistGen is the generator of group G₂. -var twistGen = &twistPoint{ - gfP2{ - gfP{0xafb4737da84c6140, 0x6043dd5a5802d8c4, 0x09e950fc52a02f86, 0x14fef0833aea7b6b}, - gfP{0x8e83b5d102bc2026, 0xdceb1935497b0172, 0xfbb8264797811adf, 0x19573841af96503b}, - }, - gfP2{ - gfP{0x64095b56c71856ee, 0xdc57f922327d3cbb, 0x55f935be33351076, 0x0da4a0e693fd6482}, - gfP{0x619dfa9d886be9f6, 0xfe7fd297f59e9b78, 0xff9e1a62231b7dfe, 0x28fd7eebae9e4206}, - }, - gfP2{*newGFp(0), *newGFp(1)}, - gfP2{*newGFp(0), *newGFp(1)}, -} - -func (c *twistPoint) String() string { - c.MakeAffine() - x, y := gfP2Decode(&c.x), gfP2Decode(&c.y) - return "(" + x.String() + ", " + y.String() + ")" -} - -func (c *twistPoint) Set(a *twistPoint) { - c.x.Set(&a.x) - c.y.Set(&a.y) - c.z.Set(&a.z) - c.t.Set(&a.t) -} - -// IsOnCurve returns true iff c is on the curve. -func (c *twistPoint) IsOnCurve() bool { - c.MakeAffine() - if c.IsInfinity() { - return true - } - - y2, x3 := &gfP2{}, &gfP2{} - y2.Square(&c.y) - x3.Square(&c.x).Mul(x3, &c.x).Add(x3, twistB) - - if *y2 != *x3 { - return false - } - cneg := &twistPoint{} - cneg.Mul(c, Order) - return cneg.z.IsZero() -} - -func (c *twistPoint) SetInfinity() { - c.x.SetZero() - c.y.SetOne() - c.z.SetZero() - c.t.SetZero() -} - -func (c *twistPoint) IsInfinity() bool { - return c.z.IsZero() -} - -func (c *twistPoint) Add(a, b *twistPoint) { - // For additional comments, see the same function in curve.go. - - if a.IsInfinity() { - c.Set(b) - return - } - if b.IsInfinity() { - c.Set(a) - return - } - - // See http://hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/addition/add-2007-bl.op3 - z12 := (&gfP2{}).Square(&a.z) - z22 := (&gfP2{}).Square(&b.z) - u1 := (&gfP2{}).Mul(&a.x, z22) - u2 := (&gfP2{}).Mul(&b.x, z12) - - t := (&gfP2{}).Mul(&b.z, z22) - s1 := (&gfP2{}).Mul(&a.y, t) - - t.Mul(&a.z, z12) - s2 := (&gfP2{}).Mul(&b.y, t) - - h := (&gfP2{}).Sub(u2, u1) - xEqual := h.IsZero() - - t.Add(h, h) - i := (&gfP2{}).Square(t) - j := (&gfP2{}).Mul(h, i) - - t.Sub(s2, s1) - yEqual := t.IsZero() - if xEqual && yEqual { - c.Double(a) - return - } - r := (&gfP2{}).Add(t, t) - - v := (&gfP2{}).Mul(u1, i) - - t4 := (&gfP2{}).Square(r) - t.Add(v, v) - t6 := (&gfP2{}).Sub(t4, j) - c.x.Sub(t6, t) - - t.Sub(v, &c.x) // t7 - t4.Mul(s1, j) // t8 - t6.Add(t4, t4) // t9 - t4.Mul(r, t) // t10 - c.y.Sub(t4, t6) - - t.Add(&a.z, &b.z) // t11 - t4.Square(t) // t12 - t.Sub(t4, z12) // t13 - t4.Sub(t, z22) // t14 - c.z.Mul(t4, h) -} - -func (c *twistPoint) Double(a *twistPoint) { - // See http://hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/doubling/dbl-2009-l.op3 - A := (&gfP2{}).Square(&a.x) - B := (&gfP2{}).Square(&a.y) - C := (&gfP2{}).Square(B) - - t := (&gfP2{}).Add(&a.x, B) - t2 := (&gfP2{}).Square(t) - t.Sub(t2, A) - t2.Sub(t, C) - d := (&gfP2{}).Add(t2, t2) - t.Add(A, A) - e := (&gfP2{}).Add(t, A) - f := (&gfP2{}).Square(e) - - t.Add(d, d) - c.x.Sub(f, t) - - t.Add(C, C) - t2.Add(t, t) - t.Add(t2, t2) - c.y.Sub(d, &c.x) - t2.Mul(e, &c.y) - c.y.Sub(t2, t) - - t.Mul(&a.y, &a.z) - c.z.Add(t, t) -} - -func (c *twistPoint) Mul(a *twistPoint, scalar *big.Int) { - sum, t := &twistPoint{}, &twistPoint{} - - for i := scalar.BitLen(); i >= 0; i-- { - t.Double(sum) - if scalar.Bit(i) != 0 { - sum.Add(t, a) - } else { - sum.Set(t) - } - } - - c.Set(sum) -} - -func (c *twistPoint) MakeAffine() { - if c.z.IsOne() { - return - } else if c.z.IsZero() { - c.x.SetZero() - c.y.SetOne() - c.t.SetZero() - return - } - - zInv := (&gfP2{}).Invert(&c.z) - t := (&gfP2{}).Mul(&c.y, zInv) - zInv2 := (&gfP2{}).Square(zInv) - c.y.Mul(t, zInv2) - t.Mul(&c.x, zInv2) - c.x.Set(t) - c.z.SetOne() - c.t.SetOne() -} - -func (c *twistPoint) Neg(a *twistPoint) { - c.x.Set(&a.x) - c.y.Neg(&a.y) - c.z.Set(&a.z) - c.t.SetZero() -} diff --git a/crypto/bn256/google/bn256.go b/crypto/bn256/google/bn256.go deleted file mode 100644 index 0a9d5cd35d..0000000000 --- a/crypto/bn256/google/bn256.go +++ /dev/null @@ -1,460 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package bn256 implements a particular bilinear group. -// -// Bilinear groups are the basis of many of the new cryptographic protocols -// that have been proposed over the past decade. They consist of a triplet of -// groups (G₁, G₂ and GT) such that there exists a function e(g₁ˣ,g₂ʸ)=gTˣʸ -// (where gₓ is a generator of the respective group). That function is called -// a pairing function. -// -// This package specifically implements the Optimal Ate pairing over a 256-bit -// Barreto-Naehrig curve as described in -// http://cryptojedi.org/papers/dclxvi-20100714.pdf. Its output is not -// compatible with the implementation described in that paper, as different -// parameters are chosen. -// -// (This package previously claimed to operate at a 128-bit security level. -// However, recent improvements in attacks mean that is no longer true. See -// https://moderncrypto.org/mail-archive/curves/2016/000740.html.) -package bn256 - -import ( - "crypto/rand" - "errors" - "io" - "math/big" -) - -// BUG(agl): this implementation is not constant time. -// TODO(agl): keep GF(p²) elements in Mongomery form. - -// G1 is an abstract cyclic group. The zero value is suitable for use as the -// output of an operation, but cannot be used as an input. -type G1 struct { - p *curvePoint -} - -// RandomG1 returns x and g₁ˣ where x is a random, non-zero number read from r. -func RandomG1(r io.Reader) (*big.Int, *G1, error) { - var k *big.Int - var err error - - for { - k, err = rand.Int(r, Order) - if err != nil { - return nil, nil, err - } - if k.Sign() > 0 { - break - } - } - - return k, new(G1).ScalarBaseMult(k), nil -} - -func (e *G1) String() string { - return "bn256.G1" + e.p.String() -} - -// CurvePoints returns p's curve points in big integer -func (e *G1) CurvePoints() (*big.Int, *big.Int, *big.Int, *big.Int) { - return e.p.x, e.p.y, e.p.z, e.p.t -} - -// ScalarBaseMult sets e to g*k where g is the generator of the group and -// then returns e. -func (e *G1) ScalarBaseMult(k *big.Int) *G1 { - if e.p == nil { - e.p = newCurvePoint(nil) - } - e.p.Mul(curveGen, k, new(bnPool)) - return e -} - -// ScalarMult sets e to a*k and then returns e. -func (e *G1) ScalarMult(a *G1, k *big.Int) *G1 { - if e.p == nil { - e.p = newCurvePoint(nil) - } - e.p.Mul(a.p, k, new(bnPool)) - return e -} - -// Add sets e to a+b and then returns e. -// BUG(agl): this function is not complete: a==b fails. -func (e *G1) Add(a, b *G1) *G1 { - if e.p == nil { - e.p = newCurvePoint(nil) - } - e.p.Add(a.p, b.p, new(bnPool)) - return e -} - -// Neg sets e to -a and then returns e. -func (e *G1) Neg(a *G1) *G1 { - if e.p == nil { - e.p = newCurvePoint(nil) - } - e.p.Negative(a.p) - return e -} - -// Marshal converts n to a byte slice. -func (e *G1) Marshal() []byte { - // Each value is a 256-bit number. - const numBytes = 256 / 8 - - if e.p.IsInfinity() { - return make([]byte, numBytes*2) - } - - e.p.MakeAffine(nil) - - xBytes := new(big.Int).Mod(e.p.x, P).Bytes() - yBytes := new(big.Int).Mod(e.p.y, P).Bytes() - - ret := make([]byte, numBytes*2) - copy(ret[1*numBytes-len(xBytes):], xBytes) - copy(ret[2*numBytes-len(yBytes):], yBytes) - - return ret -} - -// Unmarshal sets e to the result of converting the output of Marshal back into -// a group element and then returns e. -func (e *G1) Unmarshal(m []byte) ([]byte, error) { - // Each value is a 256-bit number. - const numBytes = 256 / 8 - if len(m) != 2*numBytes { - return nil, errors.New("bn256: not enough data") - } - // Unmarshal the points and check their caps - if e.p == nil { - e.p = newCurvePoint(nil) - } - e.p.x.SetBytes(m[0*numBytes : 1*numBytes]) - if e.p.x.Cmp(P) >= 0 { - return nil, errors.New("bn256: coordinate exceeds modulus") - } - e.p.y.SetBytes(m[1*numBytes : 2*numBytes]) - if e.p.y.Cmp(P) >= 0 { - return nil, errors.New("bn256: coordinate exceeds modulus") - } - // Ensure the point is on the curve - if e.p.x.Sign() == 0 && e.p.y.Sign() == 0 { - // This is the point at infinity. - e.p.y.SetInt64(1) - e.p.z.SetInt64(0) - e.p.t.SetInt64(0) - } else { - e.p.z.SetInt64(1) - e.p.t.SetInt64(1) - - if !e.p.IsOnCurve() { - return nil, errors.New("bn256: malformed point") - } - } - return m[2*numBytes:], nil -} - -// G2 is an abstract cyclic group. The zero value is suitable for use as the -// output of an operation, but cannot be used as an input. -type G2 struct { - p *twistPoint -} - -// RandomG1 returns x and g₂ˣ where x is a random, non-zero number read from r. -func RandomG2(r io.Reader) (*big.Int, *G2, error) { - var k *big.Int - var err error - - for { - k, err = rand.Int(r, Order) - if err != nil { - return nil, nil, err - } - if k.Sign() > 0 { - break - } - } - - return k, new(G2).ScalarBaseMult(k), nil -} - -func (e *G2) String() string { - return "bn256.G2" + e.p.String() -} - -// CurvePoints returns the curve points of p which includes the real -// and imaginary parts of the curve point. -func (e *G2) CurvePoints() (*gfP2, *gfP2, *gfP2, *gfP2) { - return e.p.x, e.p.y, e.p.z, e.p.t -} - -// ScalarBaseMult sets e to g*k where g is the generator of the group and -// then returns out. -func (e *G2) ScalarBaseMult(k *big.Int) *G2 { - if e.p == nil { - e.p = newTwistPoint(nil) - } - e.p.Mul(twistGen, k, new(bnPool)) - return e -} - -// ScalarMult sets e to a*k and then returns e. -func (e *G2) ScalarMult(a *G2, k *big.Int) *G2 { - if e.p == nil { - e.p = newTwistPoint(nil) - } - e.p.Mul(a.p, k, new(bnPool)) - return e -} - -// Add sets e to a+b and then returns e. -// BUG(agl): this function is not complete: a==b fails. -func (e *G2) Add(a, b *G2) *G2 { - if e.p == nil { - e.p = newTwistPoint(nil) - } - e.p.Add(a.p, b.p, new(bnPool)) - return e -} - -// Marshal converts n into a byte slice. -func (n *G2) Marshal() []byte { - // Each value is a 256-bit number. - const numBytes = 256 / 8 - - if n.p.IsInfinity() { - return make([]byte, numBytes*4) - } - - n.p.MakeAffine(nil) - - xxBytes := new(big.Int).Mod(n.p.x.x, P).Bytes() - xyBytes := new(big.Int).Mod(n.p.x.y, P).Bytes() - yxBytes := new(big.Int).Mod(n.p.y.x, P).Bytes() - yyBytes := new(big.Int).Mod(n.p.y.y, P).Bytes() - - ret := make([]byte, numBytes*4) - copy(ret[1*numBytes-len(xxBytes):], xxBytes) - copy(ret[2*numBytes-len(xyBytes):], xyBytes) - copy(ret[3*numBytes-len(yxBytes):], yxBytes) - copy(ret[4*numBytes-len(yyBytes):], yyBytes) - - return ret -} - -// Unmarshal sets e to the result of converting the output of Marshal back into -// a group element and then returns e. -func (e *G2) Unmarshal(m []byte) ([]byte, error) { - // Each value is a 256-bit number. - const numBytes = 256 / 8 - if len(m) != 4*numBytes { - return nil, errors.New("bn256: not enough data") - } - // Unmarshal the points and check their caps - if e.p == nil { - e.p = newTwistPoint(nil) - } - e.p.x.x.SetBytes(m[0*numBytes : 1*numBytes]) - if e.p.x.x.Cmp(P) >= 0 { - return nil, errors.New("bn256: coordinate exceeds modulus") - } - e.p.x.y.SetBytes(m[1*numBytes : 2*numBytes]) - if e.p.x.y.Cmp(P) >= 0 { - return nil, errors.New("bn256: coordinate exceeds modulus") - } - e.p.y.x.SetBytes(m[2*numBytes : 3*numBytes]) - if e.p.y.x.Cmp(P) >= 0 { - return nil, errors.New("bn256: coordinate exceeds modulus") - } - e.p.y.y.SetBytes(m[3*numBytes : 4*numBytes]) - if e.p.y.y.Cmp(P) >= 0 { - return nil, errors.New("bn256: coordinate exceeds modulus") - } - // Ensure the point is on the curve - if e.p.x.x.Sign() == 0 && - e.p.x.y.Sign() == 0 && - e.p.y.x.Sign() == 0 && - e.p.y.y.Sign() == 0 { - // This is the point at infinity. - e.p.y.SetOne() - e.p.z.SetZero() - e.p.t.SetZero() - } else { - e.p.z.SetOne() - e.p.t.SetOne() - - if !e.p.IsOnCurve() { - return nil, errors.New("bn256: malformed point") - } - } - return m[4*numBytes:], nil -} - -// GT is an abstract cyclic group. The zero value is suitable for use as the -// output of an operation, but cannot be used as an input. -type GT struct { - p *gfP12 -} - -func (g *GT) String() string { - return "bn256.GT" + g.p.String() -} - -// ScalarMult sets e to a*k and then returns e. -func (e *GT) ScalarMult(a *GT, k *big.Int) *GT { - if e.p == nil { - e.p = newGFp12(nil) - } - e.p.Exp(a.p, k, new(bnPool)) - return e -} - -// Add sets e to a+b and then returns e. -func (e *GT) Add(a, b *GT) *GT { - if e.p == nil { - e.p = newGFp12(nil) - } - e.p.Mul(a.p, b.p, new(bnPool)) - return e -} - -// Neg sets e to -a and then returns e. -func (e *GT) Neg(a *GT) *GT { - if e.p == nil { - e.p = newGFp12(nil) - } - e.p.Invert(a.p, new(bnPool)) - return e -} - -// Marshal converts n into a byte slice. -func (n *GT) Marshal() []byte { - n.p.Minimal() - - xxxBytes := n.p.x.x.x.Bytes() - xxyBytes := n.p.x.x.y.Bytes() - xyxBytes := n.p.x.y.x.Bytes() - xyyBytes := n.p.x.y.y.Bytes() - xzxBytes := n.p.x.z.x.Bytes() - xzyBytes := n.p.x.z.y.Bytes() - yxxBytes := n.p.y.x.x.Bytes() - yxyBytes := n.p.y.x.y.Bytes() - yyxBytes := n.p.y.y.x.Bytes() - yyyBytes := n.p.y.y.y.Bytes() - yzxBytes := n.p.y.z.x.Bytes() - yzyBytes := n.p.y.z.y.Bytes() - - // Each value is a 256-bit number. - const numBytes = 256 / 8 - - ret := make([]byte, numBytes*12) - copy(ret[1*numBytes-len(xxxBytes):], xxxBytes) - copy(ret[2*numBytes-len(xxyBytes):], xxyBytes) - copy(ret[3*numBytes-len(xyxBytes):], xyxBytes) - copy(ret[4*numBytes-len(xyyBytes):], xyyBytes) - copy(ret[5*numBytes-len(xzxBytes):], xzxBytes) - copy(ret[6*numBytes-len(xzyBytes):], xzyBytes) - copy(ret[7*numBytes-len(yxxBytes):], yxxBytes) - copy(ret[8*numBytes-len(yxyBytes):], yxyBytes) - copy(ret[9*numBytes-len(yyxBytes):], yyxBytes) - copy(ret[10*numBytes-len(yyyBytes):], yyyBytes) - copy(ret[11*numBytes-len(yzxBytes):], yzxBytes) - copy(ret[12*numBytes-len(yzyBytes):], yzyBytes) - - return ret -} - -// Unmarshal sets e to the result of converting the output of Marshal back into -// a group element and then returns e. -func (e *GT) Unmarshal(m []byte) (*GT, bool) { - // Each value is a 256-bit number. - const numBytes = 256 / 8 - - if len(m) != 12*numBytes { - return nil, false - } - - if e.p == nil { - e.p = newGFp12(nil) - } - - e.p.x.x.x.SetBytes(m[0*numBytes : 1*numBytes]) - e.p.x.x.y.SetBytes(m[1*numBytes : 2*numBytes]) - e.p.x.y.x.SetBytes(m[2*numBytes : 3*numBytes]) - e.p.x.y.y.SetBytes(m[3*numBytes : 4*numBytes]) - e.p.x.z.x.SetBytes(m[4*numBytes : 5*numBytes]) - e.p.x.z.y.SetBytes(m[5*numBytes : 6*numBytes]) - e.p.y.x.x.SetBytes(m[6*numBytes : 7*numBytes]) - e.p.y.x.y.SetBytes(m[7*numBytes : 8*numBytes]) - e.p.y.y.x.SetBytes(m[8*numBytes : 9*numBytes]) - e.p.y.y.y.SetBytes(m[9*numBytes : 10*numBytes]) - e.p.y.z.x.SetBytes(m[10*numBytes : 11*numBytes]) - e.p.y.z.y.SetBytes(m[11*numBytes : 12*numBytes]) - - return e, true -} - -// Pair calculates an Optimal Ate pairing. -func Pair(g1 *G1, g2 *G2) *GT { - return >{optimalAte(g2.p, g1.p, new(bnPool))} -} - -// PairingCheck calculates the Optimal Ate pairing for a set of points. -func PairingCheck(a []*G1, b []*G2) bool { - pool := new(bnPool) - - acc := newGFp12(pool) - acc.SetOne() - - for i := 0; i < len(a); i++ { - if a[i].p.IsInfinity() || b[i].p.IsInfinity() { - continue - } - acc.Mul(acc, miller(b[i].p, a[i].p, pool), pool) - } - ret := finalExponentiation(acc, pool) - acc.Put(pool) - - return ret.IsOne() -} - -// bnPool implements a tiny cache of *big.Int objects that's used to reduce the -// number of allocations made during processing. -type bnPool struct { - bns []*big.Int - count int -} - -func (pool *bnPool) Get() *big.Int { - if pool == nil { - return new(big.Int) - } - - pool.count++ - l := len(pool.bns) - if l == 0 { - return new(big.Int) - } - - bn := pool.bns[l-1] - pool.bns = pool.bns[:l-1] - return bn -} - -func (pool *bnPool) Put(bn *big.Int) { - if pool == nil { - return - } - pool.bns = append(pool.bns, bn) - pool.count-- -} - -func (pool *bnPool) Count() int { - return pool.count -} diff --git a/crypto/bn256/google/bn256_test.go b/crypto/bn256/google/bn256_test.go deleted file mode 100644 index a4497ada9b..0000000000 --- a/crypto/bn256/google/bn256_test.go +++ /dev/null @@ -1,311 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package bn256 - -import ( - "bytes" - "crypto/rand" - "math/big" - "testing" -) - -func TestGFp2Invert(t *testing.T) { - pool := new(bnPool) - - a := newGFp2(pool) - a.x.SetString("23423492374", 10) - a.y.SetString("12934872398472394827398470", 10) - - inv := newGFp2(pool) - inv.Invert(a, pool) - - b := newGFp2(pool).Mul(inv, a, pool) - if b.x.Int64() != 0 || b.y.Int64() != 1 { - t.Fatalf("bad result for a^-1*a: %s %s", b.x, b.y) - } - - a.Put(pool) - b.Put(pool) - inv.Put(pool) - - if c := pool.Count(); c > 0 { - t.Errorf("Pool count non-zero: %d\n", c) - } -} - -func isZero(n *big.Int) bool { - return new(big.Int).Mod(n, P).Int64() == 0 -} - -func isOne(n *big.Int) bool { - return new(big.Int).Mod(n, P).Int64() == 1 -} - -func TestGFp6Invert(t *testing.T) { - pool := new(bnPool) - - a := newGFp6(pool) - a.x.x.SetString("239487238491", 10) - a.x.y.SetString("2356249827341", 10) - a.y.x.SetString("082659782", 10) - a.y.y.SetString("182703523765", 10) - a.z.x.SetString("978236549263", 10) - a.z.y.SetString("64893242", 10) - - inv := newGFp6(pool) - inv.Invert(a, pool) - - b := newGFp6(pool).Mul(inv, a, pool) - if !isZero(b.x.x) || - !isZero(b.x.y) || - !isZero(b.y.x) || - !isZero(b.y.y) || - !isZero(b.z.x) || - !isOne(b.z.y) { - t.Fatalf("bad result for a^-1*a: %s", b) - } - - a.Put(pool) - b.Put(pool) - inv.Put(pool) - - if c := pool.Count(); c > 0 { - t.Errorf("Pool count non-zero: %d\n", c) - } -} - -func TestGFp12Invert(t *testing.T) { - pool := new(bnPool) - - a := newGFp12(pool) - a.x.x.x.SetString("239846234862342323958623", 10) - a.x.x.y.SetString("2359862352529835623", 10) - a.x.y.x.SetString("928836523", 10) - a.x.y.y.SetString("9856234", 10) - a.x.z.x.SetString("235635286", 10) - a.x.z.y.SetString("5628392833", 10) - a.y.x.x.SetString("252936598265329856238956532167968", 10) - a.y.x.y.SetString("23596239865236954178968", 10) - a.y.y.x.SetString("95421692834", 10) - a.y.y.y.SetString("236548", 10) - a.y.z.x.SetString("924523", 10) - a.y.z.y.SetString("12954623", 10) - - inv := newGFp12(pool) - inv.Invert(a, pool) - - b := newGFp12(pool).Mul(inv, a, pool) - if !isZero(b.x.x.x) || - !isZero(b.x.x.y) || - !isZero(b.x.y.x) || - !isZero(b.x.y.y) || - !isZero(b.x.z.x) || - !isZero(b.x.z.y) || - !isZero(b.y.x.x) || - !isZero(b.y.x.y) || - !isZero(b.y.y.x) || - !isZero(b.y.y.y) || - !isZero(b.y.z.x) || - !isOne(b.y.z.y) { - t.Fatalf("bad result for a^-1*a: %s", b) - } - - a.Put(pool) - b.Put(pool) - inv.Put(pool) - - if c := pool.Count(); c > 0 { - t.Errorf("Pool count non-zero: %d\n", c) - } -} - -func TestCurveImpl(t *testing.T) { - pool := new(bnPool) - - g := &curvePoint{ - pool.Get().SetInt64(1), - pool.Get().SetInt64(-2), - pool.Get().SetInt64(1), - pool.Get().SetInt64(0), - } - - x := pool.Get().SetInt64(32498273234) - X := newCurvePoint(pool).Mul(g, x, pool) - - y := pool.Get().SetInt64(98732423523) - Y := newCurvePoint(pool).Mul(g, y, pool) - - s1 := newCurvePoint(pool).Mul(X, y, pool).MakeAffine(pool) - s2 := newCurvePoint(pool).Mul(Y, x, pool).MakeAffine(pool) - - if s1.x.Cmp(s2.x) != 0 || - s2.x.Cmp(s1.x) != 0 { - t.Errorf("DH points don't match: (%s, %s) (%s, %s)", s1.x, s1.y, s2.x, s2.y) - } - - pool.Put(x) - X.Put(pool) - pool.Put(y) - Y.Put(pool) - s1.Put(pool) - s2.Put(pool) - g.Put(pool) - - if c := pool.Count(); c > 0 { - t.Errorf("Pool count non-zero: %d\n", c) - } -} - -func TestOrderG1(t *testing.T) { - g := new(G1).ScalarBaseMult(Order) - if !g.p.IsInfinity() { - t.Error("G1 has incorrect order") - } - - one := new(G1).ScalarBaseMult(new(big.Int).SetInt64(1)) - g.Add(g, one) - g.p.MakeAffine(nil) - if g.p.x.Cmp(one.p.x) != 0 || g.p.y.Cmp(one.p.y) != 0 { - t.Errorf("1+0 != 1 in G1") - } -} - -func TestOrderG2(t *testing.T) { - g := new(G2).ScalarBaseMult(Order) - if !g.p.IsInfinity() { - t.Error("G2 has incorrect order") - } - - one := new(G2).ScalarBaseMult(new(big.Int).SetInt64(1)) - g.Add(g, one) - g.p.MakeAffine(nil) - if g.p.x.x.Cmp(one.p.x.x) != 0 || - g.p.x.y.Cmp(one.p.x.y) != 0 || - g.p.y.x.Cmp(one.p.y.x) != 0 || - g.p.y.y.Cmp(one.p.y.y) != 0 { - t.Errorf("1+0 != 1 in G2") - } -} - -func TestOrderGT(t *testing.T) { - gt := Pair(&G1{curveGen}, &G2{twistGen}) - g := new(GT).ScalarMult(gt, Order) - if !g.p.IsOne() { - t.Error("GT has incorrect order") - } -} - -func TestBilinearity(t *testing.T) { - for i := 0; i < 2; i++ { - a, p1, _ := RandomG1(rand.Reader) - b, p2, _ := RandomG2(rand.Reader) - e1 := Pair(p1, p2) - - e2 := Pair(&G1{curveGen}, &G2{twistGen}) - e2.ScalarMult(e2, a) - e2.ScalarMult(e2, b) - - minusE2 := new(GT).Neg(e2) - e1.Add(e1, minusE2) - - if !e1.p.IsOne() { - t.Fatalf("bad pairing result: %s", e1) - } - } -} - -func TestG1Marshal(t *testing.T) { - g := new(G1).ScalarBaseMult(new(big.Int).SetInt64(1)) - form := g.Marshal() - _, err := new(G1).Unmarshal(form) - if err != nil { - t.Fatalf("failed to unmarshal") - } - - g.ScalarBaseMult(Order) - form = g.Marshal() - - g2 := new(G1) - if _, err = g2.Unmarshal(form); err != nil { - t.Fatalf("failed to unmarshal ∞") - } - if !g2.p.IsInfinity() { - t.Fatalf("∞ unmarshaled incorrectly") - } -} - -func TestG2Marshal(t *testing.T) { - g := new(G2).ScalarBaseMult(new(big.Int).SetInt64(1)) - form := g.Marshal() - _, err := new(G2).Unmarshal(form) - if err != nil { - t.Fatalf("failed to unmarshal") - } - - g.ScalarBaseMult(Order) - form = g.Marshal() - g2 := new(G2) - if _, err = g2.Unmarshal(form); err != nil { - t.Fatalf("failed to unmarshal ∞") - } - if !g2.p.IsInfinity() { - t.Fatalf("∞ unmarshaled incorrectly") - } -} - -func TestG1Identity(t *testing.T) { - g := new(G1).ScalarBaseMult(new(big.Int).SetInt64(0)) - if !g.p.IsInfinity() { - t.Error("failure") - } -} - -func TestG2Identity(t *testing.T) { - g := new(G2).ScalarBaseMult(new(big.Int).SetInt64(0)) - if !g.p.IsInfinity() { - t.Error("failure") - } -} - -func TestTripartiteDiffieHellman(t *testing.T) { - a, _ := rand.Int(rand.Reader, Order) - b, _ := rand.Int(rand.Reader, Order) - c, _ := rand.Int(rand.Reader, Order) - - pa := new(G1) - pa.Unmarshal(new(G1).ScalarBaseMult(a).Marshal()) - qa := new(G2) - qa.Unmarshal(new(G2).ScalarBaseMult(a).Marshal()) - pb := new(G1) - pb.Unmarshal(new(G1).ScalarBaseMult(b).Marshal()) - qb := new(G2) - qb.Unmarshal(new(G2).ScalarBaseMult(b).Marshal()) - pc := new(G1) - pc.Unmarshal(new(G1).ScalarBaseMult(c).Marshal()) - qc := new(G2) - qc.Unmarshal(new(G2).ScalarBaseMult(c).Marshal()) - - k1 := Pair(pb, qc) - k1.ScalarMult(k1, a) - k1Bytes := k1.Marshal() - - k2 := Pair(pc, qa) - k2.ScalarMult(k2, b) - k2Bytes := k2.Marshal() - - k3 := Pair(pa, qb) - k3.ScalarMult(k3, c) - k3Bytes := k3.Marshal() - - if !bytes.Equal(k1Bytes, k2Bytes) || !bytes.Equal(k2Bytes, k3Bytes) { - t.Errorf("keys didn't agree") - } -} - -func BenchmarkPairing(b *testing.B) { - for i := 0; i < b.N; i++ { - Pair(&G1{curveGen}, &G2{twistGen}) - } -} diff --git a/crypto/bn256/google/constants.go b/crypto/bn256/google/constants.go deleted file mode 100644 index 2990bd9512..0000000000 --- a/crypto/bn256/google/constants.go +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package bn256 - -import ( - "math/big" -) - -func bigFromBase10(s string) *big.Int { - n, _ := new(big.Int).SetString(s, 10) - return n -} - -// u is the BN parameter that determines the prime. -var u = bigFromBase10("4965661367192848881") - -// P is a prime over which we form a basic field: 36u⁴+36u³+24u²+6u+1. -var P = bigFromBase10("21888242871839275222246405745257275088696311157297823662689037894645226208583") - -// Order is the number of elements in both G₁ and G₂: 36u⁴+36u³+18u²+6u+1. -// Needs to be highly 2-adic for efficient SNARK key and proof generation. -// Order - 1 = 2^28 * 3^2 * 13 * 29 * 983 * 11003 * 237073 * 405928799 * 1670836401704629 * 13818364434197438864469338081. -// Refer to https://eprint.iacr.org/2013/879.pdf and https://eprint.iacr.org/2013/507.pdf for more information on these parameters. -var Order = bigFromBase10("21888242871839275222246405745257275088548364400416034343698204186575808495617") - -// xiToPMinus1Over6 is ξ^((p-1)/6) where ξ = i+9. -var xiToPMinus1Over6 = &gfP2{bigFromBase10("16469823323077808223889137241176536799009286646108169935659301613961712198316"), bigFromBase10("8376118865763821496583973867626364092589906065868298776909617916018768340080")} - -// xiToPMinus1Over3 is ξ^((p-1)/3) where ξ = i+9. -var xiToPMinus1Over3 = &gfP2{bigFromBase10("10307601595873709700152284273816112264069230130616436755625194854815875713954"), bigFromBase10("21575463638280843010398324269430826099269044274347216827212613867836435027261")} - -// xiToPMinus1Over2 is ξ^((p-1)/2) where ξ = i+9. -var xiToPMinus1Over2 = &gfP2{bigFromBase10("3505843767911556378687030309984248845540243509899259641013678093033130930403"), bigFromBase10("2821565182194536844548159561693502659359617185244120367078079554186484126554")} - -// xiToPSquaredMinus1Over3 is ξ^((p²-1)/3) where ξ = i+9. -var xiToPSquaredMinus1Over3 = bigFromBase10("21888242871839275220042445260109153167277707414472061641714758635765020556616") - -// xiTo2PSquaredMinus2Over3 is ξ^((2p²-2)/3) where ξ = i+9 (a cubic root of unity, mod p). -var xiTo2PSquaredMinus2Over3 = bigFromBase10("2203960485148121921418603742825762020974279258880205651966") - -// xiToPSquaredMinus1Over6 is ξ^((1p²-1)/6) where ξ = i+9 (a cubic root of -1, mod p). -var xiToPSquaredMinus1Over6 = bigFromBase10("21888242871839275220042445260109153167277707414472061641714758635765020556617") - -// xiTo2PMinus2Over3 is ξ^((2p-2)/3) where ξ = i+9. -var xiTo2PMinus2Over3 = &gfP2{bigFromBase10("19937756971775647987995932169929341994314640652964949448313374472400716661030"), bigFromBase10("2581911344467009335267311115468803099551665605076196740867805258568234346338")} diff --git a/crypto/bn256/google/curve.go b/crypto/bn256/google/curve.go deleted file mode 100644 index 819cb81da7..0000000000 --- a/crypto/bn256/google/curve.go +++ /dev/null @@ -1,286 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package bn256 - -import ( - "math/big" -) - -// curvePoint implements the elliptic curve y²=x³+3. Points are kept in -// Jacobian form and t=z² when valid. G₁ is the set of points of this curve on -// GF(p). -type curvePoint struct { - x, y, z, t *big.Int -} - -var curveB = new(big.Int).SetInt64(3) - -// curveGen is the generator of G₁. -var curveGen = &curvePoint{ - new(big.Int).SetInt64(1), - new(big.Int).SetInt64(2), - new(big.Int).SetInt64(1), - new(big.Int).SetInt64(1), -} - -func newCurvePoint(pool *bnPool) *curvePoint { - return &curvePoint{ - pool.Get(), - pool.Get(), - pool.Get(), - pool.Get(), - } -} - -func (c *curvePoint) String() string { - c.MakeAffine(new(bnPool)) - return "(" + c.x.String() + ", " + c.y.String() + ")" -} - -func (c *curvePoint) Put(pool *bnPool) { - pool.Put(c.x) - pool.Put(c.y) - pool.Put(c.z) - pool.Put(c.t) -} - -func (c *curvePoint) Set(a *curvePoint) { - c.x.Set(a.x) - c.y.Set(a.y) - c.z.Set(a.z) - c.t.Set(a.t) -} - -// IsOnCurve returns true iff c is on the curve where c must be in affine form. -func (c *curvePoint) IsOnCurve() bool { - yy := new(big.Int).Mul(c.y, c.y) - xxx := new(big.Int).Mul(c.x, c.x) - xxx.Mul(xxx, c.x) - yy.Sub(yy, xxx) - yy.Sub(yy, curveB) - if yy.Sign() < 0 || yy.Cmp(P) >= 0 { - yy.Mod(yy, P) - } - return yy.Sign() == 0 -} - -func (c *curvePoint) SetInfinity() { - c.z.SetInt64(0) -} - -func (c *curvePoint) IsInfinity() bool { - return c.z.Sign() == 0 -} - -func (c *curvePoint) Add(a, b *curvePoint, pool *bnPool) { - if a.IsInfinity() { - c.Set(b) - return - } - if b.IsInfinity() { - c.Set(a) - return - } - - // See http://hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/addition/add-2007-bl.op3 - - // Normalize the points by replacing a = [x1:y1:z1] and b = [x2:y2:z2] - // by [u1:s1:z1·z2] and [u2:s2:z1·z2] - // where u1 = x1·z2², s1 = y1·z2³ and u1 = x2·z1², s2 = y2·z1³ - z1z1 := pool.Get().Mul(a.z, a.z) - z1z1.Mod(z1z1, P) - z2z2 := pool.Get().Mul(b.z, b.z) - z2z2.Mod(z2z2, P) - u1 := pool.Get().Mul(a.x, z2z2) - u1.Mod(u1, P) - u2 := pool.Get().Mul(b.x, z1z1) - u2.Mod(u2, P) - - t := pool.Get().Mul(b.z, z2z2) - t.Mod(t, P) - s1 := pool.Get().Mul(a.y, t) - s1.Mod(s1, P) - - t.Mul(a.z, z1z1) - t.Mod(t, P) - s2 := pool.Get().Mul(b.y, t) - s2.Mod(s2, P) - - // Compute x = (2h)²(s²-u1-u2) - // where s = (s2-s1)/(u2-u1) is the slope of the line through - // (u1,s1) and (u2,s2). The extra factor 2h = 2(u2-u1) comes from the value of z below. - // This is also: - // 4(s2-s1)² - 4h²(u1+u2) = 4(s2-s1)² - 4h³ - 4h²(2u1) - // = r² - j - 2v - // with the notations below. - h := pool.Get().Sub(u2, u1) - xEqual := h.Sign() == 0 - - t.Add(h, h) - // i = 4h² - i := pool.Get().Mul(t, t) - i.Mod(i, P) - // j = 4h³ - j := pool.Get().Mul(h, i) - j.Mod(j, P) - - t.Sub(s2, s1) - yEqual := t.Sign() == 0 - if xEqual && yEqual { - c.Double(a, pool) - return - } - r := pool.Get().Add(t, t) - - v := pool.Get().Mul(u1, i) - v.Mod(v, P) - - // t4 = 4(s2-s1)² - t4 := pool.Get().Mul(r, r) - t4.Mod(t4, P) - t.Add(v, v) - t6 := pool.Get().Sub(t4, j) - c.x.Sub(t6, t) - - // Set y = -(2h)³(s1 + s*(x/4h²-u1)) - // This is also - // y = - 2·s1·j - (s2-s1)(2x - 2i·u1) = r(v-x) - 2·s1·j - t.Sub(v, c.x) // t7 - t4.Mul(s1, j) // t8 - t4.Mod(t4, P) - t6.Add(t4, t4) // t9 - t4.Mul(r, t) // t10 - t4.Mod(t4, P) - c.y.Sub(t4, t6) - - // Set z = 2(u2-u1)·z1·z2 = 2h·z1·z2 - t.Add(a.z, b.z) // t11 - t4.Mul(t, t) // t12 - t4.Mod(t4, P) - t.Sub(t4, z1z1) // t13 - t4.Sub(t, z2z2) // t14 - c.z.Mul(t4, h) - c.z.Mod(c.z, P) - - pool.Put(z1z1) - pool.Put(z2z2) - pool.Put(u1) - pool.Put(u2) - pool.Put(t) - pool.Put(s1) - pool.Put(s2) - pool.Put(h) - pool.Put(i) - pool.Put(j) - pool.Put(r) - pool.Put(v) - pool.Put(t4) - pool.Put(t6) -} - -func (c *curvePoint) Double(a *curvePoint, pool *bnPool) { - // See http://hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/doubling/dbl-2009-l.op3 - A := pool.Get().Mul(a.x, a.x) - A.Mod(A, P) - B := pool.Get().Mul(a.y, a.y) - B.Mod(B, P) - C_ := pool.Get().Mul(B, B) - C_.Mod(C_, P) - - t := pool.Get().Add(a.x, B) - t2 := pool.Get().Mul(t, t) - t2.Mod(t2, P) - t.Sub(t2, A) - t2.Sub(t, C_) - d := pool.Get().Add(t2, t2) - t.Add(A, A) - e := pool.Get().Add(t, A) - f := pool.Get().Mul(e, e) - f.Mod(f, P) - - t.Add(d, d) - c.x.Sub(f, t) - - t.Add(C_, C_) - t2.Add(t, t) - t.Add(t2, t2) - c.y.Sub(d, c.x) - t2.Mul(e, c.y) - t2.Mod(t2, P) - c.y.Sub(t2, t) - - t.Mul(a.y, a.z) - t.Mod(t, P) - c.z.Add(t, t) - - pool.Put(A) - pool.Put(B) - pool.Put(C_) - pool.Put(t) - pool.Put(t2) - pool.Put(d) - pool.Put(e) - pool.Put(f) -} - -func (c *curvePoint) Mul(a *curvePoint, scalar *big.Int, pool *bnPool) *curvePoint { - sum := newCurvePoint(pool) - sum.SetInfinity() - t := newCurvePoint(pool) - - for i := scalar.BitLen(); i >= 0; i-- { - t.Double(sum, pool) - if scalar.Bit(i) != 0 { - sum.Add(t, a, pool) - } else { - sum.Set(t) - } - } - - c.Set(sum) - sum.Put(pool) - t.Put(pool) - return c -} - -// MakeAffine converts c to affine form and returns c. If c is ∞, then it sets -// c to 0 : 1 : 0. -func (c *curvePoint) MakeAffine(pool *bnPool) *curvePoint { - if words := c.z.Bits(); len(words) == 1 && words[0] == 1 { - return c - } - if c.IsInfinity() { - c.x.SetInt64(0) - c.y.SetInt64(1) - c.z.SetInt64(0) - c.t.SetInt64(0) - return c - } - zInv := pool.Get().ModInverse(c.z, P) - t := pool.Get().Mul(c.y, zInv) - t.Mod(t, P) - zInv2 := pool.Get().Mul(zInv, zInv) - zInv2.Mod(zInv2, P) - c.y.Mul(t, zInv2) - c.y.Mod(c.y, P) - t.Mul(c.x, zInv2) - t.Mod(t, P) - c.x.Set(t) - c.z.SetInt64(1) - c.t.SetInt64(1) - - pool.Put(zInv) - pool.Put(t) - pool.Put(zInv2) - - return c -} - -func (c *curvePoint) Negative(a *curvePoint) { - c.x.Set(a.x) - c.y.Neg(a.y) - c.z.Set(a.z) - c.t.SetInt64(0) -} diff --git a/crypto/bn256/google/example_test.go b/crypto/bn256/google/example_test.go deleted file mode 100644 index b2d19807a2..0000000000 --- a/crypto/bn256/google/example_test.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package bn256 - -import ( - "crypto/rand" -) - -func ExamplePair() { - // This implements the tripartite Diffie-Hellman algorithm from "A One - // Round Protocol for Tripartite Diffie-Hellman", A. Joux. - // http://www.springerlink.com/content/cddc57yyva0hburb/fulltext.pdf - - // Each of three parties, a, b and c, generate a private value. - a, _ := rand.Int(rand.Reader, Order) - b, _ := rand.Int(rand.Reader, Order) - c, _ := rand.Int(rand.Reader, Order) - - // Then each party calculates g₁ and g₂ times their private value. - pa := new(G1).ScalarBaseMult(a) - qa := new(G2).ScalarBaseMult(a) - - pb := new(G1).ScalarBaseMult(b) - qb := new(G2).ScalarBaseMult(b) - - pc := new(G1).ScalarBaseMult(c) - qc := new(G2).ScalarBaseMult(c) - - // Now each party exchanges its public values with the other two and - // all parties can calculate the shared key. - k1 := Pair(pb, qc) - k1.ScalarMult(k1, a) - - k2 := Pair(pc, qa) - k2.ScalarMult(k2, b) - - k3 := Pair(pa, qb) - k3.ScalarMult(k3, c) - - // k1, k2 and k3 will all be equal. -} diff --git a/crypto/bn256/google/gfp12.go b/crypto/bn256/google/gfp12.go deleted file mode 100644 index f084eddf21..0000000000 --- a/crypto/bn256/google/gfp12.go +++ /dev/null @@ -1,200 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package bn256 - -// For details of the algorithms used, see "Multiplication and Squaring on -// Pairing-Friendly Fields, Devegili et al. -// http://eprint.iacr.org/2006/471.pdf. - -import ( - "math/big" -) - -// gfP12 implements the field of size p¹² as a quadratic extension of gfP6 -// where ω²=τ. -type gfP12 struct { - x, y *gfP6 // value is xω + y -} - -func newGFp12(pool *bnPool) *gfP12 { - return &gfP12{newGFp6(pool), newGFp6(pool)} -} - -func (e *gfP12) String() string { - return "(" + e.x.String() + "," + e.y.String() + ")" -} - -func (e *gfP12) Put(pool *bnPool) { - e.x.Put(pool) - e.y.Put(pool) -} - -func (e *gfP12) Set(a *gfP12) *gfP12 { - e.x.Set(a.x) - e.y.Set(a.y) - return e -} - -func (e *gfP12) SetZero() *gfP12 { - e.x.SetZero() - e.y.SetZero() - return e -} - -func (e *gfP12) SetOne() *gfP12 { - e.x.SetZero() - e.y.SetOne() - return e -} - -func (e *gfP12) Minimal() { - e.x.Minimal() - e.y.Minimal() -} - -func (e *gfP12) IsZero() bool { - e.Minimal() - return e.x.IsZero() && e.y.IsZero() -} - -func (e *gfP12) IsOne() bool { - e.Minimal() - return e.x.IsZero() && e.y.IsOne() -} - -func (e *gfP12) Conjugate(a *gfP12) *gfP12 { - e.x.Negative(a.x) - e.y.Set(a.y) - return a -} - -func (e *gfP12) Negative(a *gfP12) *gfP12 { - e.x.Negative(a.x) - e.y.Negative(a.y) - return e -} - -// Frobenius computes (xω+y)^p = x^p ω·ξ^((p-1)/6) + y^p -func (e *gfP12) Frobenius(a *gfP12, pool *bnPool) *gfP12 { - e.x.Frobenius(a.x, pool) - e.y.Frobenius(a.y, pool) - e.x.MulScalar(e.x, xiToPMinus1Over6, pool) - return e -} - -// FrobeniusP2 computes (xω+y)^p² = x^p² ω·ξ^((p²-1)/6) + y^p² -func (e *gfP12) FrobeniusP2(a *gfP12, pool *bnPool) *gfP12 { - e.x.FrobeniusP2(a.x) - e.x.MulGFP(e.x, xiToPSquaredMinus1Over6) - e.y.FrobeniusP2(a.y) - return e -} - -func (e *gfP12) Add(a, b *gfP12) *gfP12 { - e.x.Add(a.x, b.x) - e.y.Add(a.y, b.y) - return e -} - -func (e *gfP12) Sub(a, b *gfP12) *gfP12 { - e.x.Sub(a.x, b.x) - e.y.Sub(a.y, b.y) - return e -} - -func (e *gfP12) Mul(a, b *gfP12, pool *bnPool) *gfP12 { - tx := newGFp6(pool) - tx.Mul(a.x, b.y, pool) - t := newGFp6(pool) - t.Mul(b.x, a.y, pool) - tx.Add(tx, t) - - ty := newGFp6(pool) - ty.Mul(a.y, b.y, pool) - t.Mul(a.x, b.x, pool) - t.MulTau(t, pool) - e.y.Add(ty, t) - e.x.Set(tx) - - tx.Put(pool) - ty.Put(pool) - t.Put(pool) - return e -} - -func (e *gfP12) MulScalar(a *gfP12, b *gfP6, pool *bnPool) *gfP12 { - e.x.Mul(e.x, b, pool) - e.y.Mul(e.y, b, pool) - return e -} - -func (c *gfP12) Exp(a *gfP12, power *big.Int, pool *bnPool) *gfP12 { - sum := newGFp12(pool) - sum.SetOne() - t := newGFp12(pool) - - for i := power.BitLen() - 1; i >= 0; i-- { - t.Square(sum, pool) - if power.Bit(i) != 0 { - sum.Mul(t, a, pool) - } else { - sum.Set(t) - } - } - - c.Set(sum) - - sum.Put(pool) - t.Put(pool) - - return c -} - -func (e *gfP12) Square(a *gfP12, pool *bnPool) *gfP12 { - // Complex squaring algorithm - v0 := newGFp6(pool) - v0.Mul(a.x, a.y, pool) - - t := newGFp6(pool) - t.MulTau(a.x, pool) - t.Add(a.y, t) - ty := newGFp6(pool) - ty.Add(a.x, a.y) - ty.Mul(ty, t, pool) - ty.Sub(ty, v0) - t.MulTau(v0, pool) - ty.Sub(ty, t) - - e.y.Set(ty) - e.x.Double(v0) - - v0.Put(pool) - t.Put(pool) - ty.Put(pool) - - return e -} - -func (e *gfP12) Invert(a *gfP12, pool *bnPool) *gfP12 { - // See "Implementing cryptographic pairings", M. Scott, section 3.2. - // ftp://136.206.11.249/pub/crypto/pairings.pdf - t1 := newGFp6(pool) - t2 := newGFp6(pool) - - t1.Square(a.x, pool) - t2.Square(a.y, pool) - t1.MulTau(t1, pool) - t1.Sub(t2, t1) - t2.Invert(t1, pool) - - e.x.Negative(a.x) - e.y.Set(a.y) - e.MulScalar(e, t2, pool) - - t1.Put(pool) - t2.Put(pool) - - return e -} diff --git a/crypto/bn256/google/gfp2.go b/crypto/bn256/google/gfp2.go deleted file mode 100644 index 3981f6cb4f..0000000000 --- a/crypto/bn256/google/gfp2.go +++ /dev/null @@ -1,227 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package bn256 - -// For details of the algorithms used, see "Multiplication and Squaring on -// Pairing-Friendly Fields, Devegili et al. -// http://eprint.iacr.org/2006/471.pdf. - -import ( - "math/big" -) - -// gfP2 implements a field of size p² as a quadratic extension of the base -// field where i²=-1. -type gfP2 struct { - x, y *big.Int // value is xi+y. -} - -func newGFp2(pool *bnPool) *gfP2 { - return &gfP2{pool.Get(), pool.Get()} -} - -func (e *gfP2) String() string { - x := new(big.Int).Mod(e.x, P) - y := new(big.Int).Mod(e.y, P) - return "(" + x.String() + "," + y.String() + ")" -} - -func (e *gfP2) Put(pool *bnPool) { - pool.Put(e.x) - pool.Put(e.y) -} - -func (e *gfP2) Set(a *gfP2) *gfP2 { - e.x.Set(a.x) - e.y.Set(a.y) - return e -} - -func (e *gfP2) SetZero() *gfP2 { - e.x.SetInt64(0) - e.y.SetInt64(0) - return e -} - -func (e *gfP2) SetOne() *gfP2 { - e.x.SetInt64(0) - e.y.SetInt64(1) - return e -} - -func (e *gfP2) Minimal() { - if e.x.Sign() < 0 || e.x.Cmp(P) >= 0 { - e.x.Mod(e.x, P) - } - if e.y.Sign() < 0 || e.y.Cmp(P) >= 0 { - e.y.Mod(e.y, P) - } -} - -func (e *gfP2) IsZero() bool { - return e.x.Sign() == 0 && e.y.Sign() == 0 -} - -func (e *gfP2) IsOne() bool { - if e.x.Sign() != 0 { - return false - } - words := e.y.Bits() - return len(words) == 1 && words[0] == 1 -} - -func (e *gfP2) Conjugate(a *gfP2) *gfP2 { - e.y.Set(a.y) - e.x.Neg(a.x) - return e -} - -func (e *gfP2) Negative(a *gfP2) *gfP2 { - e.x.Neg(a.x) - e.y.Neg(a.y) - return e -} - -func (e *gfP2) Add(a, b *gfP2) *gfP2 { - e.x.Add(a.x, b.x) - e.y.Add(a.y, b.y) - return e -} - -func (e *gfP2) Sub(a, b *gfP2) *gfP2 { - e.x.Sub(a.x, b.x) - e.y.Sub(a.y, b.y) - return e -} - -func (e *gfP2) Double(a *gfP2) *gfP2 { - e.x.Lsh(a.x, 1) - e.y.Lsh(a.y, 1) - return e -} - -func (c *gfP2) Exp(a *gfP2, power *big.Int, pool *bnPool) *gfP2 { - sum := newGFp2(pool) - sum.SetOne() - t := newGFp2(pool) - - for i := power.BitLen() - 1; i >= 0; i-- { - t.Square(sum, pool) - if power.Bit(i) != 0 { - sum.Mul(t, a, pool) - } else { - sum.Set(t) - } - } - - c.Set(sum) - - sum.Put(pool) - t.Put(pool) - - return c -} - -// See "Multiplication and Squaring in Pairing-Friendly Fields", -// http://eprint.iacr.org/2006/471.pdf -func (e *gfP2) Mul(a, b *gfP2, pool *bnPool) *gfP2 { - tx := pool.Get().Mul(a.x, b.y) - t := pool.Get().Mul(b.x, a.y) - tx.Add(tx, t) - tx.Mod(tx, P) - - ty := pool.Get().Mul(a.y, b.y) - t.Mul(a.x, b.x) - ty.Sub(ty, t) - e.y.Mod(ty, P) - e.x.Set(tx) - - pool.Put(tx) - pool.Put(ty) - pool.Put(t) - - return e -} - -func (e *gfP2) MulScalar(a *gfP2, b *big.Int) *gfP2 { - e.x.Mul(a.x, b) - e.y.Mul(a.y, b) - return e -} - -// MulXi sets e=ξa where ξ=i+9 and then returns e. -func (e *gfP2) MulXi(a *gfP2, pool *bnPool) *gfP2 { - // (xi+y)(i+3) = (9x+y)i+(9y-x) - tx := pool.Get().Lsh(a.x, 3) - tx.Add(tx, a.x) - tx.Add(tx, a.y) - - ty := pool.Get().Lsh(a.y, 3) - ty.Add(ty, a.y) - ty.Sub(ty, a.x) - - e.x.Set(tx) - e.y.Set(ty) - - pool.Put(tx) - pool.Put(ty) - - return e -} - -func (e *gfP2) Square(a *gfP2, pool *bnPool) *gfP2 { - // Complex squaring algorithm: - // (xi+b)² = (x+y)(y-x) + 2*i*x*y - t1 := pool.Get().Sub(a.y, a.x) - t2 := pool.Get().Add(a.x, a.y) - ty := pool.Get().Mul(t1, t2) - ty.Mod(ty, P) - - t1.Mul(a.x, a.y) - t1.Lsh(t1, 1) - - e.x.Mod(t1, P) - e.y.Set(ty) - - pool.Put(t1) - pool.Put(t2) - pool.Put(ty) - - return e -} - -func (e *gfP2) Invert(a *gfP2, pool *bnPool) *gfP2 { - // See "Implementing cryptographic pairings", M. Scott, section 3.2. - // ftp://136.206.11.249/pub/crypto/pairings.pdf - t := pool.Get() - t.Mul(a.y, a.y) - t2 := pool.Get() - t2.Mul(a.x, a.x) - t.Add(t, t2) - - inv := pool.Get() - inv.ModInverse(t, P) - - e.x.Neg(a.x) - e.x.Mul(e.x, inv) - e.x.Mod(e.x, P) - - e.y.Mul(a.y, inv) - e.y.Mod(e.y, P) - - pool.Put(t) - pool.Put(t2) - pool.Put(inv) - - return e -} - -func (e *gfP2) Real() *big.Int { - return e.x -} - -func (e *gfP2) Imag() *big.Int { - return e.y -} diff --git a/crypto/bn256/google/gfp6.go b/crypto/bn256/google/gfp6.go deleted file mode 100644 index 218856617c..0000000000 --- a/crypto/bn256/google/gfp6.go +++ /dev/null @@ -1,296 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package bn256 - -// For details of the algorithms used, see "Multiplication and Squaring on -// Pairing-Friendly Fields, Devegili et al. -// http://eprint.iacr.org/2006/471.pdf. - -import ( - "math/big" -) - -// gfP6 implements the field of size p⁶ as a cubic extension of gfP2 where τ³=ξ -// and ξ=i+9. -type gfP6 struct { - x, y, z *gfP2 // value is xτ² + yτ + z -} - -func newGFp6(pool *bnPool) *gfP6 { - return &gfP6{newGFp2(pool), newGFp2(pool), newGFp2(pool)} -} - -func (e *gfP6) String() string { - return "(" + e.x.String() + "," + e.y.String() + "," + e.z.String() + ")" -} - -func (e *gfP6) Put(pool *bnPool) { - e.x.Put(pool) - e.y.Put(pool) - e.z.Put(pool) -} - -func (e *gfP6) Set(a *gfP6) *gfP6 { - e.x.Set(a.x) - e.y.Set(a.y) - e.z.Set(a.z) - return e -} - -func (e *gfP6) SetZero() *gfP6 { - e.x.SetZero() - e.y.SetZero() - e.z.SetZero() - return e -} - -func (e *gfP6) SetOne() *gfP6 { - e.x.SetZero() - e.y.SetZero() - e.z.SetOne() - return e -} - -func (e *gfP6) Minimal() { - e.x.Minimal() - e.y.Minimal() - e.z.Minimal() -} - -func (e *gfP6) IsZero() bool { - return e.x.IsZero() && e.y.IsZero() && e.z.IsZero() -} - -func (e *gfP6) IsOne() bool { - return e.x.IsZero() && e.y.IsZero() && e.z.IsOne() -} - -func (e *gfP6) Negative(a *gfP6) *gfP6 { - e.x.Negative(a.x) - e.y.Negative(a.y) - e.z.Negative(a.z) - return e -} - -func (e *gfP6) Frobenius(a *gfP6, pool *bnPool) *gfP6 { - e.x.Conjugate(a.x) - e.y.Conjugate(a.y) - e.z.Conjugate(a.z) - - e.x.Mul(e.x, xiTo2PMinus2Over3, pool) - e.y.Mul(e.y, xiToPMinus1Over3, pool) - return e -} - -// FrobeniusP2 computes (xτ²+yτ+z)^(p²) = xτ^(2p²) + yτ^(p²) + z -func (e *gfP6) FrobeniusP2(a *gfP6) *gfP6 { - // τ^(2p²) = τ²τ^(2p²-2) = τ²ξ^((2p²-2)/3) - e.x.MulScalar(a.x, xiTo2PSquaredMinus2Over3) - // τ^(p²) = ττ^(p²-1) = τξ^((p²-1)/3) - e.y.MulScalar(a.y, xiToPSquaredMinus1Over3) - e.z.Set(a.z) - return e -} - -func (e *gfP6) Add(a, b *gfP6) *gfP6 { - e.x.Add(a.x, b.x) - e.y.Add(a.y, b.y) - e.z.Add(a.z, b.z) - return e -} - -func (e *gfP6) Sub(a, b *gfP6) *gfP6 { - e.x.Sub(a.x, b.x) - e.y.Sub(a.y, b.y) - e.z.Sub(a.z, b.z) - return e -} - -func (e *gfP6) Double(a *gfP6) *gfP6 { - e.x.Double(a.x) - e.y.Double(a.y) - e.z.Double(a.z) - return e -} - -func (e *gfP6) Mul(a, b *gfP6, pool *bnPool) *gfP6 { - // "Multiplication and Squaring on Pairing-Friendly Fields" - // Section 4, Karatsuba method. - // http://eprint.iacr.org/2006/471.pdf - - v0 := newGFp2(pool) - v0.Mul(a.z, b.z, pool) - v1 := newGFp2(pool) - v1.Mul(a.y, b.y, pool) - v2 := newGFp2(pool) - v2.Mul(a.x, b.x, pool) - - t0 := newGFp2(pool) - t0.Add(a.x, a.y) - t1 := newGFp2(pool) - t1.Add(b.x, b.y) - tz := newGFp2(pool) - tz.Mul(t0, t1, pool) - - tz.Sub(tz, v1) - tz.Sub(tz, v2) - tz.MulXi(tz, pool) - tz.Add(tz, v0) - - t0.Add(a.y, a.z) - t1.Add(b.y, b.z) - ty := newGFp2(pool) - ty.Mul(t0, t1, pool) - ty.Sub(ty, v0) - ty.Sub(ty, v1) - t0.MulXi(v2, pool) - ty.Add(ty, t0) - - t0.Add(a.x, a.z) - t1.Add(b.x, b.z) - tx := newGFp2(pool) - tx.Mul(t0, t1, pool) - tx.Sub(tx, v0) - tx.Add(tx, v1) - tx.Sub(tx, v2) - - e.x.Set(tx) - e.y.Set(ty) - e.z.Set(tz) - - t0.Put(pool) - t1.Put(pool) - tx.Put(pool) - ty.Put(pool) - tz.Put(pool) - v0.Put(pool) - v1.Put(pool) - v2.Put(pool) - return e -} - -func (e *gfP6) MulScalar(a *gfP6, b *gfP2, pool *bnPool) *gfP6 { - e.x.Mul(a.x, b, pool) - e.y.Mul(a.y, b, pool) - e.z.Mul(a.z, b, pool) - return e -} - -func (e *gfP6) MulGFP(a *gfP6, b *big.Int) *gfP6 { - e.x.MulScalar(a.x, b) - e.y.MulScalar(a.y, b) - e.z.MulScalar(a.z, b) - return e -} - -// MulTau computes τ·(aτ²+bτ+c) = bτ²+cτ+aξ -func (e *gfP6) MulTau(a *gfP6, pool *bnPool) { - tz := newGFp2(pool) - tz.MulXi(a.x, pool) - ty := newGFp2(pool) - ty.Set(a.y) - e.y.Set(a.z) - e.x.Set(ty) - e.z.Set(tz) - tz.Put(pool) - ty.Put(pool) -} - -func (e *gfP6) Square(a *gfP6, pool *bnPool) *gfP6 { - v0 := newGFp2(pool).Square(a.z, pool) - v1 := newGFp2(pool).Square(a.y, pool) - v2 := newGFp2(pool).Square(a.x, pool) - - c0 := newGFp2(pool).Add(a.x, a.y) - c0.Square(c0, pool) - c0.Sub(c0, v1) - c0.Sub(c0, v2) - c0.MulXi(c0, pool) - c0.Add(c0, v0) - - c1 := newGFp2(pool).Add(a.y, a.z) - c1.Square(c1, pool) - c1.Sub(c1, v0) - c1.Sub(c1, v1) - xiV2 := newGFp2(pool).MulXi(v2, pool) - c1.Add(c1, xiV2) - - c2 := newGFp2(pool).Add(a.x, a.z) - c2.Square(c2, pool) - c2.Sub(c2, v0) - c2.Add(c2, v1) - c2.Sub(c2, v2) - - e.x.Set(c2) - e.y.Set(c1) - e.z.Set(c0) - - v0.Put(pool) - v1.Put(pool) - v2.Put(pool) - c0.Put(pool) - c1.Put(pool) - c2.Put(pool) - xiV2.Put(pool) - - return e -} - -func (e *gfP6) Invert(a *gfP6, pool *bnPool) *gfP6 { - // See "Implementing cryptographic pairings", M. Scott, section 3.2. - // ftp://136.206.11.249/pub/crypto/pairings.pdf - - // Here we can give a short explanation of how it works: let j be a cubic root of - // unity in GF(p²) so that 1+j+j²=0. - // Then (xτ² + yτ + z)(xj²τ² + yjτ + z)(xjτ² + yj²τ + z) - // = (xτ² + yτ + z)(Cτ²+Bτ+A) - // = (x³ξ²+y³ξ+z³-3ξxyz) = F is an element of the base field (the norm). - // - // On the other hand (xj²τ² + yjτ + z)(xjτ² + yj²τ + z) - // = τ²(y²-ξxz) + τ(ξx²-yz) + (z²-ξxy) - // - // So that's why A = (z²-ξxy), B = (ξx²-yz), C = (y²-ξxz) - t1 := newGFp2(pool) - - A := newGFp2(pool) - A.Square(a.z, pool) - t1.Mul(a.x, a.y, pool) - t1.MulXi(t1, pool) - A.Sub(A, t1) - - B := newGFp2(pool) - B.Square(a.x, pool) - B.MulXi(B, pool) - t1.Mul(a.y, a.z, pool) - B.Sub(B, t1) - - C_ := newGFp2(pool) - C_.Square(a.y, pool) - t1.Mul(a.x, a.z, pool) - C_.Sub(C_, t1) - - F := newGFp2(pool) - F.Mul(C_, a.y, pool) - F.MulXi(F, pool) - t1.Mul(A, a.z, pool) - F.Add(F, t1) - t1.Mul(B, a.x, pool) - t1.MulXi(t1, pool) - F.Add(F, t1) - - F.Invert(F, pool) - - e.x.Mul(C_, F, pool) - e.y.Mul(B, F, pool) - e.z.Mul(A, F, pool) - - t1.Put(pool) - A.Put(pool) - B.Put(pool) - C_.Put(pool) - F.Put(pool) - - return e -} diff --git a/crypto/bn256/google/main_test.go b/crypto/bn256/google/main_test.go deleted file mode 100644 index c0c85457be..0000000000 --- a/crypto/bn256/google/main_test.go +++ /dev/null @@ -1,71 +0,0 @@ -package bn256 - -import ( - "testing" - - "crypto/rand" -) - -func TestRandomG2Marshal(t *testing.T) { - for i := 0; i < 10; i++ { - n, g2, err := RandomG2(rand.Reader) - if err != nil { - t.Error(err) - continue - } - t.Logf("%v: %x\n", n, g2.Marshal()) - } -} - -func TestPairings(t *testing.T) { - a1 := new(G1).ScalarBaseMult(bigFromBase10("1")) - a2 := new(G1).ScalarBaseMult(bigFromBase10("2")) - a37 := new(G1).ScalarBaseMult(bigFromBase10("37")) - an1 := new(G1).ScalarBaseMult(bigFromBase10("21888242871839275222246405745257275088548364400416034343698204186575808495616")) - - b0 := new(G2).ScalarBaseMult(bigFromBase10("0")) - b1 := new(G2).ScalarBaseMult(bigFromBase10("1")) - b2 := new(G2).ScalarBaseMult(bigFromBase10("2")) - b27 := new(G2).ScalarBaseMult(bigFromBase10("27")) - b999 := new(G2).ScalarBaseMult(bigFromBase10("999")) - bn1 := new(G2).ScalarBaseMult(bigFromBase10("21888242871839275222246405745257275088548364400416034343698204186575808495616")) - - p1 := Pair(a1, b1) - pn1 := Pair(a1, bn1) - np1 := Pair(an1, b1) - if pn1.String() != np1.String() { - t.Error("Pairing mismatch: e(a, -b) != e(-a, b)") - } - if !PairingCheck([]*G1{a1, an1}, []*G2{b1, b1}) { - t.Error("MultiAte check gave false negative!") - } - p0 := new(GT).Add(p1, pn1) - p0_2 := Pair(a1, b0) - if p0.String() != p0_2.String() { - t.Error("Pairing mismatch: e(a, b) * e(a, -b) != 1") - } - p0_3 := new(GT).ScalarMult(p1, bigFromBase10("21888242871839275222246405745257275088548364400416034343698204186575808495617")) - if p0.String() != p0_3.String() { - t.Error("Pairing mismatch: e(a, b) has wrong order") - } - p2 := Pair(a2, b1) - p2_2 := Pair(a1, b2) - p2_3 := new(GT).ScalarMult(p1, bigFromBase10("2")) - if p2.String() != p2_2.String() { - t.Error("Pairing mismatch: e(a, b * 2) != e(a * 2, b)") - } - if p2.String() != p2_3.String() { - t.Error("Pairing mismatch: e(a, b * 2) != e(a, b) ** 2") - } - if p2.String() == p1.String() { - t.Error("Pairing is degenerate!") - } - if PairingCheck([]*G1{a1, a1}, []*G2{b1, b1}) { - t.Error("MultiAte check gave false positive!") - } - p999 := Pair(a37, b27) - p999_2 := Pair(a1, b999) - if p999.String() != p999_2.String() { - t.Error("Pairing mismatch: e(a * 37, b * 27) != e(a, b * 999)") - } -} diff --git a/crypto/bn256/google/optate.go b/crypto/bn256/google/optate.go deleted file mode 100644 index 9d6957062e..0000000000 --- a/crypto/bn256/google/optate.go +++ /dev/null @@ -1,397 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package bn256 - -func lineFunctionAdd(r, p *twistPoint, q *curvePoint, r2 *gfP2, pool *bnPool) (a, b, c *gfP2, rOut *twistPoint) { - // See the mixed addition algorithm from "Faster Computation of the - // Tate Pairing", http://arxiv.org/pdf/0904.0854v3.pdf - - B := newGFp2(pool).Mul(p.x, r.t, pool) - - D := newGFp2(pool).Add(p.y, r.z) - D.Square(D, pool) - D.Sub(D, r2) - D.Sub(D, r.t) - D.Mul(D, r.t, pool) - - H := newGFp2(pool).Sub(B, r.x) - I := newGFp2(pool).Square(H, pool) - - E := newGFp2(pool).Add(I, I) - E.Add(E, E) - - J := newGFp2(pool).Mul(H, E, pool) - - L1 := newGFp2(pool).Sub(D, r.y) - L1.Sub(L1, r.y) - - V := newGFp2(pool).Mul(r.x, E, pool) - - rOut = newTwistPoint(pool) - rOut.x.Square(L1, pool) - rOut.x.Sub(rOut.x, J) - rOut.x.Sub(rOut.x, V) - rOut.x.Sub(rOut.x, V) - - rOut.z.Add(r.z, H) - rOut.z.Square(rOut.z, pool) - rOut.z.Sub(rOut.z, r.t) - rOut.z.Sub(rOut.z, I) - - t := newGFp2(pool).Sub(V, rOut.x) - t.Mul(t, L1, pool) - t2 := newGFp2(pool).Mul(r.y, J, pool) - t2.Add(t2, t2) - rOut.y.Sub(t, t2) - - rOut.t.Square(rOut.z, pool) - - t.Add(p.y, rOut.z) - t.Square(t, pool) - t.Sub(t, r2) - t.Sub(t, rOut.t) - - t2.Mul(L1, p.x, pool) - t2.Add(t2, t2) - a = newGFp2(pool) - a.Sub(t2, t) - - c = newGFp2(pool) - c.MulScalar(rOut.z, q.y) - c.Add(c, c) - - b = newGFp2(pool) - b.SetZero() - b.Sub(b, L1) - b.MulScalar(b, q.x) - b.Add(b, b) - - B.Put(pool) - D.Put(pool) - H.Put(pool) - I.Put(pool) - E.Put(pool) - J.Put(pool) - L1.Put(pool) - V.Put(pool) - t.Put(pool) - t2.Put(pool) - - return -} - -func lineFunctionDouble(r *twistPoint, q *curvePoint, pool *bnPool) (a, b, c *gfP2, rOut *twistPoint) { - // See the doubling algorithm for a=0 from "Faster Computation of the - // Tate Pairing", http://arxiv.org/pdf/0904.0854v3.pdf - - A := newGFp2(pool).Square(r.x, pool) - B := newGFp2(pool).Square(r.y, pool) - C_ := newGFp2(pool).Square(B, pool) - - D := newGFp2(pool).Add(r.x, B) - D.Square(D, pool) - D.Sub(D, A) - D.Sub(D, C_) - D.Add(D, D) - - E := newGFp2(pool).Add(A, A) - E.Add(E, A) - - G := newGFp2(pool).Square(E, pool) - - rOut = newTwistPoint(pool) - rOut.x.Sub(G, D) - rOut.x.Sub(rOut.x, D) - - rOut.z.Add(r.y, r.z) - rOut.z.Square(rOut.z, pool) - rOut.z.Sub(rOut.z, B) - rOut.z.Sub(rOut.z, r.t) - - rOut.y.Sub(D, rOut.x) - rOut.y.Mul(rOut.y, E, pool) - t := newGFp2(pool).Add(C_, C_) - t.Add(t, t) - t.Add(t, t) - rOut.y.Sub(rOut.y, t) - - rOut.t.Square(rOut.z, pool) - - t.Mul(E, r.t, pool) - t.Add(t, t) - b = newGFp2(pool) - b.SetZero() - b.Sub(b, t) - b.MulScalar(b, q.x) - - a = newGFp2(pool) - a.Add(r.x, E) - a.Square(a, pool) - a.Sub(a, A) - a.Sub(a, G) - t.Add(B, B) - t.Add(t, t) - a.Sub(a, t) - - c = newGFp2(pool) - c.Mul(rOut.z, r.t, pool) - c.Add(c, c) - c.MulScalar(c, q.y) - - A.Put(pool) - B.Put(pool) - C_.Put(pool) - D.Put(pool) - E.Put(pool) - G.Put(pool) - t.Put(pool) - - return -} - -func mulLine(ret *gfP12, a, b, c *gfP2, pool *bnPool) { - a2 := newGFp6(pool) - a2.x.SetZero() - a2.y.Set(a) - a2.z.Set(b) - a2.Mul(a2, ret.x, pool) - t3 := newGFp6(pool).MulScalar(ret.y, c, pool) - - t := newGFp2(pool) - t.Add(b, c) - t2 := newGFp6(pool) - t2.x.SetZero() - t2.y.Set(a) - t2.z.Set(t) - ret.x.Add(ret.x, ret.y) - - ret.y.Set(t3) - - ret.x.Mul(ret.x, t2, pool) - ret.x.Sub(ret.x, a2) - ret.x.Sub(ret.x, ret.y) - a2.MulTau(a2, pool) - ret.y.Add(ret.y, a2) - - a2.Put(pool) - t3.Put(pool) - t2.Put(pool) - t.Put(pool) -} - -// sixuPlus2NAF is 6u+2 in non-adjacent form. -var sixuPlus2NAF = []int8{0, 0, 0, 1, 0, 1, 0, -1, 0, 0, 1, -1, 0, 0, 1, 0, - 0, 1, 1, 0, -1, 0, 0, 1, 0, -1, 0, 0, 0, 0, 1, 1, - 1, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 1, - 1, 0, 0, -1, 0, 0, 0, 1, 1, 0, -1, 0, 0, 1, 0, 1, 1} - -// miller implements the Miller loop for calculating the Optimal Ate pairing. -// See algorithm 1 from http://cryptojedi.org/papers/dclxvi-20100714.pdf -func miller(q *twistPoint, p *curvePoint, pool *bnPool) *gfP12 { - ret := newGFp12(pool) - ret.SetOne() - - aAffine := newTwistPoint(pool) - aAffine.Set(q) - aAffine.MakeAffine(pool) - - bAffine := newCurvePoint(pool) - bAffine.Set(p) - bAffine.MakeAffine(pool) - - minusA := newTwistPoint(pool) - minusA.Negative(aAffine, pool) - - r := newTwistPoint(pool) - r.Set(aAffine) - - r2 := newGFp2(pool) - r2.Square(aAffine.y, pool) - - for i := len(sixuPlus2NAF) - 1; i > 0; i-- { - a, b, c, newR := lineFunctionDouble(r, bAffine, pool) - if i != len(sixuPlus2NAF)-1 { - ret.Square(ret, pool) - } - - mulLine(ret, a, b, c, pool) - a.Put(pool) - b.Put(pool) - c.Put(pool) - r.Put(pool) - r = newR - - switch sixuPlus2NAF[i-1] { - case 1: - a, b, c, newR = lineFunctionAdd(r, aAffine, bAffine, r2, pool) - case -1: - a, b, c, newR = lineFunctionAdd(r, minusA, bAffine, r2, pool) - default: - continue - } - - mulLine(ret, a, b, c, pool) - a.Put(pool) - b.Put(pool) - c.Put(pool) - r.Put(pool) - r = newR - } - - // In order to calculate Q1 we have to convert q from the sextic twist - // to the full GF(p^12) group, apply the Frobenius there, and convert - // back. - // - // The twist isomorphism is (x', y') -> (xω², yω³). If we consider just - // x for a moment, then after applying the Frobenius, we have x̄ω^(2p) - // where x̄ is the conjugate of x. If we are going to apply the inverse - // isomorphism we need a value with a single coefficient of ω² so we - // rewrite this as x̄ω^(2p-2)ω². ξ⁶ = ω and, due to the construction of - // p, 2p-2 is a multiple of six. Therefore we can rewrite as - // x̄ξ^((p-1)/3)ω² and applying the inverse isomorphism eliminates the - // ω². - // - // A similar argument can be made for the y value. - - q1 := newTwistPoint(pool) - q1.x.Conjugate(aAffine.x) - q1.x.Mul(q1.x, xiToPMinus1Over3, pool) - q1.y.Conjugate(aAffine.y) - q1.y.Mul(q1.y, xiToPMinus1Over2, pool) - q1.z.SetOne() - q1.t.SetOne() - - // For Q2 we are applying the p² Frobenius. The two conjugations cancel - // out and we are left only with the factors from the isomorphism. In - // the case of x, we end up with a pure number which is why - // xiToPSquaredMinus1Over3 is ∈ GF(p). With y we get a factor of -1. We - // ignore this to end up with -Q2. - - minusQ2 := newTwistPoint(pool) - minusQ2.x.MulScalar(aAffine.x, xiToPSquaredMinus1Over3) - minusQ2.y.Set(aAffine.y) - minusQ2.z.SetOne() - minusQ2.t.SetOne() - - r2.Square(q1.y, pool) - a, b, c, newR := lineFunctionAdd(r, q1, bAffine, r2, pool) - mulLine(ret, a, b, c, pool) - a.Put(pool) - b.Put(pool) - c.Put(pool) - r.Put(pool) - r = newR - - r2.Square(minusQ2.y, pool) - a, b, c, newR = lineFunctionAdd(r, minusQ2, bAffine, r2, pool) - mulLine(ret, a, b, c, pool) - a.Put(pool) - b.Put(pool) - c.Put(pool) - r.Put(pool) - r = newR - - aAffine.Put(pool) - bAffine.Put(pool) - minusA.Put(pool) - r.Put(pool) - r2.Put(pool) - - return ret -} - -// finalExponentiation computes the (p¹²-1)/Order-th power of an element of -// GF(p¹²) to obtain an element of GT (steps 13-15 of algorithm 1 from -// http://cryptojedi.org/papers/dclxvi-20100714.pdf) -func finalExponentiation(in *gfP12, pool *bnPool) *gfP12 { - t1 := newGFp12(pool) - - // This is the p^6-Frobenius - t1.x.Negative(in.x) - t1.y.Set(in.y) - - inv := newGFp12(pool) - inv.Invert(in, pool) - t1.Mul(t1, inv, pool) - - t2 := newGFp12(pool).FrobeniusP2(t1, pool) - t1.Mul(t1, t2, pool) - - fp := newGFp12(pool).Frobenius(t1, pool) - fp2 := newGFp12(pool).FrobeniusP2(t1, pool) - fp3 := newGFp12(pool).Frobenius(fp2, pool) - - fu, fu2, fu3 := newGFp12(pool), newGFp12(pool), newGFp12(pool) - fu.Exp(t1, u, pool) - fu2.Exp(fu, u, pool) - fu3.Exp(fu2, u, pool) - - y3 := newGFp12(pool).Frobenius(fu, pool) - fu2p := newGFp12(pool).Frobenius(fu2, pool) - fu3p := newGFp12(pool).Frobenius(fu3, pool) - y2 := newGFp12(pool).FrobeniusP2(fu2, pool) - - y0 := newGFp12(pool) - y0.Mul(fp, fp2, pool) - y0.Mul(y0, fp3, pool) - - y1, y4, y5 := newGFp12(pool), newGFp12(pool), newGFp12(pool) - y1.Conjugate(t1) - y5.Conjugate(fu2) - y3.Conjugate(y3) - y4.Mul(fu, fu2p, pool) - y4.Conjugate(y4) - - y6 := newGFp12(pool) - y6.Mul(fu3, fu3p, pool) - y6.Conjugate(y6) - - t0 := newGFp12(pool) - t0.Square(y6, pool) - t0.Mul(t0, y4, pool) - t0.Mul(t0, y5, pool) - t1.Mul(y3, y5, pool) - t1.Mul(t1, t0, pool) - t0.Mul(t0, y2, pool) - t1.Square(t1, pool) - t1.Mul(t1, t0, pool) - t1.Square(t1, pool) - t0.Mul(t1, y1, pool) - t1.Mul(t1, y0, pool) - t0.Square(t0, pool) - t0.Mul(t0, t1, pool) - - inv.Put(pool) - t1.Put(pool) - t2.Put(pool) - fp.Put(pool) - fp2.Put(pool) - fp3.Put(pool) - fu.Put(pool) - fu2.Put(pool) - fu3.Put(pool) - fu2p.Put(pool) - fu3p.Put(pool) - y0.Put(pool) - y1.Put(pool) - y2.Put(pool) - y3.Put(pool) - y4.Put(pool) - y5.Put(pool) - y6.Put(pool) - - return t0 -} - -func optimalAte(a *twistPoint, b *curvePoint, pool *bnPool) *gfP12 { - e := miller(a, b, pool) - ret := finalExponentiation(e, pool) - e.Put(pool) - - if a.IsInfinity() || b.IsInfinity() { - ret.SetOne() - } - return ret -} diff --git a/crypto/bn256/google/twist.go b/crypto/bn256/google/twist.go deleted file mode 100644 index 43364ff5b7..0000000000 --- a/crypto/bn256/google/twist.go +++ /dev/null @@ -1,263 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package bn256 - -import ( - "math/big" -) - -// twistPoint implements the elliptic curve y²=x³+3/ξ over GF(p²). Points are -// kept in Jacobian form and t=z² when valid. The group G₂ is the set of -// n-torsion points of this curve over GF(p²) (where n = Order) -type twistPoint struct { - x, y, z, t *gfP2 -} - -var twistB = &gfP2{ - bigFromBase10("266929791119991161246907387137283842545076965332900288569378510910307636690"), - bigFromBase10("19485874751759354771024239261021720505790618469301721065564631296452457478373"), -} - -// twistGen is the generator of group G₂. -var twistGen = &twistPoint{ - &gfP2{ - bigFromBase10("11559732032986387107991004021392285783925812861821192530917403151452391805634"), - bigFromBase10("10857046999023057135944570762232829481370756359578518086990519993285655852781"), - }, - &gfP2{ - bigFromBase10("4082367875863433681332203403145435568316851327593401208105741076214120093531"), - bigFromBase10("8495653923123431417604973247489272438418190587263600148770280649306958101930"), - }, - &gfP2{ - bigFromBase10("0"), - bigFromBase10("1"), - }, - &gfP2{ - bigFromBase10("0"), - bigFromBase10("1"), - }, -} - -func newTwistPoint(pool *bnPool) *twistPoint { - return &twistPoint{ - newGFp2(pool), - newGFp2(pool), - newGFp2(pool), - newGFp2(pool), - } -} - -func (c *twistPoint) String() string { - return "(" + c.x.String() + ", " + c.y.String() + ", " + c.z.String() + ")" -} - -func (c *twistPoint) Put(pool *bnPool) { - c.x.Put(pool) - c.y.Put(pool) - c.z.Put(pool) - c.t.Put(pool) -} - -func (c *twistPoint) Set(a *twistPoint) { - c.x.Set(a.x) - c.y.Set(a.y) - c.z.Set(a.z) - c.t.Set(a.t) -} - -// IsOnCurve returns true iff c is on the curve where c must be in affine form. -func (c *twistPoint) IsOnCurve() bool { - pool := new(bnPool) - yy := newGFp2(pool).Square(c.y, pool) - xxx := newGFp2(pool).Square(c.x, pool) - xxx.Mul(xxx, c.x, pool) - yy.Sub(yy, xxx) - yy.Sub(yy, twistB) - yy.Minimal() - - if yy.x.Sign() != 0 || yy.y.Sign() != 0 { - return false - } - cneg := newTwistPoint(pool) - cneg.Mul(c, Order, pool) - return cneg.z.IsZero() -} - -func (c *twistPoint) SetInfinity() { - c.z.SetZero() -} - -func (c *twistPoint) IsInfinity() bool { - return c.z.IsZero() -} - -func (c *twistPoint) Add(a, b *twistPoint, pool *bnPool) { - // For additional comments, see the same function in curve.go. - - if a.IsInfinity() { - c.Set(b) - return - } - if b.IsInfinity() { - c.Set(a) - return - } - - // See http://hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/addition/add-2007-bl.op3 - z1z1 := newGFp2(pool).Square(a.z, pool) - z2z2 := newGFp2(pool).Square(b.z, pool) - u1 := newGFp2(pool).Mul(a.x, z2z2, pool) - u2 := newGFp2(pool).Mul(b.x, z1z1, pool) - - t := newGFp2(pool).Mul(b.z, z2z2, pool) - s1 := newGFp2(pool).Mul(a.y, t, pool) - - t.Mul(a.z, z1z1, pool) - s2 := newGFp2(pool).Mul(b.y, t, pool) - - h := newGFp2(pool).Sub(u2, u1) - xEqual := h.IsZero() - - t.Add(h, h) - i := newGFp2(pool).Square(t, pool) - j := newGFp2(pool).Mul(h, i, pool) - - t.Sub(s2, s1) - yEqual := t.IsZero() - if xEqual && yEqual { - c.Double(a, pool) - return - } - r := newGFp2(pool).Add(t, t) - - v := newGFp2(pool).Mul(u1, i, pool) - - t4 := newGFp2(pool).Square(r, pool) - t.Add(v, v) - t6 := newGFp2(pool).Sub(t4, j) - c.x.Sub(t6, t) - - t.Sub(v, c.x) // t7 - t4.Mul(s1, j, pool) // t8 - t6.Add(t4, t4) // t9 - t4.Mul(r, t, pool) // t10 - c.y.Sub(t4, t6) - - t.Add(a.z, b.z) // t11 - t4.Square(t, pool) // t12 - t.Sub(t4, z1z1) // t13 - t4.Sub(t, z2z2) // t14 - c.z.Mul(t4, h, pool) - - z1z1.Put(pool) - z2z2.Put(pool) - u1.Put(pool) - u2.Put(pool) - t.Put(pool) - s1.Put(pool) - s2.Put(pool) - h.Put(pool) - i.Put(pool) - j.Put(pool) - r.Put(pool) - v.Put(pool) - t4.Put(pool) - t6.Put(pool) -} - -func (c *twistPoint) Double(a *twistPoint, pool *bnPool) { - // See http://hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/doubling/dbl-2009-l.op3 - A := newGFp2(pool).Square(a.x, pool) - B := newGFp2(pool).Square(a.y, pool) - C_ := newGFp2(pool).Square(B, pool) - - t := newGFp2(pool).Add(a.x, B) - t2 := newGFp2(pool).Square(t, pool) - t.Sub(t2, A) - t2.Sub(t, C_) - d := newGFp2(pool).Add(t2, t2) - t.Add(A, A) - e := newGFp2(pool).Add(t, A) - f := newGFp2(pool).Square(e, pool) - - t.Add(d, d) - c.x.Sub(f, t) - - t.Add(C_, C_) - t2.Add(t, t) - t.Add(t2, t2) - c.y.Sub(d, c.x) - t2.Mul(e, c.y, pool) - c.y.Sub(t2, t) - - t.Mul(a.y, a.z, pool) - c.z.Add(t, t) - - A.Put(pool) - B.Put(pool) - C_.Put(pool) - t.Put(pool) - t2.Put(pool) - d.Put(pool) - e.Put(pool) - f.Put(pool) -} - -func (c *twistPoint) Mul(a *twistPoint, scalar *big.Int, pool *bnPool) *twistPoint { - sum := newTwistPoint(pool) - sum.SetInfinity() - t := newTwistPoint(pool) - - for i := scalar.BitLen(); i >= 0; i-- { - t.Double(sum, pool) - if scalar.Bit(i) != 0 { - sum.Add(t, a, pool) - } else { - sum.Set(t) - } - } - - c.Set(sum) - sum.Put(pool) - t.Put(pool) - return c -} - -// MakeAffine converts c to affine form and returns c. If c is ∞, then it sets -// c to 0 : 1 : 0. -func (c *twistPoint) MakeAffine(pool *bnPool) *twistPoint { - if c.z.IsOne() { - return c - } - if c.IsInfinity() { - c.x.SetZero() - c.y.SetOne() - c.z.SetZero() - c.t.SetZero() - return c - } - zInv := newGFp2(pool).Invert(c.z, pool) - t := newGFp2(pool).Mul(c.y, zInv, pool) - zInv2 := newGFp2(pool).Square(zInv, pool) - c.y.Mul(t, zInv2, pool) - t.Mul(c.x, zInv2, pool) - c.x.Set(t) - c.z.SetOne() - c.t.SetOne() - - zInv.Put(pool) - t.Put(pool) - zInv2.Put(pool) - - return c -} - -func (c *twistPoint) Negative(a *twistPoint, pool *bnPool) { - c.x.Set(a.x) - c.y.SetZero() - c.y.Sub(c.y, a.y) - c.z.Set(a.z) - c.t.SetZero() -} diff --git a/go.mod b/go.mod index 3fddcd6f3e..95a99c4339 100644 --- a/go.mod +++ b/go.mod @@ -14,12 +14,14 @@ require ( github.com/aws/aws-sdk-go-v2/service/route53 v1.1.1 github.com/btcsuite/btcd v0.20.1-beta github.com/cespare/cp v0.1.0 + github.com/cloudflare/bn256 v0.0.0-20220804214613-39fbc7d184f0 // indirect github.com/cloudflare/cloudflare-go v0.14.0 github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f github.com/davecgh/go-spew v1.1.1 github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea github.com/dlclark/regexp2 v1.2.0 // indirect github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf + github.com/dominant-strategies/bn256 v0.0.0-20220930122411-fbf930a7493d // indirect github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498 github.com/edsrzf/mmap-go v1.0.0 github.com/fatih/color v1.7.0 diff --git a/go.sum b/go.sum index d14492905a..c356f90cd8 100644 --- a/go.sum +++ b/go.sum @@ -98,6 +98,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudflare/bn256 v0.0.0-20220804214613-39fbc7d184f0 h1:16lxeyrXTaV4c4Aw1Azch8MUfLsmOUpCNyuJ4jIxYg0= +github.com/cloudflare/bn256 v0.0.0-20220804214613-39fbc7d184f0/go.mod h1:T2+nZA01wQim4HFBaXa1hieVkC7OL4fNhiyrX1yMkIE= github.com/cloudflare/cloudflare-go v0.14.0 h1:gFqGlGl/5f9UGXAaKapCGUfaTCgRKKnzu2VvzMZlOFA= github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304= github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ= @@ -119,6 +121,8 @@ github.com/dlclark/regexp2 v1.2.0 h1:8sAhBGEM0dRWogWqWyQeIJnxjWO6oIjl8FKqREDsGfk github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf h1:sh8rkQZavChcmakYiSlqu2425CHyFXLZZnvm7PDpU8M= github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/dominant-strategies/bn256 v0.0.0-20220930122411-fbf930a7493d h1:hkL13khTTS48QfWmjRFWpuzhOqu6S0cjpJOzPoBEDb4= +github.com/dominant-strategies/bn256 v0.0.0-20220930122411-fbf930a7493d/go.mod h1:nvtPJPChairu4o4iX2XGrstOFpLaAgNYhrUCl5bSng4= github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498 h1:Y9vTBSsV4hSwPSj4bacAU/eSnV3dAxVpepaghAdhGoQ= github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA= github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= @@ -394,6 +398,7 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= @@ -483,6 +488,7 @@ golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200806125547-5acd03effb82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/tests/fuzzers/bn256/bn256_fuzz.go b/tests/fuzzers/bn256/bn256_fuzz.go deleted file mode 100644 index ab43a1b163..0000000000 --- a/tests/fuzzers/bn256/bn256_fuzz.go +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright 2018 Péter Szilágyi. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be found -// in the LICENSE file. - -// +build gofuzz - -package bn256 - -import ( - "bytes" - "fmt" - "io" - "math/big" - - "github.com/consensys/gnark-crypto/ecc/bn254" - cloudflare "github.com/dominant-strategies/go-quai/crypto/bn256/cloudflare" - google "github.com/dominant-strategies/go-quai/crypto/bn256/google" -) - -func getG1Points(input io.Reader) (*cloudflare.G1, *google.G1, *bn254.G1Affine) { - _, xc, err := cloudflare.RandomG1(input) - if err != nil { - // insufficient input - return nil, nil, nil - } - xg := new(google.G1) - if _, err := xg.Unmarshal(xc.Marshal()); err != nil { - panic(fmt.Sprintf("Could not marshal cloudflare -> google: %v", err)) - } - xs := new(bn254.G1Affine) - if err := xs.Unmarshal(xc.Marshal()); err != nil { - panic(fmt.Sprintf("Could not marshal cloudflare -> gnark: %v", err)) - } - return xc, xg, xs -} - -func getG2Points(input io.Reader) (*cloudflare.G2, *google.G2, *bn254.G2Affine) { - _, xc, err := cloudflare.RandomG2(input) - if err != nil { - // insufficient input - return nil, nil, nil - } - xg := new(google.G2) - if _, err := xg.Unmarshal(xc.Marshal()); err != nil { - panic(fmt.Sprintf("Could not marshal cloudflare -> google: %v", err)) - } - xs := new(bn254.G2Affine) - if err := xs.Unmarshal(xc.Marshal()); err != nil { - panic(fmt.Sprintf("Could not marshal cloudflare -> gnark: %v", err)) - } - return xc, xg, xs -} - -// FuzzAdd fuzzez bn256 addition between the Google and Cloudflare libraries. -func FuzzAdd(data []byte) int { - input := bytes.NewReader(data) - xc, xg, xs := getG1Points(input) - if xc == nil { - return 0 - } - yc, yg, ys := getG1Points(input) - if yc == nil { - return 0 - } - // Ensure both libs can parse the second curve point - // Add the two points and ensure they result in the same output - rc := new(cloudflare.G1) - rc.Add(xc, yc) - - rg := new(google.G1) - rg.Add(xg, yg) - - tmpX := new(bn254.G1Jac).FromAffine(xs) - tmpY := new(bn254.G1Jac).FromAffine(ys) - rs := new(bn254.G1Affine).FromJacobian(tmpX.AddAssign(tmpY)) - - if !bytes.Equal(rc.Marshal(), rg.Marshal()) { - panic("add mismatch: cloudflare/google") - } - - if !bytes.Equal(rc.Marshal(), rs.Marshal()) { - panic("add mismatch: cloudflare/gnark") - } - return 1 -} - -// FuzzMul fuzzez bn256 scalar multiplication between the Google and Cloudflare -// libraries. -func FuzzMul(data []byte) int { - input := bytes.NewReader(data) - pc, pg, ps := getG1Points(input) - if pc == nil { - return 0 - } - // Add the two points and ensure they result in the same output - remaining := input.Len() - if remaining == 0 { - return 0 - } - if remaining > 128 { - // The evm only ever uses 32 byte integers, we need to cap this otherwise - // we run into slow exec. A 236Kb byte integer cause oss-fuzz to report it as slow. - // 128 bytes should be fine though - return 0 - } - buf := make([]byte, remaining) - input.Read(buf) - - rc := new(cloudflare.G1) - rc.ScalarMult(pc, new(big.Int).SetBytes(buf)) - - rg := new(google.G1) - rg.ScalarMult(pg, new(big.Int).SetBytes(buf)) - - rs := new(bn254.G1Jac) - psJac := new(bn254.G1Jac).FromAffine(ps) - rs.ScalarMultiplication(psJac, new(big.Int).SetBytes(buf)) - rsAffine := new(bn254.G1Affine).FromJacobian(rs) - - if !bytes.Equal(rc.Marshal(), rg.Marshal()) { - panic("scalar mul mismatch: cloudflare/google") - } - if !bytes.Equal(rc.Marshal(), rsAffine.Marshal()) { - panic("scalar mul mismatch: cloudflare/gnark") - } - return 1 -} - -func FuzzPair(data []byte) int { - input := bytes.NewReader(data) - pc, pg, ps := getG1Points(input) - if pc == nil { - return 0 - } - tc, tg, ts := getG2Points(input) - if tc == nil { - return 0 - } - - // Pair the two points and ensure they result in the same output - clPair := cloudflare.Pair(pc, tc).Marshal() - gPair := google.Pair(pg, tg).Marshal() - if !bytes.Equal(clPair, gPair) { - panic("pairing mismatch: cloudflare/google") - } - - cPair, err := bn254.Pair([]bn254.G1Affine{*ps}, []bn254.G2Affine{*ts}) - if err != nil { - panic(fmt.Sprintf("gnark/bn254 encountered error: %v", err)) - } - if !bytes.Equal(clPair, cPair.Marshal()) { - panic("pairing mismatch: cloudflare/gnark") - } - - return 1 -}