...
1 package internal
2
3 import (
4 "github.com/cloudflare/circl/sign/dilithium/internal/common"
5 )
6
7
8
9
10
11 func PolyPackLeqEta(p *common.Poly, buf []byte) {
12 if DoubleEtaBits == 4 {
13 j := 0
14 for i := 0; i < PolyLeqEtaSize; i++ {
15 buf[i] = (byte(common.Q+Eta-p[j]) |
16 byte(common.Q+Eta-p[j+1])<<4)
17 j += 2
18 }
19 } else if DoubleEtaBits == 3 {
20 j := 0
21 for i := 0; i < PolyLeqEtaSize; i += 3 {
22 buf[i] = (byte(common.Q+Eta-p[j]) |
23 (byte(common.Q+Eta-p[j+1]) << 3) |
24 (byte(common.Q+Eta-p[j+2]) << 6))
25 buf[i+1] = ((byte(common.Q+Eta-p[j+2]) >> 2) |
26 (byte(common.Q+Eta-p[j+3]) << 1) |
27 (byte(common.Q+Eta-p[j+4]) << 4) |
28 (byte(common.Q+Eta-p[j+5]) << 7))
29 buf[i+2] = ((byte(common.Q+Eta-p[j+5]) >> 1) |
30 (byte(common.Q+Eta-p[j+6]) << 2) |
31 (byte(common.Q+Eta-p[j+7]) << 5))
32 j += 8
33 }
34 } else {
35 panic("eta not supported")
36 }
37 }
38
39
40
41
42
43
44
45
46
47 func PolyUnpackLeqEta(p *common.Poly, buf []byte) {
48 if DoubleEtaBits == 4 {
49 j := 0
50 for i := 0; i < PolyLeqEtaSize; i++ {
51 p[j] = common.Q + Eta - uint32(buf[i]&15)
52 p[j+1] = common.Q + Eta - uint32(buf[i]>>4)
53 j += 2
54 }
55 } else if DoubleEtaBits == 3 {
56 j := 0
57 for i := 0; i < PolyLeqEtaSize; i += 3 {
58 p[j] = common.Q + Eta - uint32(buf[i]&7)
59 p[j+1] = common.Q + Eta - uint32((buf[i]>>3)&7)
60 p[j+2] = common.Q + Eta - uint32((buf[i]>>6)|((buf[i+1]<<2)&7))
61 p[j+3] = common.Q + Eta - uint32((buf[i+1]>>1)&7)
62 p[j+4] = common.Q + Eta - uint32((buf[i+1]>>4)&7)
63 p[j+5] = common.Q + Eta - uint32((buf[i+1]>>7)|((buf[i+2]<<1)&7))
64 p[j+6] = common.Q + Eta - uint32((buf[i+2]>>2)&7)
65 p[j+7] = common.Q + Eta - uint32((buf[i+2]>>5)&7)
66 j += 8
67 }
68 } else {
69 panic("eta not supported")
70 }
71 }
72
73
74
75 func (v *VecK) PackHint(buf []byte) {
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93 off := uint8(0)
94 for i := 0; i < K; i++ {
95 for j := uint16(0); j < common.N; j++ {
96 if v[i][j] != 0 {
97 buf[off] = uint8(j)
98 off++
99 }
100 }
101 buf[Omega+i] = off
102 }
103 for ; off < Omega; off++ {
104 buf[off] = 0
105 }
106 }
107
108
109
110
111 func (v *VecK) UnpackHint(buf []byte) bool {
112
113
114
115
116
117 *v = VecK{}
118 prevSOP := uint8(0)
119 for i := 0; i < K; i++ {
120 SOP := buf[Omega+i]
121 if SOP < prevSOP || SOP > Omega {
122 return false
123 }
124 for j := prevSOP; j < SOP; j++ {
125 if j > prevSOP && buf[j] <= buf[j-1] {
126 return false
127 }
128 v[i][buf[j]] = 1
129 }
130 prevSOP = SOP
131 }
132 for j := prevSOP; j < Omega; j++ {
133 if buf[j] != 0 {
134 return false
135 }
136 }
137
138 return true
139 }
140
141
142
143
144 func PolyUnpackLeGamma1(p *common.Poly, buf []byte) {
145 if Gamma1Bits == 17 {
146 j := 0
147 for i := 0; i < PolyLeGamma1Size; i += 9 {
148 p0 := uint32(buf[i]) | (uint32(buf[i+1]) << 8) |
149 (uint32(buf[i+2]&0x3) << 16)
150 p1 := uint32(buf[i+2]>>2) | (uint32(buf[i+3]) << 6) |
151 (uint32(buf[i+4]&0xf) << 14)
152 p2 := uint32(buf[i+4]>>4) | (uint32(buf[i+5]) << 4) |
153 (uint32(buf[i+6]&0x3f) << 12)
154 p3 := uint32(buf[i+6]>>6) | (uint32(buf[i+7]) << 2) |
155 (uint32(buf[i+8]) << 10)
156
157
158 p0 = Gamma1 - p0
159 p1 = Gamma1 - p1
160 p2 = Gamma1 - p2
161 p3 = Gamma1 - p3
162
163 p0 += uint32(int32(p0)>>31) & common.Q
164 p1 += uint32(int32(p1)>>31) & common.Q
165 p2 += uint32(int32(p2)>>31) & common.Q
166 p3 += uint32(int32(p3)>>31) & common.Q
167
168 p[j] = p0
169 p[j+1] = p1
170 p[j+2] = p2
171 p[j+3] = p3
172
173 j += 4
174 }
175 } else if Gamma1Bits == 19 {
176 j := 0
177 for i := 0; i < PolyLeGamma1Size; i += 5 {
178 p0 := uint32(buf[i]) | (uint32(buf[i+1]) << 8) |
179 (uint32(buf[i+2]&0xf) << 16)
180 p1 := uint32(buf[i+2]>>4) | (uint32(buf[i+3]) << 4) |
181 (uint32(buf[i+4]) << 12)
182
183 p0 = Gamma1 - p0
184 p1 = Gamma1 - p1
185
186 p0 += uint32(int32(p0)>>31) & common.Q
187 p1 += uint32(int32(p1)>>31) & common.Q
188
189 p[j] = p0
190 p[j+1] = p1
191
192 j += 2
193 }
194 } else {
195 panic("γ₁ not supported")
196 }
197 }
198
199
200
201
202
203 func PolyPackLeGamma1(p *common.Poly, buf []byte) {
204 if Gamma1Bits == 17 {
205 j := 0
206
207 for i := 0; i < PolyLeGamma1Size; i += 9 {
208 p0 := Gamma1 - p[j]
209 p0 += uint32(int32(p0)>>31) & common.Q
210 p1 := Gamma1 - p[j+1]
211 p1 += uint32(int32(p1)>>31) & common.Q
212 p2 := Gamma1 - p[j+2]
213 p2 += uint32(int32(p2)>>31) & common.Q
214 p3 := Gamma1 - p[j+3]
215 p3 += uint32(int32(p3)>>31) & common.Q
216
217 buf[i+0] = byte(p0)
218 buf[i+1] = byte(p0 >> 8)
219 buf[i+2] = byte(p0>>16) | byte(p1<<2)
220 buf[i+3] = byte(p1 >> 6)
221 buf[i+4] = byte(p1>>14) | byte(p2<<4)
222 buf[i+5] = byte(p2 >> 4)
223 buf[i+6] = byte(p2>>12) | byte(p3<<6)
224 buf[i+7] = byte(p3 >> 2)
225 buf[i+8] = byte(p3 >> 10)
226
227 j += 4
228 }
229 } else if Gamma1Bits == 19 {
230 j := 0
231 for i := 0; i < PolyLeGamma1Size; i += 5 {
232
233 p0 := Gamma1 - p[j]
234 p0 += uint32(int32(p0)>>31) & common.Q
235 p1 := Gamma1 - p[j+1]
236 p1 += uint32(int32(p1)>>31) & common.Q
237
238 buf[i+0] = byte(p0)
239 buf[i+1] = byte(p0 >> 8)
240 buf[i+2] = byte(p0>>16) | byte(p1<<4)
241 buf[i+3] = byte(p1 >> 4)
242 buf[i+4] = byte(p1 >> 12)
243
244 j += 2
245 }
246 } else {
247 panic("γ₁ not supported")
248 }
249 }
250
251
252
253
254 func PolyPackW1(p *common.Poly, buf []byte) {
255 if Gamma1Bits == 19 {
256 p.PackLe16(buf)
257 } else if Gamma1Bits == 17 {
258 j := 0
259 for i := 0; i < PolyW1Size; i += 3 {
260 buf[i] = byte(p[j]) | byte(p[j+1]<<6)
261 buf[i+1] = byte(p[j+1]>>2) | byte(p[j+2]<<4)
262 buf[i+2] = byte(p[j+2]>>4) | byte(p[j+3]<<2)
263 j += 4
264 }
265 } else {
266 panic("unsupported γ₁")
267 }
268 }
269
View as plain text