Cache the field representation of d

This commit is contained in:
George Tankersley 2017-07-07 00:00:00 +00:00
parent ad98326f8c
commit 08a76875a4
4 changed files with 33 additions and 25 deletions

View File

@ -51,18 +51,18 @@ func (curve ed25519Curve) Params() *elliptic.CurveParams {
}
// IsOnCurve reports whether the given (x,y) lies on the curve by checking that
// -x^2 + y^2 - 1 - dx^2y^2 = 0 (mod p).
// -x^2 + y^2 - 1 - dx^2y^2 = 0 (mod p). This function uses a hardcoded value
// of d.
func (curve ed25519Curve) IsOnCurve(x, y *big.Int) bool {
var feX, feY, feB field.FieldElement
var feX, feY field.FieldElement
field.FeFromBig(&feX, x)
field.FeFromBig(&feY, y)
field.FeFromBig(&feB, curve.B)
var lh, y2, rh field.FieldElement
field.FeSquare(&lh, &feX) // x^2
field.FeSquare(&y2, &feY) // y^2
field.FeMul(&rh, &lh, &y2) // x^2*y^2
field.FeMul(&rh, &rh, &feB) // d*x^2*y^2
field.FeMul(&rh, &rh, &group.D) // d*x^2*y^2
field.FeAdd(&rh, &rh, &field.FieldOne) // 1 + d*x^2*y^2
field.FeNeg(&lh, &lh) // -x^2
field.FeAdd(&lh, &lh, &y2) // -x^2 + y^2

11
internal/group/const.go Normal file
View File

@ -0,0 +1,11 @@
package group
import "github.com/gtank/ed25519/internal/radix51"
var (
// d, a constant in the curve equation
D radix51.FieldElement = [5]uint64{929955233495203, 466365720129213, 1662059464998953, 2033849074728123, 1442794654840575}
// 2*d, used in addition formula
D2 radix51.FieldElement = [5]uint64{1859910466990425, 932731440258426, 1072319116312658, 1815898335770999, 633789495995903}
)

View File

@ -76,24 +76,24 @@ func (v *ExtendedGroupElement) Zero() *ExtendedGroupElement {
// TODO We know Z1=1 and Z2=1 here, so mmadd-2008-hwcd-3 (6M + 1S + 1*k + 9add) could apply
func (v *ExtendedGroupElement) Add(p1, p2 *ExtendedGroupElement) *ExtendedGroupElement {
var tmp1, tmp2, A, B, C, D, E, F, G, H field.FieldElement
field.FeSub(&tmp1, &p1.Y, &p1.X) // tmp1 <-- Y1-X1
field.FeSub(&tmp2, &p2.Y, &p2.X) // tmp2 <-- Y2-X2
field.FeMul(&A, &tmp1, &tmp2) // A <-- tmp1*tmp2 = (Y1-X1)*(Y2-X2)
field.FeAdd(&tmp1, &p1.Y, &p1.X) // tmp1 <-- Y1+X1
field.FeAdd(&tmp2, &p2.Y, &p2.X) // tmp2 <-- Y2+X2
field.FeMul(&B, &tmp1, &tmp2) // B <-- tmp1*tmp2 = (Y1+X1)*(Y2+X2)
field.FeMul(&tmp1, &p1.T, &p2.T) // tmp1 <-- T1*T2
field.FeMul(&C, &tmp1, &field.D2) // C <-- tmp1*2d = T1*2d*T2
field.FeMul(&tmp1, &p1.Z, &p2.Z) // tmp1 <-- Z1*Z2
field.FeAdd(&D, &tmp1, &tmp1) // D <-- tmp1 + tmp1 = 2*Z1*Z2
field.FeSub(&E, &B, &A) // E <-- B-A
field.FeSub(&F, &D, &C) // F <-- D-C
field.FeAdd(&G, &D, &C) // G <-- D+C
field.FeAdd(&H, &B, &A) // H <-- B+A
field.FeMul(&v.X, &E, &F) // X3 <-- E*F
field.FeMul(&v.Y, &G, &H) // Y3 <-- G*H
field.FeMul(&v.T, &E, &H) // T3 <-- E*H
field.FeMul(&v.Z, &F, &G) // Z3 <-- F*G
field.FeSub(&tmp1, &p1.Y, &p1.X) // tmp1 <-- Y1-X1
field.FeSub(&tmp2, &p2.Y, &p2.X) // tmp2 <-- Y2-X2
field.FeMul(&A, &tmp1, &tmp2) // A <-- tmp1*tmp2 = (Y1-X1)*(Y2-X2)
field.FeAdd(&tmp1, &p1.Y, &p1.X) // tmp1 <-- Y1+X1
field.FeAdd(&tmp2, &p2.Y, &p2.X) // tmp2 <-- Y2+X2
field.FeMul(&B, &tmp1, &tmp2) // B <-- tmp1*tmp2 = (Y1+X1)*(Y2+X2)
field.FeMul(&tmp1, &p1.T, &p2.T) // tmp1 <-- T1*T2
field.FeMul(&C, &tmp1, &D2) // C <-- tmp1*2d = T1*2d*T2
field.FeMul(&tmp1, &p1.Z, &p2.Z) // tmp1 <-- Z1*Z2
field.FeAdd(&D, &tmp1, &tmp1) // D <-- tmp1 + tmp1 = 2*Z1*Z2
field.FeSub(&E, &B, &A) // E <-- B-A
field.FeSub(&F, &D, &C) // F <-- D-C
field.FeAdd(&G, &D, &C) // G <-- D+C
field.FeAdd(&H, &B, &A) // H <-- B+A
field.FeMul(&v.X, &E, &F) // X3 <-- E*F
field.FeMul(&v.Y, &G, &H) // Y3 <-- G*H
field.FeMul(&v.T, &E, &H) // T3 <-- E*H
field.FeMul(&v.Z, &F, &G) // Z3 <-- F*G
return v
}

View File

@ -12,7 +12,4 @@ var (
FieldZero FieldElement = [5]uint64{0, 0, 0, 0, 0}
FieldOne FieldElement = [5]uint64{1, 0, 0, 0, 0}
FieldTwo FieldElement = [5]uint64{2, 0, 0, 0, 0}
// 2*d, used in addition formula
D2 FieldElement = [5]uint64{1859910466990425, 932731440258426, 1072319116312658, 1815898335770999, 633789495995903}
)