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  }