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 }