Added PointTablePrecompute / UnsafeVarTimeScalarMultPrecomputed
This commit is contained in:
parent
a67b1e9d0a
commit
e2f706cb5c
18
precomp.go
Normal file
18
precomp.go
Normal file
|
@ -0,0 +1,18 @@
|
|||
package edwards25519
|
||||
|
||||
type PrecomputedTable [32]affineLookupTable
|
||||
|
||||
func PointTablePrecompute(q *Point) *PrecomputedTable {
|
||||
p := new(Point)
|
||||
p.Set(q)
|
||||
|
||||
var table PrecomputedTable
|
||||
|
||||
for i := 0; i < 32; i++ {
|
||||
table[i].FromP3(p)
|
||||
for j := 0; j < 8; j++ {
|
||||
p.Add(p, p)
|
||||
}
|
||||
}
|
||||
return &table
|
||||
}
|
49
unsafe.go
49
unsafe.go
|
@ -105,6 +105,55 @@ func (v *Point) UnsafeVarTimeScalarBaseMult(x *Scalar) *Point {
|
|||
return v
|
||||
}
|
||||
|
||||
// UnsafeVarTimeScalarMultPrecomputed sets v = x * q, and returns v., and returns v. Execution time depends on the inputs.
|
||||
// Deprecated: Unsafe for private operations
|
||||
func (v *Point) UnsafeVarTimeScalarMultPrecomputed(x *Scalar, table *PrecomputedTable) *Point {
|
||||
// Write x = sum(x_i * 16^i) so x*B = sum( B*x_i*16^i )
|
||||
// as described in the Ed25519 paper
|
||||
//
|
||||
// Group even and odd coefficients
|
||||
// x*B = x_0*16^0*B + x_2*16^2*B + ... + x_62*16^62*B
|
||||
// + x_1*16^1*B + x_3*16^3*B + ... + x_63*16^63*B
|
||||
// x*B = x_0*16^0*B + x_2*16^2*B + ... + x_62*16^62*B
|
||||
// + 16*( x_1*16^0*B + x_3*16^2*B + ... + x_63*16^62*B)
|
||||
//
|
||||
// We use a lookup table for each i to get x_i*16^(2*i)*B
|
||||
// and do four doublings to multiply by 16.
|
||||
digits := x.signedRadix16()
|
||||
|
||||
multiple := &affineCached{}
|
||||
tmp1 := &projP1xP1{}
|
||||
tmp2 := &projP2{}
|
||||
|
||||
// Accumulate the odd components first
|
||||
v.Set(NewIdentityPoint())
|
||||
for i := 1; i < 64; i += 2 {
|
||||
table[i/2].UnsafeVarTimeSelectInto(multiple, digits[i])
|
||||
tmp1.AddAffine(v, multiple)
|
||||
v.fromP1xP1(tmp1)
|
||||
}
|
||||
|
||||
// Multiply by 16
|
||||
tmp2.FromP3(v) // tmp2 = v in P2 coords
|
||||
tmp1.Double(tmp2) // tmp1 = 2*v in P1xP1 coords
|
||||
tmp2.FromP1xP1(tmp1) // tmp2 = 2*v in P2 coords
|
||||
tmp1.Double(tmp2) // tmp1 = 4*v in P1xP1 coords
|
||||
tmp2.FromP1xP1(tmp1) // tmp2 = 4*v in P2 coords
|
||||
tmp1.Double(tmp2) // tmp1 = 8*v in P1xP1 coords
|
||||
tmp2.FromP1xP1(tmp1) // tmp2 = 8*v in P2 coords
|
||||
tmp1.Double(tmp2) // tmp1 = 16*v in P1xP1 coords
|
||||
v.fromP1xP1(tmp1) // now v = 16*(odd components)
|
||||
|
||||
// Accumulate the even components
|
||||
for i := 0; i < 64; i += 2 {
|
||||
table[i/2].UnsafeVarTimeSelectInto(multiple, digits[i])
|
||||
tmp1.AddAffine(v, multiple)
|
||||
v.fromP1xP1(tmp1)
|
||||
}
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
// Set dest to x*Q, where -8 <= x <= 8, in variable time.
|
||||
// Deprecated: Unsafe for private operations
|
||||
func (v *affineLookupTable) UnsafeVarTimeSelectInto(dest *affineCached, x int8) {
|
||||
|
|
|
@ -61,6 +61,29 @@ func TestUnsafeVarTimeScalarMultNonIdentityPoint(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestUnsafeVarTimeScalarMultPrecomputedNonIdentityPoint(t *testing.T) {
|
||||
// Check whether p.ScalarMult and q.ScalaBaseMult give the same,
|
||||
// when p and q are originally set to the base point.
|
||||
|
||||
table := PointTablePrecompute(B)
|
||||
|
||||
unsafeVarTimeScalarMultPrecomputedNonIdentityPoint := func(x Scalar) bool {
|
||||
var p, q Point
|
||||
q.Set(B)
|
||||
|
||||
p.UnsafeVarTimeScalarMultPrecomputed(&x, table)
|
||||
q.ScalarBaseMult(&x)
|
||||
|
||||
checkOnCurve(t, &p, &q)
|
||||
|
||||
return p.Equal(&q) == 1
|
||||
}
|
||||
|
||||
if err := quick.Check(unsafeVarTimeScalarMultPrecomputedNonIdentityPoint, quickCheckConfig(32)); 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.
|
||||
|
@ -98,3 +121,15 @@ func BenchmarkUnsafeVarTimeScalarBaseMult(b *testing.B) {
|
|||
p.UnsafeVarTimeScalarBaseMult(dalekScalar)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkUnsafeVarTimeScalarMultPrecomputed(b *testing.B) {
|
||||
var p Point
|
||||
|
||||
table := PointTablePrecompute(B)
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
p.UnsafeVarTimeScalarMultPrecomputed(dalekScalar, table)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue