github.com/cloudflare/circl@v1.5.0/sign/dilithium/mode3/internal/vec.go (about) 1 package internal 2 3 import ( 4 common "github.com/cloudflare/circl/sign/internal/dilithium" 5 ) 6 7 // A vector of L polynomials. 8 type VecL [L]common.Poly 9 10 // A vector of K polynomials. 11 type VecK [K]common.Poly 12 13 // Normalize the polynomials in this vector. 14 func (v *VecL) Normalize() { 15 for i := 0; i < L; i++ { 16 v[i].Normalize() 17 } 18 } 19 20 // Normalize the polynomials in this vector assuming their coefficients 21 // are already bounded by 2q. 22 func (v *VecL) NormalizeAssumingLe2Q() { 23 for i := 0; i < L; i++ { 24 v[i].NormalizeAssumingLe2Q() 25 } 26 } 27 28 // Sets v to w + u. Does not normalize. 29 func (v *VecL) Add(w, u *VecL) { 30 for i := 0; i < L; i++ { 31 v[i].Add(&w[i], &u[i]) 32 } 33 } 34 35 // Applies NTT componentwise. See Poly.NTT() for details. 36 func (v *VecL) NTT() { 37 for i := 0; i < L; i++ { 38 v[i].NTT() 39 } 40 } 41 42 // Checks whether any of the coefficients exceeds the given bound in supnorm 43 // 44 // Requires the vector to be normalized. 45 func (v *VecL) Exceeds(bound uint32) bool { 46 for i := 0; i < L; i++ { 47 if v[i].Exceeds(bound) { 48 return true 49 } 50 } 51 return false 52 } 53 54 // Applies Poly.Power2Round componentwise. 55 // 56 // Requires the vector to be normalized. 57 func (v *VecL) Power2Round(v0PlusQ, v1 *VecL) { 58 for i := 0; i < L; i++ { 59 v[i].Power2Round(&v0PlusQ[i], &v1[i]) 60 } 61 } 62 63 // Applies Poly.Decompose componentwise. 64 // 65 // Requires the vector to be normalized. 66 func (v *VecL) Decompose(v0PlusQ, v1 *VecL) { 67 for i := 0; i < L; i++ { 68 PolyDecompose(&v[i], &v0PlusQ[i], &v1[i]) 69 } 70 } 71 72 // Sequentially packs each polynomial using Poly.PackLeqEta(). 73 func (v *VecL) PackLeqEta(buf []byte) { 74 offset := 0 75 for i := 0; i < L; i++ { 76 PolyPackLeqEta(&v[i], buf[offset:]) 77 offset += PolyLeqEtaSize 78 } 79 } 80 81 // Sets v to the polynomials packed in buf using VecL.PackLeqEta(). 82 func (v *VecL) UnpackLeqEta(buf []byte) { 83 offset := 0 84 for i := 0; i < L; i++ { 85 PolyUnpackLeqEta(&v[i], buf[offset:]) 86 offset += PolyLeqEtaSize 87 } 88 } 89 90 // Sequentially packs each polynomial using PolyPackLeGamma1(). 91 func (v *VecL) PackLeGamma1(buf []byte) { 92 offset := 0 93 for i := 0; i < L; i++ { 94 PolyPackLeGamma1(&v[i], buf[offset:]) 95 offset += PolyLeGamma1Size 96 } 97 } 98 99 // Sets v to the polynomials packed in buf using VecL.PackLeGamma1(). 100 func (v *VecL) UnpackLeGamma1(buf []byte) { 101 offset := 0 102 for i := 0; i < L; i++ { 103 PolyUnpackLeGamma1(&v[i], buf[offset:]) 104 offset += PolyLeGamma1Size 105 } 106 } 107 108 // Normalize the polynomials in this vector. 109 func (v *VecK) Normalize() { 110 for i := 0; i < K; i++ { 111 v[i].Normalize() 112 } 113 } 114 115 // Normalize the polynomials in this vector assuming their coefficients 116 // are already bounded by 2q. 117 func (v *VecK) NormalizeAssumingLe2Q() { 118 for i := 0; i < K; i++ { 119 v[i].NormalizeAssumingLe2Q() 120 } 121 } 122 123 // Sets v to w + u. Does not normalize. 124 func (v *VecK) Add(w, u *VecK) { 125 for i := 0; i < K; i++ { 126 v[i].Add(&w[i], &u[i]) 127 } 128 } 129 130 // Checks whether any of the coefficients exceeds the given bound in supnorm 131 // 132 // Requires the vector to be normalized. 133 func (v *VecK) Exceeds(bound uint32) bool { 134 for i := 0; i < K; i++ { 135 if v[i].Exceeds(bound) { 136 return true 137 } 138 } 139 return false 140 } 141 142 // Applies Poly.Power2Round componentwise. 143 // 144 // Requires the vector to be normalized. 145 func (v *VecK) Power2Round(v0PlusQ, v1 *VecK) { 146 for i := 0; i < K; i++ { 147 v[i].Power2Round(&v0PlusQ[i], &v1[i]) 148 } 149 } 150 151 // Applies Poly.Decompose componentwise. 152 // 153 // Requires the vector to be normalized. 154 func (v *VecK) Decompose(v0PlusQ, v1 *VecK) { 155 for i := 0; i < K; i++ { 156 PolyDecompose(&v[i], &v0PlusQ[i], &v1[i]) 157 } 158 } 159 160 // Sets v to the hint vector for v0 the modified low bits and v1 161 // the unmodified high bits --- see makeHint(). 162 // 163 // Returns the number of ones in the hint vector. 164 func (v *VecK) MakeHint(v0, v1 *VecK) (pop uint32) { 165 for i := 0; i < K; i++ { 166 pop += PolyMakeHint(&v[i], &v0[i], &v1[i]) 167 } 168 return 169 } 170 171 // Computes corrections to the high bits of the polynomials in the vector 172 // w using the hints in h and sets v to the corrected high bits. Returns v. 173 // See useHint(). 174 func (v *VecK) UseHint(q, hint *VecK) *VecK { 175 for i := 0; i < K; i++ { 176 PolyUseHint(&v[i], &q[i], &hint[i]) 177 } 178 return v 179 } 180 181 // Sequentially packs each polynomial using Poly.PackT1(). 182 func (v *VecK) PackT1(buf []byte) { 183 offset := 0 184 for i := 0; i < K; i++ { 185 v[i].PackT1(buf[offset:]) 186 offset += common.PolyT1Size 187 } 188 } 189 190 // Sets v to the vector packed into buf by PackT1(). 191 func (v *VecK) UnpackT1(buf []byte) { 192 offset := 0 193 for i := 0; i < K; i++ { 194 v[i].UnpackT1(buf[offset:]) 195 offset += common.PolyT1Size 196 } 197 } 198 199 // Sequentially packs each polynomial using Poly.PackT0(). 200 func (v *VecK) PackT0(buf []byte) { 201 offset := 0 202 for i := 0; i < K; i++ { 203 v[i].PackT0(buf[offset:]) 204 offset += common.PolyT0Size 205 } 206 } 207 208 // Sets v to the vector packed into buf by PackT0(). 209 func (v *VecK) UnpackT0(buf []byte) { 210 offset := 0 211 for i := 0; i < K; i++ { 212 v[i].UnpackT0(buf[offset:]) 213 offset += common.PolyT0Size 214 } 215 } 216 217 // Sequentially packs each polynomial using Poly.PackLeqEta(). 218 func (v *VecK) PackLeqEta(buf []byte) { 219 offset := 0 220 for i := 0; i < K; i++ { 221 PolyPackLeqEta(&v[i], buf[offset:]) 222 offset += PolyLeqEtaSize 223 } 224 } 225 226 // Sets v to the polynomials packed in buf using VecK.PackLeqEta(). 227 func (v *VecK) UnpackLeqEta(buf []byte) { 228 offset := 0 229 for i := 0; i < K; i++ { 230 PolyUnpackLeqEta(&v[i], buf[offset:]) 231 offset += PolyLeqEtaSize 232 } 233 } 234 235 // Applies NTT componentwise. See Poly.NTT() for details. 236 func (v *VecK) NTT() { 237 for i := 0; i < K; i++ { 238 v[i].NTT() 239 } 240 } 241 242 // Sequentially packs each polynomial using PolyPackW1(). 243 func (v *VecK) PackW1(buf []byte) { 244 offset := 0 245 for i := 0; i < K; i++ { 246 PolyPackW1(&v[i], buf[offset:]) 247 offset += PolyW1Size 248 } 249 } 250 251 // Sets v to a - b. 252 // 253 // Warning: assumes coefficients of the polynomials of b are less than 2q. 254 func (v *VecK) Sub(a, b *VecK) { 255 for i := 0; i < K; i++ { 256 v[i].Sub(&a[i], &b[i]) 257 } 258 } 259 260 // Sets v to 2ᵈ w without reducing. 261 func (v *VecK) MulBy2toD(w *VecK) { 262 for i := 0; i < K; i++ { 263 v[i].MulBy2toD(&w[i]) 264 } 265 } 266 267 // Applies InvNTT componentwise. See Poly.InvNTT() for details. 268 func (v *VecK) InvNTT() { 269 for i := 0; i < K; i++ { 270 v[i].InvNTT() 271 } 272 } 273 274 // Applies Poly.ReduceLe2Q() componentwise. 275 func (v *VecK) ReduceLe2Q() { 276 for i := 0; i < K; i++ { 277 v[i].ReduceLe2Q() 278 } 279 }