Skip to content

Commit 8b1d310

Browse files
committed
bn256: explicitly fix MakeAffine for ∞
When c = ∞, z = 0 and 0 does not have a modular inverse, triggering undefined behavior (recently changed to returning nil) in ModInverse. Unclear how this used to work anyway. Looks like ModInverse was leaving the receiver untouched, making zInv = 0 when pool = nil. Fixes golang/go#25199 Change-Id: Ib39abf59f0e71cf43cdb5836142ebdd3b206fb3f Reviewed-on: https://go-review.googlesource.com/110695 Run-TryBot: Filippo Valsorda <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Filippo Valsorda <[email protected]> Reviewed-by: Adam Langley <[email protected]>
1 parent 2c241ca commit 8b1d310

File tree

3 files changed

+32
-4
lines changed

3 files changed

+32
-4
lines changed

bn256/bn256.go

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,18 @@ func (e *G1) Neg(a *G1) *G1 {
9797

9898
// Marshal converts n to a byte slice.
9999
func (e *G1) Marshal() []byte {
100+
// Each value is a 256-bit number.
101+
const numBytes = 256 / 8
102+
103+
if e.p.IsInfinity() {
104+
return make([]byte, numBytes*2)
105+
}
106+
100107
e.p.MakeAffine(nil)
101108

102109
xBytes := new(big.Int).Mod(e.p.x, p).Bytes()
103110
yBytes := new(big.Int).Mod(e.p.y, p).Bytes()
104111

105-
// Each value is a 256-bit number.
106-
const numBytes = 256 / 8
107112

108113
ret := make([]byte, numBytes*2)
109114
copy(ret[1*numBytes-len(xBytes):], xBytes)
@@ -205,15 +210,20 @@ func (e *G2) Add(a, b *G2) *G2 {
205210

206211
// Marshal converts n into a byte slice.
207212
func (n *G2) Marshal() []byte {
213+
// Each value is a 256-bit number.
214+
const numBytes = 256 / 8
215+
216+
if n.p.IsInfinity() {
217+
return make([]byte, numBytes*4)
218+
}
219+
208220
n.p.MakeAffine(nil)
209221

210222
xxBytes := new(big.Int).Mod(n.p.x.x, p).Bytes()
211223
xyBytes := new(big.Int).Mod(n.p.x.y, p).Bytes()
212224
yxBytes := new(big.Int).Mod(n.p.y.x, p).Bytes()
213225
yyBytes := new(big.Int).Mod(n.p.y.y, p).Bytes()
214226

215-
// Each value is a 256-bit number.
216-
const numBytes = 256 / 8
217227

218228
ret := make([]byte, numBytes*4)
219229
copy(ret[1*numBytes-len(xxBytes):], xxBytes)

bn256/curve.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,10 +245,19 @@ func (c *curvePoint) Mul(a *curvePoint, scalar *big.Int, pool *bnPool) *curvePoi
245245
return c
246246
}
247247

248+
// MakeAffine converts c to affine form and returns c. If c is ∞, then it sets
249+
// c to 0 : 1 : 0.
248250
func (c *curvePoint) MakeAffine(pool *bnPool) *curvePoint {
249251
if words := c.z.Bits(); len(words) == 1 && words[0] == 1 {
250252
return c
251253
}
254+
if c.IsInfinity() {
255+
c.x.SetInt64(0)
256+
c.y.SetInt64(1)
257+
c.z.SetInt64(0)
258+
c.t.SetInt64(0)
259+
return c
260+
}
252261

253262
zInv := pool.Get().ModInverse(c.z, p)
254263
t := pool.Get().Mul(c.y, zInv)

bn256/twist.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,10 +219,19 @@ func (c *twistPoint) Mul(a *twistPoint, scalar *big.Int, pool *bnPool) *twistPoi
219219
return c
220220
}
221221

222+
// MakeAffine converts c to affine form and returns c. If c is ∞, then it sets
223+
// c to 0 : 1 : 0.
222224
func (c *twistPoint) MakeAffine(pool *bnPool) *twistPoint {
223225
if c.z.IsOne() {
224226
return c
225227
}
228+
if c.IsInfinity() {
229+
c.x.SetZero()
230+
c.y.SetOne()
231+
c.z.SetZero()
232+
c.t.SetZero()
233+
return c
234+
}
226235

227236
zInv := newGFp2(pool).Invert(c.z, pool)
228237
t := newGFp2(pool).Mul(c.y, zInv, pool)

0 commit comments

Comments
 (0)