github.com/cloudflare/circl@v1.5.0/sign/internal/dilithium/amd64.go (about)

     1  //go:build amd64 && !purego
     2  // +build amd64,!purego
     3  
     4  package dilithium
     5  
     6  import (
     7  	"golang.org/x/sys/cpu"
     8  )
     9  
    10  // Execute an in-place forward NTT on as.
    11  //
    12  // Assumes the coefficients are in Montgomery representation and bounded
    13  // by 2*Q.  The resulting coefficients are again in Montgomery representation,
    14  // but are only bounded bt 18*Q.
    15  func (p *Poly) NTT() {
    16  	if cpu.X86.HasAVX2 {
    17  		nttAVX2(
    18  			(*[N]uint32)(p),
    19  		)
    20  	} else {
    21  		p.nttGeneric()
    22  	}
    23  }
    24  
    25  // Execute an in-place inverse NTT and multiply by Montgomery factor R
    26  //
    27  // Assumes the coefficients are in Montgomery representation and bounded
    28  // by 2*Q.  The resulting coefficients are again in Montgomery representation
    29  // and bounded by 2*Q.
    30  func (p *Poly) InvNTT() {
    31  	if cpu.X86.HasAVX2 {
    32  		invNttAVX2(
    33  			(*[N]uint32)(p),
    34  		)
    35  	} else {
    36  		p.invNttGeneric()
    37  	}
    38  }
    39  
    40  // Sets p to the polynomial whose coefficients are the pointwise multiplication
    41  // of those of a and b.  The coefficients of p are bounded by 2q.
    42  //
    43  // Assumes a and b are in Montgomery form and that the pointwise product
    44  // of each coefficient is below 2³² q.
    45  func (p *Poly) MulHat(a, b *Poly) {
    46  	if cpu.X86.HasAVX2 {
    47  		mulHatAVX2(
    48  			(*[N]uint32)(p),
    49  			(*[N]uint32)(a),
    50  			(*[N]uint32)(b),
    51  		)
    52  	} else {
    53  		p.mulHatGeneric(a, b)
    54  	}
    55  }
    56  
    57  // Sets p to a + b.  Does not normalize polynomials.
    58  func (p *Poly) Add(a, b *Poly) {
    59  	if cpu.X86.HasAVX2 {
    60  		addAVX2(
    61  			(*[N]uint32)(p),
    62  			(*[N]uint32)(a),
    63  			(*[N]uint32)(b),
    64  		)
    65  	} else {
    66  		p.addGeneric(a, b)
    67  	}
    68  }
    69  
    70  // Sets p to a - b.
    71  //
    72  // Warning: assumes coefficients of b are less than 2q.
    73  // Sets p to a + b.  Does not normalize polynomials.
    74  func (p *Poly) Sub(a, b *Poly) {
    75  	if cpu.X86.HasAVX2 {
    76  		subAVX2(
    77  			(*[N]uint32)(p),
    78  			(*[N]uint32)(a),
    79  			(*[N]uint32)(b),
    80  		)
    81  	} else {
    82  		p.subGeneric(a, b)
    83  	}
    84  }
    85  
    86  // Writes p whose coefficients are in [0, 16) to buf, which must be of
    87  // length N/2.
    88  func (p *Poly) PackLe16(buf []byte) {
    89  	if cpu.X86.HasAVX2 {
    90  		if len(buf) < PolyLe16Size {
    91  			panic("buf too small")
    92  		}
    93  		packLe16AVX2(
    94  			(*[N]uint32)(p),
    95  			&buf[0],
    96  		)
    97  	} else {
    98  		p.packLe16Generic(buf)
    99  	}
   100  }
   101  
   102  // Reduces each of the coefficients to <2q.
   103  func (p *Poly) ReduceLe2Q() {
   104  	if cpu.X86.HasAVX2 {
   105  		reduceLe2QAVX2((*[N]uint32)(p))
   106  	} else {
   107  		p.reduceLe2QGeneric()
   108  	}
   109  }
   110  
   111  // Reduce each of the coefficients to <q.
   112  func (p *Poly) Normalize() {
   113  	if cpu.X86.HasAVX2 {
   114  		p.ReduceLe2Q()
   115  		p.NormalizeAssumingLe2Q()
   116  	} else {
   117  		p.normalizeGeneric()
   118  	}
   119  }
   120  
   121  // Normalize the coefficients in this polynomial assuming they are already
   122  // bounded by 2q.
   123  func (p *Poly) NormalizeAssumingLe2Q() {
   124  	if cpu.X86.HasAVX2 {
   125  		le2qModQAVX2((*[N]uint32)(p))
   126  	} else {
   127  		p.normalizeAssumingLe2QGeneric()
   128  	}
   129  }
   130  
   131  // Checks whether the "supnorm" (see sec 2.1 of the spec) of p is equal
   132  // or greater than the given bound.
   133  //
   134  // Requires the coefficients of p to be normalized.
   135  func (p *Poly) Exceeds(bound uint32) bool {
   136  	if cpu.X86.HasAVX2 {
   137  		return exceedsAVX2((*[N]uint32)(p), bound) == 1
   138  	}
   139  	return p.exceedsGeneric(bound)
   140  }
   141  
   142  // Sets p to 2ᵈ q without reducing.
   143  //
   144  // So it requires the coefficients of p  to be less than 2³²⁻ᴰ.
   145  func (p *Poly) MulBy2toD(q *Poly) {
   146  	if cpu.X86.HasAVX2 {
   147  		mulBy2toDAVX2(
   148  			(*[N]uint32)(p),
   149  			(*[N]uint32)(q),
   150  		)
   151  	} else {
   152  		p.mulBy2toDGeneric(q)
   153  	}
   154  }