twist_basemult.go raw

   1  package goldilocks
   2  
   3  import (
   4  	"crypto/subtle"
   5  
   6  	mlsb "github.com/cloudflare/circl/math/mlsbset"
   7  )
   8  
   9  const (
  10  	// MLSBRecoding parameters
  11  	fxT   = 448
  12  	fxV   = 2
  13  	fxW   = 3
  14  	fx2w1 = 1 << (uint(fxW) - 1)
  15  )
  16  
  17  // ScalarBaseMult returns kG where G is the generator point.
  18  func (e twistCurve) ScalarBaseMult(k *Scalar) *twistPoint {
  19  	m, err := mlsb.New(fxT, fxV, fxW)
  20  	if err != nil {
  21  		panic(err)
  22  	}
  23  	if m.IsExtended() {
  24  		panic("not extended")
  25  	}
  26  
  27  	var isZero int
  28  	if k.IsZero() {
  29  		isZero = 1
  30  	}
  31  	subtle.ConstantTimeCopy(isZero, k[:], order[:])
  32  
  33  	minusK := *k
  34  	isEven := 1 - int(k[0]&0x1)
  35  	minusK.Neg()
  36  	subtle.ConstantTimeCopy(isEven, k[:], minusK[:])
  37  	c, err := m.Encode(k[:])
  38  	if err != nil {
  39  		panic(err)
  40  	}
  41  
  42  	gP := c.Exp(groupMLSB{})
  43  	P := gP.(*twistPoint)
  44  	P.cneg(uint(isEven))
  45  	return P
  46  }
  47  
  48  type groupMLSB struct{}
  49  
  50  func (e groupMLSB) ExtendedEltP() mlsb.EltP      { return nil }
  51  func (e groupMLSB) Sqr(x mlsb.EltG)              { x.(*twistPoint).Double() }
  52  func (e groupMLSB) Mul(x mlsb.EltG, y mlsb.EltP) { x.(*twistPoint).mixAddZ1(y.(*preTwistPointAffine)) }
  53  func (e groupMLSB) Identity() mlsb.EltG          { return twistCurve{}.Identity() }
  54  func (e groupMLSB) NewEltP() mlsb.EltP           { return &preTwistPointAffine{} }
  55  func (e groupMLSB) Lookup(a mlsb.EltP, v uint, s, u int32) {
  56  	Tabj := &tabFixMult[v]
  57  	P := a.(*preTwistPointAffine)
  58  	for k := range Tabj {
  59  		P.cmov(&Tabj[k], uint(subtle.ConstantTimeEq(int32(k), u)))
  60  	}
  61  	P.cneg(int(s >> 31))
  62  }
  63