mirror of https://github.com/gtank/ristretto255
internal/group: rewrite DoubleZ1 because stack is cheaper than mental state
This commit is contained in:
parent
2925e841f7
commit
79589420d8
|
@ -1,4 +1,5 @@
|
||||||
// Copyright (c) 2017 George Tankersley. All rights reserved.
|
// Copyright (c) 2017 George Tankersley. All rights reserved.
|
||||||
|
// Copyright (c) 2019 The Go Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -231,44 +232,30 @@ func (v *ProjectiveGroupElement) Zero() *ProjectiveGroupElement {
|
||||||
// This assumption is one reason why this package is internal. For instance, it
|
// This assumption is one reason why this package is internal. For instance, it
|
||||||
// will not hold throughout a Montgomery ladder, when we convert to projective
|
// will not hold throughout a Montgomery ladder, when we convert to projective
|
||||||
// from possibly arbitrary extended coordinates.
|
// from possibly arbitrary extended coordinates.
|
||||||
func (v *ProjectiveGroupElement) DoubleZ1() *ProjectiveGroupElement {
|
func (v *ProjectiveGroupElement) DoubleZ1(u *ProjectiveGroupElement) *ProjectiveGroupElement {
|
||||||
// TODO This function is inconsistent with the other ones in that it
|
var B, C, D, E, F radix51.FieldElement
|
||||||
// returns a copy rather than smashing the receiver. It doesn't matter
|
|
||||||
// because it is always called on ephemeral intermediate values, but should
|
|
||||||
// fix.
|
|
||||||
var p, q ProjectiveGroupElement
|
|
||||||
var t0, t1 radix51.FieldElement
|
|
||||||
|
|
||||||
p = *v
|
if u.Z.Equal(radix51.Zero) != 1 {
|
||||||
|
panic("ed25519: DoubleZ1 called with Z != 1")
|
||||||
|
}
|
||||||
|
|
||||||
// C = X1^2, D = Y1^2
|
B.Square(B.Add(&u.X, &u.Y)) // B = (X1+Y1)^2
|
||||||
t0.Square(&p.X)
|
C.Square(&u.X) // C = X1^2
|
||||||
t1.Square(&p.Y)
|
D.Square(&u.Y) // D = Y1^2
|
||||||
|
E.Neg(&C) // E = a*C where a = -1
|
||||||
// B = (X1+Y1)^2
|
F.Add(&E, &D) // F = E + D
|
||||||
p.Z.Add(&p.X, &p.Y) // Z is irrelevant but already allocated
|
|
||||||
q.X.Square(&p.Z)
|
|
||||||
|
|
||||||
// E = a*C where a = -1
|
|
||||||
q.Z.Neg(&t0)
|
|
||||||
|
|
||||||
// F = E + D
|
|
||||||
p.X.Add(&q.Z, &t1)
|
|
||||||
|
|
||||||
// X3 = (B-C-D)*(F-2)
|
// X3 = (B-C-D)*(F-2)
|
||||||
p.Y.Sub(&q.X, &t0)
|
v.Y.Sub(v.Y.Sub(&B, &C), &D)
|
||||||
p.Y.Sub(&p.Y, &t1)
|
v.X.Mul(&v.Y, v.X.Sub(&F, radix51.Two))
|
||||||
p.Z.Sub(&p.X, radix51.Two)
|
|
||||||
q.X.Mul(&p.Y, &p.Z)
|
|
||||||
|
|
||||||
// Y3 = F*(E-D)
|
// Y3 = F*(E-D)
|
||||||
p.Y.Sub(&q.Z, &t1)
|
v.Y.Mul(&F, v.Y.Sub(&E, &D))
|
||||||
q.Y.Mul(&p.X, &p.Y)
|
|
||||||
|
|
||||||
// Z3 = F^2 - 2*F
|
// Z3 = F^2 - 2*F
|
||||||
q.Z.Square(&p.X)
|
v.Z.Square(&F)
|
||||||
q.Z.Sub(&q.Z, &p.X)
|
v.Z.Sub(&v.Z, &F)
|
||||||
q.Z.Sub(&q.Z, &p.X)
|
v.Z.Sub(&v.Z, &F)
|
||||||
|
|
||||||
return &q
|
return v
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue