github.com/cloudflare/circl@v1.5.0/pke/kyber/kyber512/internal/vec.go (about)

     1  package internal
     2  
     3  import (
     4  	"github.com/cloudflare/circl/pke/kyber/internal/common"
     5  )
     6  
     7  // A vector of K polynomials
     8  type Vec [K]common.Poly
     9  
    10  // Samples v[i] from a centered binomial distribution with given η,
    11  // seed and nonce+i.
    12  //
    13  // Essentially CBD_η(PRF(seed, nonce+i)) from the specification.
    14  func (v *Vec) DeriveNoise(seed []byte, nonce uint8, eta int) {
    15  	for i := 0; i < K; i++ {
    16  		v[i].DeriveNoise(seed, nonce+uint8(i), eta)
    17  	}
    18  }
    19  
    20  // Sets p to the inner product of a and b using "pointwise" multiplication.
    21  //
    22  // See MulHat() and NTT() for a description of the multiplication.
    23  // Assumes a and b are in Montgomery form.  p will be in Montgomery form,
    24  // and its coefficients will be bounded in absolute value by 2kq.
    25  // If a and b are not in Montgomery form, then the action is the same
    26  // as "pointwise" multiplication followed by multiplying by R⁻¹, the inverse
    27  // of the Montgomery factor.
    28  func PolyDotHat(p *common.Poly, a, b *Vec) {
    29  	var t common.Poly
    30  	*p = common.Poly{} // set p to zero
    31  	for i := 0; i < K; i++ {
    32  		t.MulHat(&a[i], &b[i])
    33  		p.Add(&t, p)
    34  	}
    35  }
    36  
    37  // Almost normalizes coefficients in-place.
    38  //
    39  // Ensures each coefficient is in {0, …, q}.
    40  func (v *Vec) BarrettReduce() {
    41  	for i := 0; i < K; i++ {
    42  		v[i].BarrettReduce()
    43  	}
    44  }
    45  
    46  // Normalizes coefficients in-place.
    47  //
    48  // Ensures each coefficient is in {0, …, q-1}.
    49  func (v *Vec) Normalize() {
    50  	for i := 0; i < K; i++ {
    51  		v[i].Normalize()
    52  	}
    53  }
    54  
    55  // Applies in-place inverse NTT().  See Poly.InvNTT() for assumptions.
    56  func (v *Vec) InvNTT() {
    57  	for i := 0; i < K; i++ {
    58  		v[i].InvNTT()
    59  	}
    60  }
    61  
    62  // Applies in-place forward NTT().  See Poly.NTT() for assumptions.
    63  func (v *Vec) NTT() {
    64  	for i := 0; i < K; i++ {
    65  		v[i].NTT()
    66  	}
    67  }
    68  
    69  // Sets v to a + b.
    70  func (v *Vec) Add(a, b *Vec) {
    71  	for i := 0; i < K; i++ {
    72  		v[i].Add(&a[i], &b[i])
    73  	}
    74  }
    75  
    76  // Packs v into buf, which must be of length K*PolySize.
    77  func (v *Vec) Pack(buf []byte) {
    78  	for i := 0; i < K; i++ {
    79  		v[i].Pack(buf[common.PolySize*i:])
    80  	}
    81  }
    82  
    83  // Unpacks v from buf which must be of length K*PolySize.
    84  func (v *Vec) Unpack(buf []byte) {
    85  	for i := 0; i < K; i++ {
    86  		v[i].Unpack(buf[common.PolySize*i:])
    87  	}
    88  }
    89  
    90  // Writes Compress_q(v, d) to m.
    91  //
    92  // Assumes v is normalized and d is in {3, 4, 5, 10, 11}.
    93  func (v *Vec) CompressTo(m []byte, d int) {
    94  	size := compressedPolySize(d)
    95  	for i := 0; i < K; i++ {
    96  		v[i].CompressTo(m[size*i:], d)
    97  	}
    98  }
    99  
   100  // Set v to Decompress_q(m, 1).
   101  //
   102  // Assumes d is in {3, 4, 5, 10, 11}.  v will be normalized.
   103  func (v *Vec) Decompress(m []byte, d int) {
   104  	size := compressedPolySize(d)
   105  	for i := 0; i < K; i++ {
   106  		v[i].Decompress(m[size*i:], d)
   107  	}
   108  }
   109  
   110  // ⌈(256 d)/8⌉
   111  func compressedPolySize(d int) int {
   112  	switch d {
   113  	case 4:
   114  		return 128
   115  	case 5:
   116  		return 160
   117  	case 10:
   118  		return 320
   119  	case 11:
   120  		return 352
   121  	}
   122  	panic("unsupported d")
   123  }