Added unsafe VarTime methods for ScalarMult, ScalarBaseMult
This commit is contained in:
parent
8c58ed0e35
commit
e42c4b5eb9
81
unsafe.go
Normal file
81
unsafe.go
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
package edwards25519
|
||||||
|
|
||||||
|
// UnsafeVarTimeScalarMult sets v = x * q, and returns v., and returns v. Execution time depends on the inputs.
|
||||||
|
// Deprecated: Unsafe for private operations
|
||||||
|
func (v *Point) UnsafeVarTimeScalarMult(x *Scalar, q *Point) *Point {
|
||||||
|
checkInitialized(q)
|
||||||
|
|
||||||
|
// Build lookup table for point q
|
||||||
|
var table nafLookupTable5
|
||||||
|
table.FromP3(q)
|
||||||
|
// Compute a NAF for scalar x
|
||||||
|
naf := x.nonAdjacentForm(5)
|
||||||
|
|
||||||
|
multiple := &projCached{}
|
||||||
|
tmp1 := &projP1xP1{}
|
||||||
|
tmp2 := &projP2{}
|
||||||
|
tmp2.Zero()
|
||||||
|
|
||||||
|
// Move from high to low bits, doubling the accumulator
|
||||||
|
// at each iteration and checking whether there is a nonzero
|
||||||
|
// coefficient to look up a multiple of.
|
||||||
|
//
|
||||||
|
// Skip trying to find the first nonzero coefficent, because
|
||||||
|
// searching might be more work than a few extra doublings.
|
||||||
|
for i := 255; i >= 0; i-- {
|
||||||
|
tmp1.Double(tmp2)
|
||||||
|
if naf[i] > 0 {
|
||||||
|
v.fromP1xP1(tmp1)
|
||||||
|
table.SelectInto(multiple, naf[i])
|
||||||
|
tmp1.Add(v, multiple)
|
||||||
|
} else if naf[i] < 0 {
|
||||||
|
v.fromP1xP1(tmp1)
|
||||||
|
table.SelectInto(multiple, -naf[i])
|
||||||
|
tmp1.Sub(v, multiple)
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp2.FromP1xP1(tmp1)
|
||||||
|
}
|
||||||
|
|
||||||
|
v.fromP2(tmp2)
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnsafeVarTimeScalarBaseMult sets v = x * B, where B is the canonical generator, and returns v. Execution time depends on the inputs.
|
||||||
|
// Deprecated: Unsafe for private operations
|
||||||
|
// This is not faster than ScalarBaseMult
|
||||||
|
func (v *Point) UnsafeVarTimeScalarBaseMult(x *Scalar) *Point {
|
||||||
|
basepointNafTable := basepointNafTable()
|
||||||
|
// Because the basepoint is fixed, we can use a wider NAF
|
||||||
|
// corresponding to a bigger table.
|
||||||
|
naf := x.nonAdjacentForm(8)
|
||||||
|
|
||||||
|
multiple := &affineCached{}
|
||||||
|
tmp1 := &projP1xP1{}
|
||||||
|
tmp2 := &projP2{}
|
||||||
|
tmp2.Zero()
|
||||||
|
|
||||||
|
// Move from high to low bits, doubling the accumulator
|
||||||
|
// at each iteration and checking whether there is a nonzero
|
||||||
|
// coefficient to look up a multiple of.
|
||||||
|
//
|
||||||
|
// Skip trying to find the first nonzero coefficent, because
|
||||||
|
// searching might be more work than a few extra doublings.
|
||||||
|
for i := 255; i >= 0; i-- {
|
||||||
|
tmp1.Double(tmp2)
|
||||||
|
if naf[i] > 0 {
|
||||||
|
v.fromP1xP1(tmp1)
|
||||||
|
basepointNafTable.SelectInto(multiple, naf[i])
|
||||||
|
tmp1.AddAffine(v, multiple)
|
||||||
|
} else if naf[i] < 0 {
|
||||||
|
v.fromP1xP1(tmp1)
|
||||||
|
basepointNafTable.SelectInto(multiple, -naf[i])
|
||||||
|
tmp1.SubAffine(v, multiple)
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp2.FromP1xP1(tmp1)
|
||||||
|
}
|
||||||
|
|
||||||
|
v.fromP2(tmp2)
|
||||||
|
return v
|
||||||
|
}
|
100
unsafe_test.go
Normal file
100
unsafe_test.go
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
package edwards25519
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"testing/quick"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestUnsafeVarTimeScalarMultMatchesScalarBaseMult(t *testing.T) {
|
||||||
|
unsafeVarTimeScalarMultMatchesScalarMult := func(x Scalar) bool {
|
||||||
|
var p, check Point
|
||||||
|
|
||||||
|
p.UnsafeVarTimeScalarMult(&x, B)
|
||||||
|
|
||||||
|
check.ScalarBaseMult(&x)
|
||||||
|
|
||||||
|
checkOnCurve(t, &p, &check)
|
||||||
|
return p.Equal(&check) == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := quick.Check(unsafeVarTimeScalarMultMatchesScalarMult, quickCheckConfig32); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnsafeVarTimeScalarBaseMultMatchesScalarBaseMult(t *testing.T) {
|
||||||
|
unsafeVarTimeScalarBaseMultMatchesScalarMult := func(x Scalar) bool {
|
||||||
|
var p, check Point
|
||||||
|
|
||||||
|
p.UnsafeVarTimeScalarBaseMult(&x)
|
||||||
|
|
||||||
|
check.ScalarBaseMult(&x)
|
||||||
|
|
||||||
|
checkOnCurve(t, &p, &check)
|
||||||
|
return p.Equal(&check) == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := quick.Check(unsafeVarTimeScalarBaseMultMatchesScalarMult, quickCheckConfig32); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnsafeVarTimeScalarMultNonIdentityPoint(t *testing.T) {
|
||||||
|
// Check whether p.ScalarMult and q.ScalaBaseMult give the same,
|
||||||
|
// when p and q are originally set to the base point.
|
||||||
|
|
||||||
|
unsafeVarTimeScalarMultNonIdentityPoint := func(x Scalar) bool {
|
||||||
|
var p, q Point
|
||||||
|
p.Set(B)
|
||||||
|
q.Set(B)
|
||||||
|
|
||||||
|
p.UnsafeVarTimeScalarMult(&x, B)
|
||||||
|
q.ScalarBaseMult(&x)
|
||||||
|
|
||||||
|
checkOnCurve(t, &p, &q)
|
||||||
|
|
||||||
|
return p.Equal(&q) == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := quick.Check(unsafeVarTimeScalarMultNonIdentityPoint, quickCheckConfig32); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnsafeVarTimeScalarBaseMultNonIdentityPoint(t *testing.T) {
|
||||||
|
// Check whether p.ScalarMult and q.ScalaBaseMult give the same,
|
||||||
|
// when p and q are originally set to the base point.
|
||||||
|
|
||||||
|
unsafeVarTimeScalarBaseMultNonIdentityPoint := func(x Scalar) bool {
|
||||||
|
var p, q Point
|
||||||
|
p.Set(B)
|
||||||
|
q.Set(B)
|
||||||
|
|
||||||
|
p.UnsafeVarTimeScalarBaseMult(&x)
|
||||||
|
q.ScalarBaseMult(&x)
|
||||||
|
|
||||||
|
checkOnCurve(t, &p, &q)
|
||||||
|
|
||||||
|
return p.Equal(&q) == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := quick.Check(unsafeVarTimeScalarBaseMultNonIdentityPoint, quickCheckConfig32); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkUnsafeVarTimeScalarMult(b *testing.B) {
|
||||||
|
var p Point
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
p.UnsafeVarTimeScalarMult(dalekScalar, B)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkUnsafeVarTimeScalarBaseMult(b *testing.B) {
|
||||||
|
var p Point
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
p.UnsafeVarTimeScalarBaseMult(dalekScalar)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue