github.com/amazechain/amc@v0.1.3/common/crypto/bn256/cloudflare/gfp2.go (about) 1 // Copyright 2023 The AmazeChain Authors 2 // This file is part of the AmazeChain library. 3 // 4 // The AmazeChain library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The AmazeChain library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the AmazeChain library. If not, see <http://www.gnu.org/licenses/>. 16 17 package bn256 18 19 // For details of the algorithms used, see "Multiplication and Squaring on 20 // Pairing-Friendly Fields, Devegili et al. 21 // http://eprint.iacr.org/2006/471.pdf. 22 23 // gfP2 implements a field of size p² as a quadratic extension of the base field 24 // where i²=-1. 25 type gfP2 struct { 26 x, y gfP // value is xi+y. 27 } 28 29 func gfP2Decode(in *gfP2) *gfP2 { 30 out := &gfP2{} 31 montDecode(&out.x, &in.x) 32 montDecode(&out.y, &in.y) 33 return out 34 } 35 36 func (e *gfP2) String() string { 37 return "(" + e.x.String() + ", " + e.y.String() + ")" 38 } 39 40 func (e *gfP2) Set(a *gfP2) *gfP2 { 41 e.x.Set(&a.x) 42 e.y.Set(&a.y) 43 return e 44 } 45 46 func (e *gfP2) SetZero() *gfP2 { 47 e.x = gfP{0} 48 e.y = gfP{0} 49 return e 50 } 51 52 func (e *gfP2) SetOne() *gfP2 { 53 e.x = gfP{0} 54 e.y = *newGFp(1) 55 return e 56 } 57 58 func (e *gfP2) IsZero() bool { 59 zero := gfP{0} 60 return e.x == zero && e.y == zero 61 } 62 63 func (e *gfP2) IsOne() bool { 64 zero, one := gfP{0}, *newGFp(1) 65 return e.x == zero && e.y == one 66 } 67 68 func (e *gfP2) Conjugate(a *gfP2) *gfP2 { 69 e.y.Set(&a.y) 70 gfpNeg(&e.x, &a.x) 71 return e 72 } 73 74 func (e *gfP2) Neg(a *gfP2) *gfP2 { 75 gfpNeg(&e.x, &a.x) 76 gfpNeg(&e.y, &a.y) 77 return e 78 } 79 80 func (e *gfP2) Add(a, b *gfP2) *gfP2 { 81 gfpAdd(&e.x, &a.x, &b.x) 82 gfpAdd(&e.y, &a.y, &b.y) 83 return e 84 } 85 86 func (e *gfP2) Sub(a, b *gfP2) *gfP2 { 87 gfpSub(&e.x, &a.x, &b.x) 88 gfpSub(&e.y, &a.y, &b.y) 89 return e 90 } 91 92 // See "Multiplication and Squaring in Pairing-Friendly Fields", 93 // http://eprint.iacr.org/2006/471.pdf 94 func (e *gfP2) Mul(a, b *gfP2) *gfP2 { 95 tx, t := &gfP{}, &gfP{} 96 gfpMul(tx, &a.x, &b.y) 97 gfpMul(t, &b.x, &a.y) 98 gfpAdd(tx, tx, t) 99 100 ty := &gfP{} 101 gfpMul(ty, &a.y, &b.y) 102 gfpMul(t, &a.x, &b.x) 103 gfpSub(ty, ty, t) 104 105 e.x.Set(tx) 106 e.y.Set(ty) 107 return e 108 } 109 110 func (e *gfP2) MulScalar(a *gfP2, b *gfP) *gfP2 { 111 gfpMul(&e.x, &a.x, b) 112 gfpMul(&e.y, &a.y, b) 113 return e 114 } 115 116 // MulXi sets e=ξa where ξ=i+9 and then returns e. 117 func (e *gfP2) MulXi(a *gfP2) *gfP2 { 118 // (xi+y)(i+9) = (9x+y)i+(9y-x) 119 tx := &gfP{} 120 gfpAdd(tx, &a.x, &a.x) 121 gfpAdd(tx, tx, tx) 122 gfpAdd(tx, tx, tx) 123 gfpAdd(tx, tx, &a.x) 124 125 gfpAdd(tx, tx, &a.y) 126 127 ty := &gfP{} 128 gfpAdd(ty, &a.y, &a.y) 129 gfpAdd(ty, ty, ty) 130 gfpAdd(ty, ty, ty) 131 gfpAdd(ty, ty, &a.y) 132 133 gfpSub(ty, ty, &a.x) 134 135 e.x.Set(tx) 136 e.y.Set(ty) 137 return e 138 } 139 140 func (e *gfP2) Square(a *gfP2) *gfP2 { 141 // Complex squaring algorithm: 142 // (xi+y)² = (x+y)(y-x) + 2*i*x*y 143 tx, ty := &gfP{}, &gfP{} 144 gfpSub(tx, &a.y, &a.x) 145 gfpAdd(ty, &a.x, &a.y) 146 gfpMul(ty, tx, ty) 147 148 gfpMul(tx, &a.x, &a.y) 149 gfpAdd(tx, tx, tx) 150 151 e.x.Set(tx) 152 e.y.Set(ty) 153 return e 154 } 155 156 func (e *gfP2) Invert(a *gfP2) *gfP2 { 157 // See "Implementing cryptographic pairings", M. Scott, section 3.2. 158 // ftp://136.206.11.249/pub/crypto/pairings.pdf 159 t1, t2 := &gfP{}, &gfP{} 160 gfpMul(t1, &a.x, &a.x) 161 gfpMul(t2, &a.y, &a.y) 162 gfpAdd(t1, t1, t2) 163 164 inv := &gfP{} 165 inv.Invert(t1) 166 167 gfpNeg(t1, &a.x) 168 169 gfpMul(&e.x, t1, inv) 170 gfpMul(&e.y, &a.y, inv) 171 return e 172 }