1 #include "api.h"
2 #include "inner.h"
3 #include "randombytes.h"
4 #include <stddef.h>
5 #include <string.h>
6 /*
7  * Wrapper for implementing the PQClean API.
8  */
9 
10 
11 
12 #define NONCELEN   40
13 #define SEEDLEN    48
14 
15 /*
16  * Encoding formats (nnnn = log of degree, 9 for Falcon-512, 10 for Falcon-1024)
17  *
18  *   private key:
19  *      header byte: 0101nnnn
20  *      private f  (6 or 5 bits by element, depending on degree)
21  *      private g  (6 or 5 bits by element, depending on degree)
22  *      private F  (8 bits by element)
23  *
24  *   public key:
25  *      header byte: 0000nnnn
26  *      public h   (14 bits by element)
27  *
28  *   signature:
29  *      header byte: 0011nnnn
30  *      nonce     40 bytes
31  *      value     (12 bits by element)
32  *
33  *   message + signature:
34  *      signature length   (2 bytes, big-endian)
35  *      nonce              40 bytes
36  *      message
37  *      header byte:       0010nnnn
38  *      value              (12 bits by element)
39  *      (signature length is 1+len(value), not counting the nonce)
40  */
41 
42 /* see api.h */
43 int
PQCLEAN_FALCON512_AVX2_crypto_sign_keypair(unsigned char * pk,unsigned char * sk)44 PQCLEAN_FALCON512_AVX2_crypto_sign_keypair(unsigned char *pk, unsigned char *sk) {
45     union {
46         uint8_t b[FALCON_KEYGEN_TEMP_9];
47         uint64_t dummy_u64;
48         fpr dummy_fpr;
49     } tmp;
50     int8_t f[512], g[512], F[512];
51     uint16_t h[512];
52     unsigned char seed[SEEDLEN];
53     inner_shake256_context rng;
54     size_t u, v;
55 
56     /*
57      * Generate key pair.
58      */
59     randombytes(seed, sizeof seed);
60     inner_shake256_init(&rng);
61     inner_shake256_inject(&rng, seed, sizeof seed);
62     inner_shake256_flip(&rng);
63     PQCLEAN_FALCON512_AVX2_keygen(&rng, f, g, F, NULL, h, 9, tmp.b);
64     inner_shake256_ctx_release(&rng);
65 
66     /*
67      * Encode private key.
68      */
69     sk[0] = 0x50 + 9;
70     u = 1;
71     v = PQCLEAN_FALCON512_AVX2_trim_i8_encode(
72             sk + u, PQCLEAN_FALCON512_AVX2_CRYPTO_SECRETKEYBYTES - u,
73             f, 9, PQCLEAN_FALCON512_AVX2_max_fg_bits[9]);
74     if (v == 0) {
75         return -1;
76     }
77     u += v;
78     v = PQCLEAN_FALCON512_AVX2_trim_i8_encode(
79             sk + u, PQCLEAN_FALCON512_AVX2_CRYPTO_SECRETKEYBYTES - u,
80             g, 9, PQCLEAN_FALCON512_AVX2_max_fg_bits[9]);
81     if (v == 0) {
82         return -1;
83     }
84     u += v;
85     v = PQCLEAN_FALCON512_AVX2_trim_i8_encode(
86             sk + u, PQCLEAN_FALCON512_AVX2_CRYPTO_SECRETKEYBYTES - u,
87             F, 9, PQCLEAN_FALCON512_AVX2_max_FG_bits[9]);
88     if (v == 0) {
89         return -1;
90     }
91     u += v;
92     if (u != PQCLEAN_FALCON512_AVX2_CRYPTO_SECRETKEYBYTES) {
93         return -1;
94     }
95 
96     /*
97      * Encode public key.
98      */
99     pk[0] = 0x00 + 9;
100     v = PQCLEAN_FALCON512_AVX2_modq_encode(
101             pk + 1, PQCLEAN_FALCON512_AVX2_CRYPTO_PUBLICKEYBYTES - 1,
102             h, 9);
103     if (v != PQCLEAN_FALCON512_AVX2_CRYPTO_PUBLICKEYBYTES - 1) {
104         return -1;
105     }
106 
107     return 0;
108 }
109 
110 /*
111  * Compute the signature. nonce[] receives the nonce and must have length
112  * NONCELEN bytes. sigbuf[] receives the signature value (without nonce
113  * or header byte), with *sigbuflen providing the maximum value length and
114  * receiving the actual value length.
115  *
116  * If a signature could be computed but not encoded because it would
117  * exceed the output buffer size, then a new signature is computed. If
118  * the provided buffer size is too low, this could loop indefinitely, so
119  * the caller must provide a size that can accommodate signatures with a
120  * large enough probability.
121  *
122  * Return value: 0 on success, -1 on error.
123  */
124 static int
do_sign(uint8_t * nonce,uint8_t * sigbuf,size_t * sigbuflen,const uint8_t * m,size_t mlen,const uint8_t * sk)125 do_sign(uint8_t *nonce, uint8_t *sigbuf, size_t *sigbuflen,
126         const uint8_t *m, size_t mlen, const uint8_t *sk) {
127     union {
128         uint8_t b[72 * 512];
129         uint64_t dummy_u64;
130         fpr dummy_fpr;
131     } tmp;
132     int8_t f[512], g[512], F[512], G[512];
133     union {
134         int16_t sig[512];
135         uint16_t hm[512];
136     } r;
137     unsigned char seed[SEEDLEN];
138     inner_shake256_context sc;
139     size_t u, v;
140 
141     /*
142      * Decode the private key.
143      */
144     if (sk[0] != 0x50 + 9) {
145         return -1;
146     }
147     u = 1;
148     v = PQCLEAN_FALCON512_AVX2_trim_i8_decode(
149             f, 9, PQCLEAN_FALCON512_AVX2_max_fg_bits[9],
150             sk + u, PQCLEAN_FALCON512_AVX2_CRYPTO_SECRETKEYBYTES - u);
151     if (v == 0) {
152         return -1;
153     }
154     u += v;
155     v = PQCLEAN_FALCON512_AVX2_trim_i8_decode(
156             g, 9, PQCLEAN_FALCON512_AVX2_max_fg_bits[9],
157             sk + u, PQCLEAN_FALCON512_AVX2_CRYPTO_SECRETKEYBYTES - u);
158     if (v == 0) {
159         return -1;
160     }
161     u += v;
162     v = PQCLEAN_FALCON512_AVX2_trim_i8_decode(
163             F, 9, PQCLEAN_FALCON512_AVX2_max_FG_bits[9],
164             sk + u, PQCLEAN_FALCON512_AVX2_CRYPTO_SECRETKEYBYTES - u);
165     if (v == 0) {
166         return -1;
167     }
168     u += v;
169     if (u != PQCLEAN_FALCON512_AVX2_CRYPTO_SECRETKEYBYTES) {
170         return -1;
171     }
172     if (!PQCLEAN_FALCON512_AVX2_complete_private(G, f, g, F, 9, tmp.b)) {
173         return -1;
174     }
175 
176     /*
177      * Create a random nonce (40 bytes).
178      */
179     randombytes(nonce, NONCELEN);
180 
181     /*
182      * Hash message nonce + message into a vector.
183      */
184     inner_shake256_init(&sc);
185     inner_shake256_inject(&sc, nonce, NONCELEN);
186     inner_shake256_inject(&sc, m, mlen);
187     inner_shake256_flip(&sc);
188     PQCLEAN_FALCON512_AVX2_hash_to_point_ct(&sc, r.hm, 9, tmp.b);
189     inner_shake256_ctx_release(&sc);
190 
191     /*
192      * Initialize a RNG.
193      */
194     randombytes(seed, sizeof seed);
195     inner_shake256_init(&sc);
196     inner_shake256_inject(&sc, seed, sizeof seed);
197     inner_shake256_flip(&sc);
198 
199     /*
200      * Compute and return the signature. This loops until a signature
201      * value is found that fits in the provided buffer.
202      */
203     for (;;) {
204         PQCLEAN_FALCON512_AVX2_sign_dyn(r.sig, &sc, f, g, F, G, r.hm, 9, tmp.b);
205         v = PQCLEAN_FALCON512_AVX2_comp_encode(sigbuf, *sigbuflen, r.sig, 9);
206         if (v != 0) {
207             inner_shake256_ctx_release(&sc);
208             *sigbuflen = v;
209             return 0;
210         }
211     }
212 }
213 
214 /*
215  * Verify a sigature. The nonce has size NONCELEN bytes. sigbuf[]
216  * (of size sigbuflen) contains the signature value, not including the
217  * header byte or nonce. Return value is 0 on success, -1 on error.
218  */
219 static int
do_verify(const uint8_t * nonce,const uint8_t * sigbuf,size_t sigbuflen,const uint8_t * m,size_t mlen,const uint8_t * pk)220 do_verify(
221     const uint8_t *nonce, const uint8_t *sigbuf, size_t sigbuflen,
222     const uint8_t *m, size_t mlen, const uint8_t *pk) {
223     union {
224         uint8_t b[2 * 512];
225         uint64_t dummy_u64;
226         fpr dummy_fpr;
227     } tmp;
228     uint16_t h[512], hm[512];
229     int16_t sig[512];
230     inner_shake256_context sc;
231 
232     /*
233      * Decode public key.
234      */
235     if (pk[0] != 0x00 + 9) {
236         return -1;
237     }
238     if (PQCLEAN_FALCON512_AVX2_modq_decode(h, 9,
239                                            pk + 1, PQCLEAN_FALCON512_AVX2_CRYPTO_PUBLICKEYBYTES - 1)
240             != PQCLEAN_FALCON512_AVX2_CRYPTO_PUBLICKEYBYTES - 1) {
241         return -1;
242     }
243     PQCLEAN_FALCON512_AVX2_to_ntt_monty(h, 9);
244 
245     /*
246      * Decode signature.
247      */
248     if (sigbuflen == 0) {
249         return -1;
250     }
251     if (PQCLEAN_FALCON512_AVX2_comp_decode(sig, 9, sigbuf, sigbuflen) != sigbuflen) {
252         return -1;
253     }
254 
255     /*
256      * Hash nonce + message into a vector.
257      */
258     inner_shake256_init(&sc);
259     inner_shake256_inject(&sc, nonce, NONCELEN);
260     inner_shake256_inject(&sc, m, mlen);
261     inner_shake256_flip(&sc);
262     PQCLEAN_FALCON512_AVX2_hash_to_point_ct(&sc, hm, 9, tmp.b);
263     inner_shake256_ctx_release(&sc);
264 
265     /*
266      * Verify signature.
267      */
268     if (!PQCLEAN_FALCON512_AVX2_verify_raw(hm, sig, h, 9, tmp.b)) {
269         return -1;
270     }
271     return 0;
272 }
273 
274 /* see api.h */
275 int
PQCLEAN_FALCON512_AVX2_crypto_sign_signature(uint8_t * sig,size_t * siglen,const uint8_t * m,size_t mlen,const uint8_t * sk)276 PQCLEAN_FALCON512_AVX2_crypto_sign_signature(
277     uint8_t *sig, size_t *siglen,
278     const uint8_t *m, size_t mlen, const uint8_t *sk) {
279     /*
280      * The PQCLEAN_FALCON512_AVX2_CRYPTO_BYTES constant is used for
281      * the signed message object (as produced by PQCLEAN_FALCON512_AVX2_crypto_sign())
282      * and includes a two-byte length value, so we take care here
283      * to only generate signatures that are two bytes shorter than
284      * the maximum. This is done to ensure that PQCLEAN_FALCON512_AVX2_crypto_sign()
285      * and PQCLEAN_FALCON512_AVX2_crypto_sign_signature() produce the exact same signature
286      * value, if used on the same message, with the same private key,
287      * and using the same output from randombytes() (this is for
288      * reproducibility of tests).
289      */
290     size_t vlen;
291 
292     vlen = PQCLEAN_FALCON512_AVX2_CRYPTO_BYTES - NONCELEN - 3;
293     if (do_sign(sig + 1, sig + 1 + NONCELEN, &vlen, m, mlen, sk) < 0) {
294         return -1;
295     }
296     sig[0] = 0x30 + 9;
297     *siglen = 1 + NONCELEN + vlen;
298     return 0;
299 }
300 
301 /* see api.h */
302 int
PQCLEAN_FALCON512_AVX2_crypto_sign_verify(const uint8_t * sig,size_t siglen,const uint8_t * m,size_t mlen,const uint8_t * pk)303 PQCLEAN_FALCON512_AVX2_crypto_sign_verify(
304     const uint8_t *sig, size_t siglen,
305     const uint8_t *m, size_t mlen, const uint8_t *pk) {
306     if (siglen < 1 + NONCELEN) {
307         return -1;
308     }
309     if (sig[0] != 0x30 + 9) {
310         return -1;
311     }
312     return do_verify(sig + 1,
313                      sig + 1 + NONCELEN, siglen - 1 - NONCELEN, m, mlen, pk);
314 }
315 
316 /* see api.h */
317 int
PQCLEAN_FALCON512_AVX2_crypto_sign(uint8_t * sm,size_t * smlen,const uint8_t * m,size_t mlen,const uint8_t * sk)318 PQCLEAN_FALCON512_AVX2_crypto_sign(
319     uint8_t *sm, size_t *smlen,
320     const uint8_t *m, size_t mlen, const uint8_t *sk) {
321     uint8_t *pm, *sigbuf;
322     size_t sigbuflen;
323 
324     /*
325      * Move the message to its final location; this is a memmove() so
326      * it handles overlaps properly.
327      */
328     memmove(sm + 2 + NONCELEN, m, mlen);
329     pm = sm + 2 + NONCELEN;
330     sigbuf = pm + 1 + mlen;
331     sigbuflen = PQCLEAN_FALCON512_AVX2_CRYPTO_BYTES - NONCELEN - 3;
332     if (do_sign(sm + 2, sigbuf, &sigbuflen, pm, mlen, sk) < 0) {
333         return -1;
334     }
335     pm[mlen] = 0x20 + 9;
336     sigbuflen ++;
337     sm[0] = (uint8_t)(sigbuflen >> 8);
338     sm[1] = (uint8_t)sigbuflen;
339     *smlen = mlen + 2 + NONCELEN + sigbuflen;
340     return 0;
341 }
342 
343 /* see api.h */
344 int
PQCLEAN_FALCON512_AVX2_crypto_sign_open(uint8_t * m,size_t * mlen,const uint8_t * sm,size_t smlen,const uint8_t * pk)345 PQCLEAN_FALCON512_AVX2_crypto_sign_open(
346     uint8_t *m, size_t *mlen,
347     const uint8_t *sm, size_t smlen, const uint8_t *pk) {
348     const uint8_t *sigbuf;
349     size_t pmlen, sigbuflen;
350 
351     if (smlen < 3 + NONCELEN) {
352         return -1;
353     }
354     sigbuflen = ((size_t)sm[0] << 8) | (size_t)sm[1];
355     if (sigbuflen < 2 || sigbuflen > (smlen - NONCELEN - 2)) {
356         return -1;
357     }
358     sigbuflen --;
359     pmlen = smlen - NONCELEN - 3 - sigbuflen;
360     if (sm[2 + NONCELEN + pmlen] != 0x20 + 9) {
361         return -1;
362     }
363     sigbuf = sm + 2 + NONCELEN + pmlen + 1;
364 
365     /*
366      * The 2-byte length header and the one-byte signature header
367      * have been verified. Nonce is at sm+2, followed by the message
368      * itself. Message length is in pmlen. sigbuf/sigbuflen point to
369      * the signature value (excluding the header byte).
370      */
371     if (do_verify(sm + 2, sigbuf, sigbuflen,
372                   sm + 2 + NONCELEN, pmlen, pk) < 0) {
373         return -1;
374     }
375 
376     /*
377      * Signature is correct, we just have to copy/move the message
378      * to its final destination. The memmove() properly handles
379      * overlaps.
380      */
381     memmove(m, sm + 2 + NONCELEN, pmlen);
382     *mlen = pmlen;
383     return 0;
384 }
385