@@ -349,3 +349,48 @@ func (v *Point) VarTimeMultiScalarMult(scalars []*Scalar, points []*Point) *Poin
349349 v .fromP2 (tmp2 )
350350 return v
351351}
352+
353+ // Select sets v to a if cond == 1 and to b if cond == 0.
354+ func (v * Point ) Select (a , b * Point , cond int ) * Point {
355+ v .x .Select (& a .x , & b .x , cond )
356+ v .y .Select (& a .y , & b .y , cond )
357+ v .z .Select (& a .z , & b .z , cond )
358+ v .t .Select (& a .t , & b .t , cond )
359+ return v
360+ }
361+
362+ // Double sets v = p + p, and returns v.
363+ func (v * Point ) Double (p * Point ) * Point {
364+ checkInitialized (p )
365+
366+ pp := new (projP2 ).FromP3 (p )
367+ p1 := new (projP1xP1 ).Double (pp )
368+ return v .fromP1xP1 (p1 )
369+ }
370+
371+ func (v * Point ) addCached (p * Point , qCached * projCached ) * Point {
372+ result := new (projP1xP1 ).Add (p , qCached )
373+ return v .fromP1xP1 (result )
374+ }
375+
376+ // ScalarMultSlow sets v = x * q, and returns v. It doesn't precompute a large
377+ // table, so it is considerably slower, but requires less memory.
378+ //
379+ // The scalar multiplication is done in constant time.
380+ func (v * Point ) ScalarMultSlow (x * Scalar , q * Point ) * Point {
381+ checkInitialized (q )
382+
383+ s := x .Bytes ()
384+ qCached := new (projCached ).FromP3 (q )
385+ v .Set (NewIdentityPoint ())
386+ t := new (Point )
387+
388+ for i := 255 ; i >= 0 ; i -- {
389+ v .Double (v )
390+ t .addCached (v , qCached )
391+ cond := (s [i / 8 ] >> (i % 8 )) & 1
392+ v .Select (t , v , int (cond ))
393+ }
394+
395+ return v
396+ }
0 commit comments