mirror of https://github.com/gtank/ristretto255
internal/ed25519: implement BasepointMul
This commit is contained in:
parent
e69072e96b
commit
23073b0135
|
@ -12,7 +12,49 @@ import (
|
||||||
//
|
//
|
||||||
// The scalar multiplication is done in constant time.
|
// The scalar multiplication is done in constant time.
|
||||||
func (v *ProjP3) BasepointMul(x *scalar.Scalar) *ProjP3 {
|
func (v *ProjP3) BasepointMul(x *scalar.Scalar) *ProjP3 {
|
||||||
panic("unimplemented")
|
// 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.Zero()
|
||||||
|
for i := 1; i < 64; i += 2 {
|
||||||
|
basepointTable[i/2].SelectInto(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 {
|
||||||
|
basepointTable[i/2].SelectInto(multiple, digits[i])
|
||||||
|
tmp1.AddAffine(v, multiple)
|
||||||
|
v.FromP1xP1(tmp1)
|
||||||
|
}
|
||||||
|
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,14 @@ func TestScalarMulVsDalek(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBasepointMulVsDalek(t *testing.T) {
|
||||||
|
var p ProjP3
|
||||||
|
p.BasepointMul(&dalekScalar)
|
||||||
|
if dalekScalarBasepoint.Equal(&p) != 1 {
|
||||||
|
t.Error("Scalar mul does not match dalek")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestScalarMulDistributesOverAdd(t *testing.T) {
|
func TestScalarMulDistributesOverAdd(t *testing.T) {
|
||||||
scalarMulDistributesOverAdd := func(x, y scalar.Scalar) bool {
|
scalarMulDistributesOverAdd := func(x, y scalar.Scalar) bool {
|
||||||
// The quickcheck generation strategy chooses a random
|
// The quickcheck generation strategy chooses a random
|
||||||
|
@ -99,3 +107,18 @@ func TestBasepointTableGeneration(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestScalarMulMatchesBasepointMul(t *testing.T) {
|
||||||
|
scalarMulMatchesBasepointMul := func(x scalar.Scalar) bool {
|
||||||
|
// FIXME opaque scalars
|
||||||
|
x[31] &= 127
|
||||||
|
var p, q ProjP3
|
||||||
|
p.ScalarMul(&x, &B)
|
||||||
|
q.BasepointMul(&x)
|
||||||
|
return p.Equal(&q) == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := quick.Check(scalarMulMatchesBasepointMul, quickCheckConfig); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue