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)
return p.Double().ToAffine()
return p.DoubleZ1().ToAffine()
}
// 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 radix25A = edwards25519.FieldElement{
// 486662, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// }
var radix51A = field.FieldElement{
486662, 0, 0, 0, 0,
}
// var radix51A = radix51.FieldElement{
// 486662, 0, 0, 0, 0,
// }
func BenchmarkFeMul51(b *testing.B) {
var h field.FieldElement
for i := 0; i < b.N; i++ {
field.FeMul(&h, &radix51A, &radix51A)
}
}
// func BenchmarkFeMul25(b *testing.B) {
// var h edwards25519.FieldElement
// for i := 0; i < b.N; i++ {
// edwards25519.FeMul(&h, &radix25A, &radix25A)
// }
// }
func BenchmarkFeSquare51(b *testing.B) {
var h field.FieldElement
for i := 0; i < b.N; i++ {
field.FeSquare(&h, &radix51A)
}
}
// func BenchmarkFeMul51(b *testing.B) {
// var h radix51.FieldElement
// for i := 0; i < b.N; i++ {
// radix51.FeMul(&h, &radix51A, &radix51A)
// }
// }
var concreteCurve = Ed25519().(ed25519Curve)
var randFieldInt, _ = rand.Int(rand.Reader, concreteCurve.P)
// func BenchmarkFeSquare25(b *testing.B) {
// var h edwards25519.FieldElement
// for i := 0; i < b.N; i++ {
// edwards25519.FeSquare(&h, &radix25A)
// }
// }
// func BenchmarkFeSquare51(b *testing.B) {
// var h radix51.FieldElement
// for i := 0; i < b.N; i++ {
// radix51.FeSquare(&h, &radix51A)
// }
// }
func BenchmarkFeFromBig(b *testing.B) {
var fe field.FieldElement
for i := 0; i < b.N; i++ {
field.FeFromBig(&fe, randFieldInt)
}
}

View File

@ -98,8 +98,8 @@ func (v *ExtendedGroupElement) Add(p1, p2 *ExtendedGroupElement) *ExtendedGroupE
}
func (v *ExtendedGroupElement) Double() *ExtendedGroupElement {
var p ProjectiveGroupElement = v.ToProjective()
return p.Double().ToExtended()
// return v.ToProjective().Double().ToExtended()
panic("not yet implemented")
}
// 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)
}
// 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 {
var r ExtendedGroupElement
var zinv field.FieldElement
field.FeCopy(&r.X, &v.X)
field.FeCopy(&r.Y, &v.Y)
field.FeCopy(&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
field.FeMul(&r.X, &v.X, &v.Z)
field.FeMul(&r.Y, &v.Y, &v.Z)
field.FeMul(&r.T, &v.X, &v.Y)
field.FeSquare(&r.Z, &v.Z)
return &r
}
@ -166,8 +165,8 @@ func (v *ProjectiveGroupElement) Zero() *ProjectiveGroupElement {
// Z3 = F^2-2*F
//
// This assumption is one reason why this package is internal. For instance, it
// will not hold during a Montgomery ladder using extended coordinates.
// TODO: Hand off or switch entirely to dbl-2008-bbjlp when package is public.
// will not hold throughout a Montgomery ladder using extended coordinates.
// TODO: Check or switch entirely to dbl-2008-bbjlp like everyone else.
func (v *ProjectiveGroupElement) DoubleZ1() *ProjectiveGroupElement {
var p, q ProjectiveGroupElement
var t0, t1 field.FieldElement

View File

@ -4,7 +4,10 @@
// public domain amd64-51-30k version of ed25519 from SUPERCOP.
package radix51
import "math/big"
import (
"math/big"
"math/bits"
)
// 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 +
@ -314,14 +317,25 @@ func FeToBytes(r *[32]byte, v *FieldElement) {
r[31] = byte((t[4] >> 44))
}
func FeFromBig(h *FieldElement, in *big.Int) {
tmpBytes := in.Bytes()
var buf, reverse [32]byte
copy(buf[32-len(tmpBytes):], tmpBytes)
for i := 0; i < 32; i++ {
reverse[i] = buf[31-i]
func FeFromBig(h *FieldElement, num *big.Int) {
var buf [32]byte
offset := 0
words := num.Bits()
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 {

View File

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