use faster FeFromBig & a horrible assortment of other random changes

This commit is contained in:
George Tankersley 2017-06-29 00:00:00 +00:00
parent 4d11c7b5a6
commit c9f6a1c183
6 changed files with 59 additions and 66 deletions

View File

@ -1,11 +0,0 @@
// Copyright (c) 2017 George Tankersley. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package ed25519
import (
"math/big"
)
var ()

View File

@ -88,7 +88,7 @@ func (curve ed25519Curve) Double(x1, y1 *big.Int) (x, y *big.Int) {
p.FromAffine(x1, y1) p.FromAffine(x1, y1)
return p.Double().ToAffine() return p.DoubleZ1().ToAffine()
} }
// ScalarMult returns k*(Bx,By) where k is a number in big-endian form. // ScalarMult returns k*(Bx,By) where k is a number in big-endian form.

View File

@ -357,39 +357,30 @@ func BenchmarkDouble(b *testing.B) {
// } // }
// } // }
// // A is a constant from the Montgomery form of curve25519. var radix51A = field.FieldElement{
// var radix25A = edwards25519.FieldElement{ 486662, 0, 0, 0, 0,
// 486662, 0, 0, 0, 0, 0, 0, 0, 0, 0, }
// }
// var radix51A = radix51.FieldElement{ func BenchmarkFeMul51(b *testing.B) {
// 486662, 0, 0, 0, 0, var h field.FieldElement
// } for i := 0; i < b.N; i++ {
field.FeMul(&h, &radix51A, &radix51A)
}
}
// func BenchmarkFeMul25(b *testing.B) { func BenchmarkFeSquare51(b *testing.B) {
// var h edwards25519.FieldElement var h field.FieldElement
// for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
// edwards25519.FeMul(&h, &radix25A, &radix25A) field.FeSquare(&h, &radix51A)
// } }
// } }
// func BenchmarkFeMul51(b *testing.B) { var concreteCurve = Ed25519().(ed25519Curve)
// var h radix51.FieldElement var randFieldInt, _ = rand.Int(rand.Reader, concreteCurve.P)
// for i := 0; i < b.N; i++ {
// radix51.FeMul(&h, &radix51A, &radix51A)
// }
// }
// func BenchmarkFeSquare25(b *testing.B) { func BenchmarkFeFromBig(b *testing.B) {
// var h edwards25519.FieldElement var fe field.FieldElement
// for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
// edwards25519.FeSquare(&h, &radix25A) field.FeFromBig(&fe, randFieldInt)
// } }
// } }
// func BenchmarkFeSquare51(b *testing.B) {
// var h radix51.FieldElement
// for i := 0; i < b.N; i++ {
// radix51.FeSquare(&h, &radix51A)
// }
// }

View File

