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 }