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