@ -98,8 +98,8 @@ func (v *ExtendedGroupElement) Add(p1, p2 *ExtendedGroupElement) *ExtendedGroupE
} }
func (v *ExtendedGroupElement) Double() *ExtendedGroupElement { func (v *ExtendedGroupElement) Double() *ExtendedGroupElement {
var p ProjectiveGroupElement = v.ToProjective() // return v.ToProjective().Double().ToExtended()
return p.Double().ToExtended() panic("not yet implemented")
} }
// Projective coordinates are XYZ with x = X/Z, y = Y/Z, or the "P2" // Projective coordinates are XYZ with x = X/Z, y = Y/Z, or the "P2"
@ -125,17 +125,16 @@ func (v *ProjectiveGroupElement) ToAffine() (*big.Int, *big.Int) {
return field.FeToBig(&x), field.FeToBig(&y) return field.FeToBig(&x), field.FeToBig(&y)
} }
// HWCD Section 3: "Given (X : Y : Z) in [projective coordinates] passing to
// [extended coordinates, (X : Y : T : Z)] can be performed in 3M+1S by computing
// (XZ, YZ, XY, Z^2)"
func (v *ProjectiveGroupElement) ToExtended() *ExtendedGroupElement { func (v *ProjectiveGroupElement) ToExtended() *ExtendedGroupElement {
var r ExtendedGroupElement var r ExtendedGroupElement
var zinv field.FieldElement
field.FeCopy(&r.X, &v.X) field.FeMul(&r.X, &v.X, &v.Z)
field.FeCopy(&r.Y, &v.Y) field.FeMul(&r.Y, &v.Y, &v.Z)
field.FeCopy(&r.Z, &v.Z) field.FeMul(&r.T, &v.X, &v.Y)
field.FeSquare(&r.Z, &v.Z)
field.FeInvert(&zinv, &v.Z)
field.FeMul(&r.T, &v.X, &v.Y) // XY = ZT
field.FeMul(&r.T, &r.T, &zinv) // T = ZT/Z
return &r return &r
} }
@ -166,8 +165,8 @@ func (v *ProjectiveGroupElement) Zero() *ProjectiveGroupElement {
// Z3 = F^2-2*F // Z3 = F^2-2*F
// //
// 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 during a Montgomery ladder using extended coordinates. // will not hold throughout a Montgomery ladder using extended coordinates.
// TODO: Hand off or switch entirely to dbl-2008-bbjlp when package is public. // TODO: Check or switch entirely to dbl-2008-bbjlp like everyone else.
func (v *ProjectiveGroupElement) DoubleZ1() *ProjectiveGroupElement { func (v *ProjectiveGroupElement) DoubleZ1() *ProjectiveGroupElement {
var p, q ProjectiveGroupElement var p, q ProjectiveGroupElement
var t0, t1 field.FieldElement var t0, t1 field.FieldElement

View File

@ -4,7 +4,10 @@
// public domain amd64-51-30k version of ed25519 from SUPERCOP. // public domain amd64-51-30k version of ed25519 from SUPERCOP.
package radix51 package radix51
import "math/big" import (
"math/big"
"math/bits"
)
// FieldElement represents an element of the field GF(2^255-19). An element t // FieldElement represents an element of the field GF(2^255-19). An element t
// represents the integer t[0] + t[1]*2^51 + t[2]*2^102 + t[3]*2^153 + // represents the integer t[0] + t[1]*2^51 + t[2]*2^102 + t[3]*2^153 +
@ -314,14 +317,25 @@ func FeToBytes(r *[32]byte, v *FieldElement) {
r[31] = byte((t[4] >> 44)) r[31] = byte((t[4] >> 44))
} }
func FeFromBig(h *FieldElement, in *big.Int) { func FeFromBig(h *FieldElement, num *big.Int) {
tmpBytes := in.Bytes() var buf [32]byte
var buf, reverse [32]byte
copy(buf[32-len(tmpBytes):], tmpBytes) offset := 0
for i := 0; i < 32; i++ { words := num.Bits()
reverse[i] = buf[31-i] numWords := len(words)
for n := 0; n < numWords; n++ {
word := words[n]
for i := 0; i < bits.UintSize/8; i++ {
if offset >= len(buf) {
break
}
buf[offset] = byte(word >> uint((i << 3)))
offset++
}
} }
FeFromBytes(h, &reverse)
FeFromBytes(h, &buf)
} }
func FeToBig(h *FieldElement) *big.Int { func FeToBig(h *FieldElement) *big.Int {

View File

@ -149,12 +149,12 @@ func TestFeEqual(t *testing.T) {
var y FieldElement = [5]uint64{5, 4, 3, 2, 1} var y FieldElement = [5]uint64{5, 4, 3, 2, 1}
eq := FeEqual(&x, &x) eq := FeEqual(&x, &x)
if eq != 0 { if !eq {
t.Errorf("wrong about equality") t.Errorf("wrong about equality")
} }
eq = FeEqual(&x, &y) eq = FeEqual(&x, &y)
if eq == 0 { if eq {
t.Errorf("wrong about inequality") t.Errorf("wrong about inequality")
} }
} }