github.com/consensys/gnark-crypto@v0.14.0/field/generator/internal/templates/element/exp.go (about)

     1  package element
     2  
     3  const Exp = `
     4  // Exp z = xᵏ (mod q)
     5  func (z *{{.ElementName}}) Exp(x {{.ElementName}}, k *big.Int) *{{.ElementName}} {
     6  	if k.IsUint64() && k.Uint64() == 0 {
     7  		return z.SetOne()
     8  	}
     9  
    10  	e := k
    11  	if k.Sign() == -1 {
    12  		// negative k, we invert
    13  		// if k < 0: xᵏ (mod q) == (x⁻¹)ᵏ (mod q)
    14  		x.Inverse(&x)
    15  
    16  		// we negate k in a temp big.Int since
    17  		// Int.Bit(_) of k and -k is different
    18  		e = pool.BigInt.Get()
    19  		defer pool.BigInt.Put(e)
    20  		e.Neg(k)
    21  	}
    22  
    23  	z.Set(&x)
    24  
    25  	for i := e.BitLen() - 2; i >= 0; i-- {
    26  		z.Square(z)
    27  		if e.Bit(i) == 1 {
    28  			z.Mul(z, &x)
    29  		}
    30  	}
    31  
    32  	return z
    33  }
    34  
    35  `