github.com/ethw3/go-ethereuma@v0.0.0-20221013053120-c14602a4c23c/crypto/bn256/cloudflare/gfp2.go (about) 1 package bn256 2 3 // For details of the algorithms used, see "Multiplication and Squaring on 4 // Pairing-Friendly Fields, Devegili et al. 5 // http://eprint.iacr.org/2006/471.pdf. 6 7 // gfP2 implements a field of size p² as a quadratic extension of the base field 8 // where i²=-1. 9 type gfP2 struct { 10 x, y gfP // value is xi+y. 11 } 12 13 func gfP2Decode(in *gfP2) *gfP2 { 14 out := &gfP2{} 15 montDecode(&out.x, &in.x) 16 montDecode(&out.y, &in.y) 17 return out 18 } 19 20 func (e *gfP2) String() string { 21 return "(" + e.x.String() + ", " + e.y.String() + ")" 22 } 23 24 func (e *gfP2) Set(a *gfP2) *gfP2 { 25 e.x.Set(&a.x) 26 e.y.Set(&a.y) 27 return e 28 } 29 30 func (e *gfP2) SetZero() *gfP2 { 31 e.x = gfP{0} 32 e.y = gfP{0} 33 return e 34 } 35 36 func (e *gfP2) SetOne() *gfP2 { 37 e.x = gfP{0} 38 e.y = *newGFp(1) 39 return e 40 } 41 42 func (e *gfP2) IsZero() bool { 43 zero := gfP{0} 44 return e.x == zero && e.y == zero 45 } 46 47 func (e *gfP2) IsOne() bool { 48 zero, one := gfP{0}, *newGFp(1) 49 return e.x == zero && e.y == one 50 } 51 52 func (e *gfP2) Conjugate(a *gfP2) *gfP2 { 53 e.y.Set(&a.y) 54 gfpNeg(&e.x, &a.x) 55 return e 56 } 57 58 func (e *gfP2) Neg(a *gfP2) *gfP2 { 59 gfpNeg(&e.x, &a.x) 60 gfpNeg(&e.y, &a.y) 61 return e 62 } 63 64 func (e *gfP2) Add(a, b *gfP2) *gfP2 { 65 gfpAdd(&e.x, &a.x, &b.x) 66 gfpAdd(&e.y, &a.y, &b.y) 67 return e 68 } 69 70 func (e *gfP2) Sub(a, b *gfP2) *gfP2 { 71 gfpSub(&e.x, &a.x, &b.x) 72 gfpSub(&e.y, &a.y, &b.y) 73 return e 74 } 75 76 // See "Multiplication and Squaring in Pairing-Friendly Fields", 77 // http://eprint.iacr.org/2006/471.pdf 78 func (e *gfP2) Mul(a, b *gfP2) *gfP2 { 79 tx, t := &gfP{}, &gfP{} 80 gfpMul(tx, &a.x, &b.y) 81 gfpMul(t, &b.x, &a.y) 82 gfpAdd(tx, tx, t) 83 84 ty := &gfP{} 85 gfpMul(ty, &a.y, &b.y) 86 gfpMul(t, &a.x, &b.x) 87 gfpSub(ty, ty, t) 88 89 e.x.Set(tx) 90 e.y.Set(ty) 91 return e 92 } 93 94 func (e *gfP2) MulScalar(a *gfP2, b *gfP) *gfP2 { 95 gfpMul(&e.x, &a.x, b) 96 gfpMul(&e.y, &a.y, b) 97 return e 98 } 99 100 // MulXi sets e=ξa where ξ=i+9 and then returns e. 101 func (e *gfP2) MulXi(a *gfP2) *gfP2 { 102 // (xi+y)(i+9) = (9x+y)i+(9y-x) 103 tx := &gfP{} 104 gfpAdd(tx, &a.x, &a.x) 105 gfpAdd(tx, tx, tx) 106 gfpAdd(tx, tx, tx) 107 gfpAdd(tx, tx, &a.x) 108 109 gfpAdd(tx, tx, &a.y) 110 111 ty := &gfP{} 112 gfpAdd(ty, &a.y, &a.y) 113 gfpAdd(ty, ty, ty) 114 gfpAdd(ty, ty, ty) 115 gfpAdd(ty, ty, &a.y) 116 117 gfpSub(ty, ty, &a.x) 118 119 e.x.Set(tx) 120 e.y.Set(ty) 121 return e 122 } 123 124 func (e *gfP2) Square(a *gfP2) *gfP2 { 125 // Complex squaring algorithm: 126 // (xi+y)² = (x+y)(y-x) + 2*i*x*y 127 tx, ty := &gfP{}, &gfP{} 128 gfpSub(tx, &a.y, &a.x) 129 gfpAdd(ty, &a.x, &a.y) 130 gfpMul(ty, tx, ty) 131 132 gfpMul(tx, &a.x, &a.y) 133 gfpAdd(tx, tx, tx) 134 135 e.x.Set(tx) 136 e.y.Set(ty) 137 return e 138 } 139 140 func (e *gfP2) Invert(a *gfP2) *gfP2 { 141 // See "Implementing cryptographic pairings", M. Scott, section 3.2. 142 // ftp://136.206.11.249/pub/crypto/pairings.pdf 143 t1, t2 := &gfP{}, &gfP{} 144 gfpMul(t1, &a.x, &a.x) 145 gfpMul(t2, &a.y, &a.y) 146 gfpAdd(t1, t1, t2) 147 148 inv := &gfP{} 149 inv.Invert(t1) 150 151 gfpNeg(t1, &a.x) 152 153 gfpMul(&e.x, t1, inv) 154 gfpMul(&e.y, &a.y, inv) 155 return e 156 }