scalar: fix aliasing of MultiplyAdd addend and receiver

This commit is contained in:
Filippo Valsorda 2022-07-29 22:58:21 +02:00 committed by Filippo Valsorda
parent 589b96254b
commit 755954a498
2 changed files with 23 additions and 2 deletions

View file

@ -40,9 +40,12 @@ func NewScalar() *Scalar {
return &Scalar{}
}
// MultiplyAdd sets s = x * y + z mod l, and returns s. DEPRECATED. Use the individual Add and Multiply methods instead.
// MultiplyAdd sets s = x * y + z mod l, and returns s. It is equivalent to
// using Multiply and then Add.
func (s *Scalar) MultiplyAdd(x, y, z *Scalar) *Scalar {
return s.Multiply(x, y).Add(s, z)
// Make a copy of z in case it aliases s.
zCopy := new(Scalar).Set(z)
return s.Multiply(x, y).Add(s, zCopy)
}
// Add sets s = x + y mod l, and returns s.

View file

@ -75,6 +75,9 @@ func TestScalarAliasing(t *testing.T) {
"Negate": func(v, x Scalar) bool {
return checkAliasingOneArg((*Scalar).Negate, v, x)
},
"Invert": func(v, x Scalar) bool {
return checkAliasingOneArg((*Scalar).Invert, v, x)
},
"Multiply": func(v, x, y Scalar) bool {
return checkAliasingTwoArgs((*Scalar).Multiply, v, x, y)
},
@ -84,6 +87,21 @@ func TestScalarAliasing(t *testing.T) {
"Subtract": func(v, x, y Scalar) bool {
return checkAliasingTwoArgs((*Scalar).Subtract, v, x, y)
},
"MultiplyAdd1": func(v, x, y, fixed Scalar) bool {
return checkAliasingTwoArgs(func(v, x, y *Scalar) *Scalar {
return v.MultiplyAdd(&fixed, x, y)
}, v, x, y)
},
"MultiplyAdd2": func(v, x, y, fixed Scalar) bool {
return checkAliasingTwoArgs(func(v, x, y *Scalar) *Scalar {
return v.MultiplyAdd(x, &fixed, y)
}, v, x, y)
},
"MultiplyAdd3": func(v, x, y, fixed Scalar) bool {
return checkAliasingTwoArgs(func(v, x, y *Scalar) *Scalar {
return v.MultiplyAdd(x, y, &fixed)
}, v, x, y)
},
} {
err := quick.Check(f, &quick.Config{MaxCountScale: 1 << 5})
if err != nil {