arm64.go raw

   1  //go:build arm64 && !purego
   2  // +build arm64,!purego
   3  
   4  package common
   5  
   6  // Sets p to a + b.  Does not normalize coefficients.
   7  func (p *Poly) Add(a, b *Poly) {
   8  	polyAddARM64(p, a, b)
   9  }
  10  
  11  // Sets p to a - b.  Does not normalize coefficients.
  12  func (p *Poly) Sub(a, b *Poly) {
  13  	polySubARM64(p, a, b)
  14  }
  15  
  16  // Executes an in-place forward "NTT" on p.
  17  //
  18  // Assumes the coefficients are in absolute value ≤q.  The resulting
  19  // coefficients are in absolute value ≤7q.  If the input is in Montgomery
  20  // form, then the result is in Montgomery form and so (by linearity of the NTT)
  21  // if the input is in regular form, then the result is also in regular form.
  22  // The order of coefficients will be "tangled". These can be put back into
  23  // their proper order by calling Detangle().
  24  func (p *Poly) NTT() {
  25  	p.nttGeneric()
  26  }
  27  
  28  // Executes an in-place inverse "NTT" on p and multiply by the Montgomery
  29  // factor R.
  30  //
  31  // Requires coefficients to be in "tangled" order, see Tangle().
  32  // Assumes the coefficients are in absolute value ≤q.  The resulting
  33  // coefficients are in absolute value ≤q.  If the input is in Montgomery
  34  // form, then the result is in Montgomery form and so (by linearity)
  35  // if the input is in regular form, then the result is also in regular form.
  36  func (p *Poly) InvNTT() {
  37  	p.invNTTGeneric()
  38  }
  39  
  40  // Sets p to the "pointwise" multiplication of a and b.
  41  //
  42  // That is: InvNTT(p) = InvNTT(a) * InvNTT(b).  Assumes a and b are in
  43  // Montgomery form.  Products between coefficients of a and b must be strictly
  44  // bounded in absolute value by 2¹⁵q.  p will be in Montgomery form and
  45  // bounded in absolute value by 2q.
  46  //
  47  // Requires a and b to be in "tangled" order, see Tangle().  p will be in
  48  // tangled order as well.
  49  func (p *Poly) MulHat(a, b *Poly) {
  50  	p.mulHatGeneric(a, b)
  51  }
  52  
  53  // Puts p into the right form to be used with (among others) InvNTT().
  54  func (p *Poly) Tangle() {
  55  	// In the generic implementation there is no advantage to using a
  56  	// different order, so we use the standard order everywhere.
  57  }
  58  
  59  // Puts p back into standard form.
  60  func (p *Poly) Detangle() {
  61  	// In the generic implementation there is no advantage to using a
  62  	// different order, so we use the standard order everywhere.
  63  }
  64  
  65  // Almost normalizes coefficients.
  66  //
  67  // Ensures each coefficient is in {0, …, q}.
  68  func (p *Poly) BarrettReduce() {
  69  	p.barrettReduceGeneric()
  70  }
  71  
  72  // Normalizes coefficients.
  73  //
  74  // Ensures each coefficient is in {0, …, q-1}.
  75  func (p *Poly) Normalize() {
  76  	p.normalizeGeneric()
  77  }
  78  
  79  //go:noescape
  80  func polyAddARM64(p, a, b *Poly)
  81  
  82  //go:noescape
  83  func polySubARM64(p, a, b *Poly)
  84