* Copied qTESLA-p-I round2 (2019-08-19) code * Code compiles, NIST-KAT works * Included detached signature API * Generated testvectors * Fixed name in api.h * code style * Fixed error in Makefile * Passing pytest * Fixing types (uint8_t bytes and size_t indices) * Replaced SHAKE with SHAKE128 where necessary * Fixed bug: (signed) integer overflow * Added qTESLA-p-III * Code is now independent of machine endianness * repaired Microsoft makefiletags/v0.0.1
@@ -0,0 +1,25 @@ | |||||
name: qTESLA-p-I | |||||
type: signature | |||||
claimed-nist-level: 1 | |||||
length-public-key: 14880 | |||||
length-secret-key: 5184 | |||||
length-signature: 2592 | |||||
nistkat-sha256: e6bc42e0281cd95865e9707181a381b81f84c85957cd8e46a7889179769707dd | |||||
testvectors-sha256: b2ebe8cc08c43a46648b3801236aeb6691e0bf2e683e77c3820dd22ee7fd9574 | |||||
principal-submitters: | |||||
- Nina Bindel | |||||
auxiliary-submitters: | |||||
- Sedat Akleylek | |||||
- Erdem Alkim | |||||
- Paulo S. L. M. Barreto | |||||
- Johannes Buchmann | |||||
- Edward Eaton | |||||
- Gus Gutoski | |||||
- Juliane Krämer | |||||
- Patrick Longa | |||||
- Harun Polat | |||||
- Jefferson E. Ricardini | |||||
- Gustavo Zanon | |||||
implementations: | |||||
- name: clean | |||||
version: https://qtesla.org/wp-content/uploads/2019/08/qTESLA_NIST_update_08.19.2019.zip |
@@ -0,0 +1,109 @@ | |||||
#ifndef PQCLEAN_QTESLAPI_CLEAN_CDTSAMP | |||||
#define PQCLEAN_QTESLAPI_CLEAN_CDTSAMP | |||||
/************************************************************************************* | |||||
* qTESLA: an efficient post-quantum signature scheme based on the R-LWE problem | |||||
* | |||||
* Abstract: CDT constants for the Gaussian sampler | |||||
**************************************************************************************/ | |||||
#include "params.h" | |||||
#include <stdint.h> | |||||
// Sigma = 8.5, 64-bit precision | |||||
#define CDT_ROWS 78 | |||||
#define CDT_COLS 2 | |||||
static const int32_t cdt_v[CDT_ROWS * CDT_COLS] = { | |||||
0x00000000L, 0x00000000L, // 0 | |||||
0x0601F22AL, 0x280663D4L, // 1 | |||||
0x11F09FFAL, 0x162FE23DL, // 2 | |||||
0x1DA089E9L, 0x437226E8L, // 3 | |||||
0x28EAB25DL, 0x04C51FE2L, // 4 | |||||
0x33AC2F26L, 0x14FDBA70L, // 5 | |||||
0x3DC767DCL, 0x4565C960L, // 6 | |||||
0x4724FC62L, 0x3342C78AL, // 7 | |||||
0x4FB448F4L, 0x5229D06DL, // 8 | |||||
0x576B8599L, 0x7423407FL, // 9 | |||||
0x5E4786DAL, 0x3210BAF7L, // 10 | |||||
0x644B2C92L, 0x431B3947L, // 11 | |||||
0x697E90CEL, 0x77C362C4L, // 12 | |||||
0x6DEE0B96L, 0x2798C9CEL, // 13 | |||||
0x71A92144L, 0x5765FCE4L, // 14 | |||||
0x74C16FD5L, 0x1E2A0990L, // 15 | |||||
0x7749AC92L, 0x0DF36EEBL, // 16 | |||||
0x7954BFA4L, 0x28079289L, // 17 | |||||
0x7AF5067AL, 0x2EDC2050L, // 18 | |||||
0x7C3BC17CL, 0x123D5E7BL, // 19 | |||||
0x7D38AD76L, 0x2A9381D9L, // 20 | |||||
0x7DF9C5DFL, 0x0E868CA7L, // 21 | |||||
0x7E8B2ABAL, 0x18E5C811L, // 22 | |||||
0x7EF7237CL, 0x00908272L, // 23 | |||||
0x7F4637C5L, 0x6DBA5126L, // 24 | |||||
0x7F7F5707L, 0x4A52EDEBL, // 25 | |||||
0x7FA808CCL, 0x23290599L, // 26 | |||||
0x7FC4A083L, 0x69BDF2D5L, // 27 | |||||
0x7FD870CAL, 0x42275558L, // 28 | |||||
0x7FE5FB5DL, 0x3EF82C1BL, // 29 | |||||
0x7FEF1BFAL, 0x6C03A362L, // 30 | |||||
0x7FF52D4EL, 0x316C2C8CL, // 31 | |||||
0x7FF927BAL, 0x12AE54AFL, // 32 | |||||
0x7FFBBA43L, 0x749CC0E2L, // 33 | |||||
0x7FFD5E3DL, 0x4524AD91L, // 34 | |||||
0x7FFE6664L, 0x535785B5L, // 35 | |||||
0x7FFF0A41L, 0x0B291681L, // 36 | |||||
0x7FFF6E81L, 0x132C3D6FL, // 37 | |||||
0x7FFFAAFEL, 0x4DBC6BEDL, // 38 | |||||
0x7FFFCEFDL, 0x7A1E2D14L, // 39 | |||||
0x7FFFE41EL, 0x4C6EC115L, // 40 | |||||
0x7FFFF059L, 0x319503C8L, // 41 | |||||
0x7FFFF754L, 0x5DDD0D40L, // 42 | |||||
0x7FFFFB43L, 0x0B9E9823L, // 43 | |||||
0x7FFFFD71L, 0x76B81AE1L, // 44 | |||||
0x7FFFFEA3L, 0x7E66A1ECL, // 45 | |||||
0x7FFFFF49L, 0x26F6E191L, // 46 | |||||
0x7FFFFFA1L, 0x2FA31694L, // 47 | |||||
0x7FFFFFCFL, 0x5247BEC9L, // 48 | |||||
0x7FFFFFE7L, 0x4F4127C7L, // 49 | |||||
0x7FFFFFF3L, 0x6FAA69FDL, // 50 | |||||
0x7FFFFFFAL, 0x0630D073L, // 51 | |||||
0x7FFFFFFDL, 0x0F2957BBL, // 52 | |||||
0x7FFFFFFEL, 0x4FD29432L, // 53 | |||||
0x7FFFFFFFL, 0x2CFAD60DL, // 54 | |||||
0x7FFFFFFFL, 0x5967A930L, // 55 | |||||
0x7FFFFFFFL, 0x6E4C9DFFL, // 56 | |||||
0x7FFFFFFFL, 0x77FDCCC8L, // 57 | |||||
0x7FFFFFFFL, 0x7C6CE89EL, // 58 | |||||
0x7FFFFFFFL, 0x7E6D116FL, // 59 | |||||
0x7FFFFFFFL, 0x7F50FA31L, // 60 | |||||
0x7FFFFFFFL, 0x7FB50089L, // 61 | |||||
0x7FFFFFFFL, 0x7FE04C2DL, // 62 | |||||
0x7FFFFFFFL, 0x7FF2C7C1L, // 63 | |||||
0x7FFFFFFFL, 0x7FFA8FE3L, // 64 | |||||
0x7FFFFFFFL, 0x7FFDCB1BL, // 65 | |||||
0x7FFFFFFFL, 0x7FFF1DE2L, // 66 | |||||
0x7FFFFFFFL, 0x7FFFA6B7L, // 67 | |||||
0x7FFFFFFFL, 0x7FFFDD39L, // 68 | |||||
0x7FFFFFFFL, 0x7FFFF2A3L, // 69 | |||||
0x7FFFFFFFL, 0x7FFFFAEFL, // 70 | |||||
0x7FFFFFFFL, 0x7FFFFE1BL, // 71 | |||||
0x7FFFFFFFL, 0x7FFFFF4DL, // 72 | |||||
0x7FFFFFFFL, 0x7FFFFFBFL, // 73 | |||||
0x7FFFFFFFL, 0x7FFFFFE9L, // 74 | |||||
0x7FFFFFFFL, 0x7FFFFFF8L, // 75 | |||||
0x7FFFFFFFL, 0x7FFFFFFDL, // 76 | |||||
0x7FFFFFFFL, 0x7FFFFFFFL, // 77 | |||||
}; // cdt_v | |||||
// memory requirements: | |||||
// 2048 samples: 25512 bytes | |||||
// 1024 samples: 13224 bytes | |||||
// 512 samples: 7080 bytes | |||||
// 256 samples: 4008 bytes | |||||
// 128 samples: 2472 bytes | |||||
// 64 samples: 1704 bytes | |||||
// 32 samples: 1320 bytes | |||||
// table alone: 624 bytes | |||||
#endif |
@@ -0,0 +1,28 @@ | |||||
Lattice-based digital signature scheme qTESLA | |||||
The qTESLA source code and header files in this package are released with an MIT license. | |||||
MIT License | |||||
Copyright (c) Microsoft Corporation and qTESLA implementation owners: | |||||
Sedat Akleylek, Erdem Alkim, Paulo Barreto, Patrick Longa, Harun Polat, | |||||
Jefferson Ricardini, and Gustavo Zanon. All rights reserved. | |||||
Permission is hereby granted, free of charge, to any person obtaining a copy | |||||
of this software and associated documentation files (the "Software"), to deal | |||||
in the Software without restriction, including without limitation the rights | |||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||||
copies of the Software, and to permit persons to whom the Software is | |||||
furnished to do so, subject to the following conditions: | |||||
The above copyright notice and this permission notice shall be included in all | |||||
copies or substantial portions of the Software. | |||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||||
SOFTWARE | |||||
@@ -0,0 +1,20 @@ | |||||
# This Makefile can be used with GNU Make or BSD Make | |||||
LIB=libqtesla-p-I_clean.a | |||||
HEADERS = api.h CDT32.h config.h gauss.h pack.h params.h poly.h sample.h | |||||
OBJECTS = consts.o gauss.o pack.o poly.o sample.o sign.o | |||||
CFLAGS=-O3 -Wall -Wconversion -Wextra -Wpedantic -Wvla -Werror -Wmissing-prototypes -Wredundant-decls -std=c99 -I../../../common $(EXTRAFLAGS) | |||||
all: $(LIB) | |||||
%.o: %.c $(HEADERS) | |||||
$(CC) $(CFLAGS) -c -o $@ $< | |||||
$(LIB): $(OBJECTS) | |||||
$(AR) -r $@ $(OBJECTS) | |||||
clean: | |||||
$(RM) $(OBJECTS) | |||||
$(RM) $(LIB) |
@@ -0,0 +1,19 @@ | |||||
# This Makefile can be used with Microsoft Visual Studio's nmake using the command: | |||||
# nmake /f Makefile.Microsoft_nmake | |||||
LIBRARY=libqtesla-p-I_clean.lib | |||||
OBJECTS=consts.obj gauss.obj pack.obj poly.obj sample.obj sign.obj | |||||
CFLAGS=/nologo /I ..\..\..\common /W4 /WX | |||||
all: $(LIBRARY) | |||||
# Make sure objects are recompiled if headers change. | |||||
$(OBJECTS): *.h | |||||
$(LIBRARY): $(OBJECTS) | |||||
LIB.EXE /NOLOGO /WX /OUT:$@ $** | |||||
clean: | |||||
-DEL $(OBJECTS) | |||||
-DEL $(LIBRARY) |
@@ -0,0 +1,42 @@ | |||||
#ifndef PQCLEAN_QTESLAPI_CLEAN_API_H | |||||
#define PQCLEAN_QTESLAPI_CLEAN_API_H | |||||
/************************************************************************************* | |||||
* qTESLA: an efficient post-quantum signature scheme based on the R-LWE problem | |||||
* | |||||
* Abstract: API header file | |||||
**************************************************************************************/ | |||||
#include <stddef.h> | |||||
#include <stdint.h> | |||||
#define PQCLEAN_QTESLAPI_CLEAN_CRYPTO_SECRETKEYBYTES 5184 | |||||
#define PQCLEAN_QTESLAPI_CLEAN_CRYPTO_PUBLICKEYBYTES 14880 | |||||
#define PQCLEAN_QTESLAPI_CLEAN_CRYPTO_BYTES 2592 | |||||
#define PQCLEAN_QTESLAPI_CLEAN_CRYPTO_ALGNAME "qTESLA-p-I" | |||||
int PQCLEAN_QTESLAPI_CLEAN_crypto_sign_keypair( | |||||
uint8_t *pk, uint8_t *sk); | |||||
int PQCLEAN_QTESLAPI_CLEAN_crypto_sign( | |||||
uint8_t *sm, size_t *smlen, | |||||
const uint8_t *m, size_t mlen, | |||||
const uint8_t *sk); | |||||
int PQCLEAN_QTESLAPI_CLEAN_crypto_sign_open( | |||||
uint8_t *m, size_t *mlen, | |||||
const uint8_t *sm, size_t smlen, | |||||
const uint8_t *pk | |||||
); | |||||
int PQCLEAN_QTESLAPI_CLEAN_crypto_sign_signature( | |||||
uint8_t *sig, size_t *siglen, | |||||
const uint8_t *m, size_t mlen, | |||||
const uint8_t *sk); | |||||
int PQCLEAN_QTESLAPI_CLEAN_crypto_sign_verify( | |||||
const uint8_t *sig, size_t siglen, | |||||
const uint8_t *m, size_t mlen, | |||||
const uint8_t *pk); | |||||
#endif |
@@ -0,0 +1,19 @@ | |||||
#ifndef PQCLEAN_QTESLAPI_CLEAN_CONFIG_H | |||||
#define PQCLEAN_QTESLAPI_CLEAN_CONFIG_H | |||||
/************************************************************************************* | |||||
* qTESLA: an efficient post-quantum signature scheme based on the R-LWE problem | |||||
* | |||||
* Abstract: configuration file | |||||
**************************************************************************************/ | |||||
#include <stdbool.h> | |||||
#include <stddef.h> | |||||
#include <stdint.h> | |||||
#define RADIX 32 | |||||
#define RADIX32 32 | |||||
typedef uint32_t digit_t; | |||||
typedef int32_t sdigit_t; | |||||
#endif |
@@ -0,0 +1,146 @@ | |||||
/************************************************************************************* | |||||
* qTESLA: an efficient post-quantum signature scheme based on the R-LWE problem | |||||
* | |||||
* Abstract: constants for the NTT | |||||
**************************************************************************************/ | |||||
#include "params.h" | |||||
#include "poly.h" | |||||
#include <stdint.h> | |||||
const poly PQCLEAN_QTESLAPI_CLEAN_zeta = { | |||||
184007114, 341297933, 172127038, 306069179, 260374244, 269720605, 20436325, 2157599, 36206659, 61987110, 112759694, 92762708, 278504038, 139026960, 183642748, 298230187, | |||||
37043356, 230730845, 107820937, 97015745, 156688276, 38891102, 170244636, 259345227, 170077366, 141586883, 100118513, 328793523, 289946488, 263574185, 132014089, 14516260, | |||||
87424978, 192691578, 190961717, 262687761, 333967048, 12957952, 326574509, 273585413, 151922543, 195893203, 261889302, 120488377, 169571794, 44896463, 128576039, 68257019, | |||||
20594664, 44164717, 36060712, 256009818, 172063915, 211967562, 135533785, 104908181, 203788155, 52968398, 123297488, 44711423, 329131026, 245797804, 220629853, 200431766, | |||||
92905498, 215466666, 227373088, 120513729, 274875394, 236766448, 84216704, 97363940, 224003799, 167341181, 333540791, 225846253, 290150331, 137934911, 101127339, 95054535, | |||||
7072757, 58600117, 264117725, 207480694, 268253444, 292044590, 166300682, 256585624, 133577520, 119707476, 58169614, 188489502, 184778640, 156039906, 286669262, 112658784, | |||||
89254003, 266568758, 290599527, 80715937, 180664712, 225980378, 103512701, 304604206, 327443646, 92082345, 296093912, 144843084, 309484036, 329737605, 141656867, 264967053, | |||||
227847682, 328674715, 208663554, 309005608, 315790590, 182996330, 333212133, 203436199, 13052895, 23858345, 173478900, 97132319, 57066271, 70747422, 202106993, 309870606, | |||||
56390934, 336126437, 189147643, 219236223, 293351741, 305570320, 18378834, 336914091, 59506067, 277923611, 217306643, 129369847, 308113789, 56954705, 190254906, 199465001, | |||||
119331054, 143640880, 17590914, 309468163, 172483421, 153376031, 58864560, 70957183, 237697179, 116097341, 62196815, 80692520, 310642530, 328595292, 12121494, 71200620, | |||||
200016287, 235006678, 21821056, 102505389, 183332133, 59734849, 283127491, 313646880, 30359439, 163176989, 50717815, 100183661, 322975554, 92821217, 283119421, 34453836, | |||||
303758926, 89460722, 147514506, 175603941, 76494101, 220775631, 304963431, 38821441, 217317485, 301302769, 328727631, 101476595, 270750726, 253708871, 176201368, 324059659, | |||||
114780906, 304156831, 273708648, 144095014, 263545324, 179240984, 187811389, 244886526, 202581571, 209325648, 117231636, 182195945, 217965216, 252295904, 332003328, 46153749, | |||||
334740528, 62618402, 301165510, 283016648, 212224416, 234984074, 107363471, 125430881, 172821269, 270409387, 156316970, 311644197, 50537885, 248376507, 154072039, 331539029, | |||||
48454192, 267029920, 225963915, 16753350, 76840946, 226444843, 108106635, 154887261, 326283837, 101291223, 204194230, 54014060, 104099734, 104245071, 260949411, 333985274, | |||||
291682234, 328313139, 29607387, 106291750, 162553334, 275058303, 64179189, 263147140, 15599810, 325103190, 137254480, 66787068, 4755224, 308520011, 181897417, 325162685, | |||||
221099032, 131741505, 147534370, 131533267, 144073688, 166398146, 155829711, 252509898, 251605008, 323547097, 216038649, 232629333, 95137254, 287931575, 235583527, 32386598, | |||||
76722491, 60825791, 138354268, 400761, 51907675, 197369064, 319840588, 98618414, 84343982, 108113946, 314679670, 134518178, 64988900, 4333172, 295712261, 200707216, | |||||
147647414, 318013383, 77682006, 92518996, 42154619, 87464521, 285037574, 332936592, 62635246, 5534097, 308862707, 91097989, 269726589, 273280832, 251670430, 95492698, | |||||
21676891, 182964692, 177187742, 294825274, 85128609, 273594538, 93115857, 116308166, 312212122, 18665807, 32192823, 313249299, 98777368, 273984239, 312125377, 205655336, | |||||
264861277, 178920022, 341054719, 232663249, 173564046, 176591124, 157537342, 305058098, 277279130, 170028356, 228573747, 31628995, 175280663, 37304323, 122111670, 210658936, | |||||
175704183, 314649282, 325535066, 266783938, 301319742, 327923297, 279787306, 304633001, 304153402, 292839078, 147442886, 94150133, 40461238, 221384781, 269671052, 265445273, | |||||
208370149, 160863546, 287765159, 339146643, 129600429, 96192870, 113146118, 95879915, 216708053, 285201955, 67756451, 79028039, 309141895, 138447809, 212246614, 12641916, | |||||
243544995, 33459809, 76979779, 71155723, 152521243, 200750888, 36425947, 339074467, 319204591, 188312744, 266105966, 280016981, 183723313, 238915015, 23277613, 160934729, | |||||
200611286, 163282810, 297928823, 226921588, 86839172, 145317111, 202226936, 51887320, 318474782, 282270658, 221219795, 207597867, 132089009, 334627662, 163952597, 67529059, | |||||
173759630, 234865017, 255217646, 277806158, 61964704, 216678166, 96126463, 39218331, 70028373, 4899005, 238135514, 242700690, 284680271, 81041980, 332906491, 463527, | |||||
299280916, 204600651, 149654879, 222229829, 26825157, 81825189, 127990873, 200962599, 16149163, 108812393, 217708971, 152638110, 28735779, 5272794, 19720409, 231726324, | |||||
49854178, 118319174, 185669526, 223407181, 243138094, 259020958, 308825615, 164156486, 341391280, 192526841, 97036052, 279986894, 20263748, 32228956, 43816679, 343421811, | |||||
124320208, 3484106, 31711063, 147679160, 195369505, 54243678, 279088595, 149119313, 301997352, 244557309, 19700779, 138872683, 230523717, 113507709, 135291486, 313025300, | |||||
254384479, 219815764, 253574481, 220646316, 124744817, 123915741, 325760383, 123516396, 138140410, 154060994, 314730104, 57286356, 222353426, 76630003, 145380041, 52039855, | |||||
229881219, 332902036, 152308429, 95071889, 124799350, 270141530, 47897266, 119620601, 133269057, 138561303, 341820265, 66049665, 273409631, 304306012, 212490958, 210388603, | |||||
277413768, 280793261, 223131872, 162407285, 44911970, 316685837, 298709373, 252812339, 230786851, 230319350, 56863422, 341141914, 177295413, 248222411, 215148650, 97970603, | |||||
291678055, 161911155, 339645428, 206445182, 31895080, 279676698, 78257775, 268845232, 92545841, 336725589, 47384597, 62216335, 82290365, 89893410, 266117967, 791867, | |||||
28042243, 110563426, 183316855, 281174508, 166338432, 86326996, 261473803, 164647535, 84749290, 157518777, 214336587, 72257047, 13358702, 229010735, 204196474, 179927635, | |||||
21786785, 330554989, 164559635, 144505300, 280425045, 324057501, 268227440, 323362437, 26891539, 228523003, 166709094, 61174973, 13532911, 42168701, 133044957, 158219357, | |||||
220115616, 15174468, 281706353, 283813987, 263212325, 289818392, 247170937, 276072317, 197581495, 33713097, 181695825, 96829354, 32991226, 228583784, 4040287, 65188717, | |||||
258204083, 96366799, 176298395, 341574369, 306098123, 218746932, 29191888, 311810435, 305844323, 31614267, 28130094, 72716426, 38568041, 197579396, 14876445, 228525674, | |||||
294569685, 2451649, 165929882, 112195415, 204786047, 138216235, 3438132, 126150615, 59754608, 158965324, 268160978, 266231264, 244422459, 306155336, 218178824, 301806695, | |||||
208837335, 212153467, 209725081, 269355286, 295716530, 13980580, 264284060, 301901789, 275319045, 107139083, 4006959, 143908623, 139848274, 25357089, 21607040, 340818603, | |||||
91260932, 198869267, 45119941, 224113252, 269556513, 42857483, 268925602, 188501450, 235382337, 324688793, 113056679, 177232352, 98280013, 117743899, 87369665, 330110286, | |||||
310895756, 268425063, 27568325, 266303142, 181405304, 65876631, 246283438, 127636847, 16153922, 210256884, 9257227, 147272724, 235571791, 340876897, 31558760, 224463520, | |||||
229909008, 40943950, 263351999, 14865952, 27279162, 51980445, 99553161, 108121152, 145230283, 217402431, 84060866, 190168688, 46894008, 205718237, 296935065, 331646198, | |||||
59709076, 265829428, 214503586, 310273189, 86051634, 247210969, 275872780, 55395653, 302717617, 155583500, 207999042, 293597246, 305796948, 139332832, 198434142, 104197059, | |||||
320317582, 101819543, 70813687, 43594385, 241913829, 210308279, 298735610, 151599086, 92093482, 24654121, 52528801, 134711941, 324580593, 293101038, 121757877, 323940193, | |||||
276114751, 33522997, 218880483, 46953248, 33126382, 294367143, 161595040, 208968904, 129221110, 323693686, 234366848, 50155901, 123936119, 72127416, 34243899, 171824126, | |||||
26019236, 93997235, 28452989, 24219933, 188331672, 181161011, 146526219, 186502916, 258266311, 207146754, 206589869, 189836867, 107762500, 129011227, 222324073, 331319091, | |||||
36618753, 141615400, 273319528, 246222615, 156139193, 290104141, 154851520, 310226922, 60187406, 73704819, 225899604, 87931539, 142487643, 152682959, 45891249, 212048348, | |||||
148547910, 207745063, 4405848, 179269204, 216233362, 230307487, 303352796, 41616117, 47140231, 13452075, 94626849, 48892822, 78453712, 214721933, 300785835, 1512599, | |||||
173577933, 163255132, 239883248, 205714288, 306118903, 106953300, 150085654, 77068348, 246390345, 199698311, 280165539, 256497526, 194381508, 78125966, 168327358, 180735395, | |||||
145983352, 243342736, 198463602, 83165996, 286431792, 22885329, 271516106, 66137359, 243561376, 324886778, 149497212, 24531379, 32857894, 62778029, 56960216, 224996784, | |||||
129315394, 81068505, 277744916, 215817366, 117205172, 195090165, 287841567, 57750901, 162987791, 259309908, 135370005, 194853269, 236792732, 219249166, 42349628, 27805769, | |||||
186263338, 310699018, 6491000, 228545163, 315890485, 22219119, 144392189, 15505150, 87848372, 155973124, 20446561, 177725890, 226669021, 205315635, 269580641, 133696452, | |||||
189388357, 314652032, 317225560, 304194584, 157633737, 298144493, 185785271, 337434647, 559796, 4438732, 249110619, 184824722, 221490126, 205632858, 172362641, 176702767, | |||||
276712118, 296075254, 111221225, 259809961, 15438443, 198021462, 134378223, 162261445, 170746654, 256890644, 125206341, 307078324, 279553989, 170124925, 296845387, 188226544, | |||||
295437875, 315053523, 172025817, 279046062, 189967278, 158662482, 192989875, 326540363, 135446089, 98631439, 257379933, 325004289, 26554274, 62190249, 228828648, 274361329, | |||||
18518762, 184854759, 210189061, 186836398, 230859454, 206912014, 201250021, 276332768, 119984643, 91358832, 325377399, 69085488, 307352479, 308876137, 208756649, 32865966, | |||||
152976045, 207821125, 66426662, 67585526, 118828370, 3107192, 322037257, 146029104, 106553806, 266958791, 89567376, 153815988, 90786397, 271042585, 203781777, 169087756, | |||||
315867500, 306916544, 7528726, 327732739, 227901532, 2263402, 14357894, 269740764, 322090105, 59838559, 298337502, 292797139, 337635349, 66476915, 75612762, 328089387, | |||||
155232910, 87069405, 36163560, 273715413, 321325749, 218096743, 308178877, 21861281, 180676741, 135208372, 119891712, 122406065, 267537516, 341350322, 87789083, 196340943, | |||||
217070591, 83564209, 159382818, 253921239, 184673854, 213569600, 194031064, 35973794, 18071215, 250854127, 115090766, 147707843, 330337973, 266187164, 27853295, 296801215, | |||||
254949704, 43331190, 73930201, 35703461, 119780800, 216998106, 12687572, 250863345, 243908221, 330555990, 296216993, 202100577, 111307303, 151049872, 103451600, 237710099, | |||||
78658022, 121490075, 134292528, 88277916, 177315676, 186629690, 77848818, 211822377, 145696683, 289190386, 274721999, 328391282, 218772820, 91324151, 321725584, 277577004, | |||||
65732866, 275538085, 144429136, 204062923, 177280727, 214204692, 264758257, 169151951, 335535576, 334002493, 281131703, 305997258, 310527888, 136973519, 216764406, 235954329, | |||||
254049694, 285174861, 264316834, 11792643, 149333889, 214699018, 261331547, 317320791, 24527858, 118790777, 264146824, 174296812, 332779737, 94199786, 288227027, 172048372, | |||||
}; | |||||
const poly PQCLEAN_QTESLAPI_CLEAN_zetainv = { | |||||
55349550, 249376791, 10796840, 169279765, 79429753, 224785800, 319048719, 26255786, 82245030, 128877559, 194242688, 331783934, 79259743, 58401716, 89526883, 107622248, | |||||
126812171, 206603058, 33048689, 37579319, 62444874, 9574084, 8041001, 174424626, 78818320, 129371885, 166295850, 139513654, 199147441, 68038492, 277843711, 65999573, | |||||
21850993, 252252426, 124803757, 15185295, 68854578, 54386191, 197879894, 131754200, 265727759, 156946887, 166260901, 255298661, 209284049, 222086502, 264918555, 105866478, | |||||
240124977, 192526705, 232269274, 141476000, 47359584, 13020587, 99668356, 92713232, 330889005, 126578471, 223795777, 307873116, 269646376, 300245387, 88626873, 46775362, | |||||
315723282, 77389413, 13238604, 195868734, 228485811, 92722450, 325505362, 307602783, 149545513, 130006977, 158902723, 89655338, 184193759, 260012368, 126505986, 147235634, | |||||
255787494, 2226255, 76039061, 221170512, 223684865, 208368205, 162899836, 321715296, 35397700, 125479834, 22250828, 69861164, 307413017, 256507172, 188343667, 15487190, | |||||
267963815, 277099662, 5941228, 50779438, 45239075, 283738018, 21486472, 73835813, 329218683, 341313175, 115675045, 15843838, 336047851, 36660033, 27709077, 174488821, | |||||
139794800, 72533992, 252790180, 189760589, 254009201, 76617786, 237022771, 197547473, 21539320, 340469385, 224748207, 275991051, 277149915, 135755452, 190600532, 310710611, | |||||
134819928, 34700440, 36224098, 274491089, 18199178, 252217745, 223591934, 67243809, 142326556, 136664563, 112717123, 156740179, 133387516, 158721818, 325057815, 69215248, | |||||
114747929, 281386328, 317022303, 18572288, 86196644, 244945138, 208130488, 17036214, 150586702, 184914095, 153609299, 64530515, 171550760, 28523054, 48138702, 155350033, | |||||
46731190, 173451652, 64022588, 36498253, 218370236, 86685933, 172829923, 181315132, 209198354, 145555115, 328138134, 83766616, 232355352, 47501323, 66864459, 166873810, | |||||
171213936, 137943719, 122086451, 158751855, 94465958, 339137845, 343016781, 6141930, 157791306, 45432084, 185942840, 39381993, 26351017, 28924545, 154188220, 209880125, | |||||
73995936, 138260942, 116907556, 165850687, 323130016, 187603453, 255728205, 328071427, 199184388, 321357458, 27686092, 115031414, 337085577, 32877559, 157313239, 315770808, | |||||
301226949, 124327411, 106783845, 148723308, 208206572, 84266669, 180588786, 285825676, 55735010, 148486412, 226371405, 127759211, 65831661, 262508072, 214261183, 118579793, | |||||
286616361, 280798548, 310718683, 319045198, 194079365, 18689799, 100015201, 277439218, 72060471, 320691248, 57144785, 260410581, 145112975, 100233841, 197593225, 162841182, | |||||
175249219, 265450611, 149195069, 87079051, 63411038, 143878266, 97186232, 266508229, 193490923, 236623277, 37457674, 137862289, 103693329, 180321445, 169998644, 342063978, | |||||
42790742, 128854644, 265122865, 294683755, 248949728, 330124502, 296436346, 301960460, 40223781, 113269090, 127343215, 164307373, 339170729, 135831514, 195028667, 131528229, | |||||
297685328, 190893618, 201088934, 255645038, 117676973, 269871758, 283389171, 33349655, 188725057, 53472436, 187437384, 97353962, 70257049, 201961177, 306957824, 12257486, | |||||
121252504, 214565350, 235814077, 153739710, 136986708, 136429823, 85310266, 157073661, 197050358, 162415566, 155244905, 319356644, 315123588, 249579342, 317557341, 171752451, | |||||
309332678, 271449161, 219640458, 293420676, 109209729, 19882891, 214355467, 134607673, 181981537, 49209434, 310450195, 296623329, 124696094, 310053580, 67461826, 19636384, | |||||
221818700, 50475539, 18995984, 208864636, 291047776, 318922456, 251483095, 191977491, 44840967, 133268298, 101662748, 299982192, 272762890, 241757034, 23258995, 239379518, | |||||
145142435, 204243745, 37779629, 49979331, 135577535, 187993077, 40858960, 288180924, 67703797, 96365608, 257524943, 33303388, 129072991, 77747149, 283867501, 11930379, | |||||
46641512, 137858340, 296682569, 153407889, 259515711, 126174146, 198346294, 235455425, 244023416, 291596132, 316297415, 328710625, 80224578, 302632627, 113667569, 119113057, | |||||
312017817, 2699680, 108004786, 196303853, 334319350, 133319693, 327422655, 215939730, 97293139, 277699946, 162171273, 77273435, 316008252, 75151514, 32680821, 13466291, | |||||
256206912, 225832678, 245296564, 166344225, 230519898, 18887784, 108194240, 155075127, 74650975, 300719094, 74020064, 119463325, 298456636, 144707310, 252315645, 2757974, | |||||
321969537, 318219488, 203728303, 199667954, 339569618, 236437494, 68257532, 41674788, 79292517, 329595997, 47860047, 74221291, 133851496, 131423110, 134739242, 41769882, | |||||
125397753, 37421241, 99154118, 77345313, 75415599, 184611253, 283821969, 217425962, 340138445, 205360342, 138790530, 231381162, 177646695, 341124928, 49006892, 115050903, | |||||
328700132, 145997181, 305008536, 270860151, 315446483, 311962310, 37732254, 31766142, 314384689, 124829645, 37478454, 2002208, 167278182, 247209778, 85372494, 278387860, | |||||
339536290, 114992793, 310585351, 246747223, 161880752, 309863480, 145995082, 67504260, 96405640, 53758185, 80364252, 59762590, 61870224, 328402109, 123460961, 185357220, | |||||
210531620, 301407876, 330043666, 282401604, 176867483, 115053574, 316685038, 20214140, 75349137, 19519076, 63151532, 199071277, 179016942, 13021588, 321789792, 163648942, | |||||
139380103, 114565842, 330217875, 271319530, 129239990, 186057800, 258827287, 178929042, 82102774, 257249581, 177238145, 62402069, 160259722, 233013151, 315534334, 342784710, | |||||
77458610, 253683167, 261286212, 281360242, 296191980, 6850988, 251030736, 74731345, 265318802, 63899879, 311681497, 137131395, 3931149, 181665422, 51898522, 245605974, | |||||
128427927, 95354166, 166281164, 2434663, 286713155, 113257227, 112789726, 90764238, 44867204, 26890740, 298664607, 181169292, 120444705, 62783316, 66162809, 133187974, | |||||
131085619, 39270565, 70166946, 277526912, 1756312, 205015274, 210307520, 223955976, 295679311, 73435047, 218777227, 248504688, 191268148, 10674541, 113695358, 291536722, | |||||
198196536, 266946574, 121223151, 286290221, 28846473, 189515583, 205436167, 220060181, 17816194, 219660836, 218831760, 122930261, 90002096, 123760813, 89192098, 30551277, | |||||
208285091, 230068868, 113052860, 204703894, 323875798, 99019268, 41579225, 194457264, 64487982, 289332899, 148207072, 195897417, 311865514, 340092471, 219256369, 154766, | |||||
299759898, 311347621, 323312829, 63589683, 246540525, 151049736, 2185297, 179420091, 34750962, 84555619, 100438483, 120169396, 157907051, 225257403, 293722399, 111850253, | |||||
323856168, 338303783, 314840798, 190938467, 125867606, 234764184, 327427414, 142613978, 215585704, 261751388, 316751420, 121346748, 193921698, 138975926, 44295661, 343113050, | |||||
10670086, 262534597, 58896306, 100875887, 105441063, 338677572, 273548204, 304358246, 247450114, 126898411, 281611873, 65770419, 88358931, 108711560, 169816947, 276047518, | |||||
179623980, 8948915, 211487568, 135978710, 122356782, 61305919, 25101795, 291689257, 141349641, 198259466, 256737405, 116654989, 45647754, 180293767, 142965291, 182641848, | |||||
320298964, 104661562, 159853264, 63559596, 77470611, 155263833, 24371986, 4502110, 307150630, 142825689, 191055334, 272420854, 266596798, 310116768, 100031582, 330934661, | |||||
131329963, 205128768, 34434682, 264548538, 275820126, 58374622, 126868524, 247696662, 230430459, 247383707, 213976148, 4429934, 55811418, 182713031, 135206428, 78131304, | |||||
73905525, 122191796, 303115339, 249426444, 196133691, 50737499, 39423175, 38943576, 63789271, 15653280, 42256835, 76792639, 18041511, 28927295, 167872394, 132917641, | |||||
221464907, 306272254, 168295914, 311947582, 115002830, 173548221, 66297447, 38518479, 186039235, 166985453, 170012531, 110913328, 2521858, 164656555, 78715300, 137921241, | |||||
31451200, 69592338, 244799209, 30327278, 311383754, 324910770, 31364455, 227268411, 250460720, 69982039, 258447968, 48751303, 166388835, 160611885, 321899686, 248083879, | |||||
91906147, 70295745, 73849988, 252478588, 34713870, 338042480, 280941331, 10639985, 58539003, 256112056, 301421958, 251057581, 265894571, 25563194, 195929163, 142869361, | |||||
47864316, 339243405, 278587677, 209058399, 28896907, 235462631, 259232595, 244958163, 23735989, 146207513, 291668902, 343175816, 205222309, 282750786, 266854086, 311189979, | |||||
107993050, 55645002, 248439323, 110947244, 127537928, 20029480, 91971569, 91066679, 187746866, 177178431, 199502889, 212043310, 196042207, 211835072, 122477545, 18413892, | |||||
161679160, 35056566, 338821353, 276789509, 206322097, 18473387, 327976767, 80429437, 279397388, 68518274, 181023243, 237284827, 313969190, 15263438, 51894343, 9591303, | |||||
82627166, 239331506, 239476843, 289562517, 139382347, 242285354, 17292740, 188689316, 235469942, 117131734, 266735631, 326823227, 117612662, 76546657, 295122385, 12037548, | |||||
189504538, 95200070, 293038692, 31932380, 187259607, 73167190, 170755308, 218145696, 236213106, 108592503, 131352161, 60559929, 42411067, 280958175, 8836049, 297422828, | |||||
11573249, 91280673, 125611361, 161380632, 226344941, 134250929, 140995006, 98690051, 155765188, 164335593, 80031253, 199481563, 69867929, 39419746, 228795671, 19516918, | |||||
167375209, 89867706, 72825851, 242099982, 14848946, 42273808, 126259092, 304755136, 38613146, 122800946, 267082476, 167972636, 196062071, 254115855, 39817651, 309122741, | |||||
60457156, 250755360, 20601023, 243392916, 292858762, 180399588, 313217138, 29929697, 60449086, 283841728, 160244444, 241071188, 321755521, 108569899, 143560290, 272375957, | |||||
331455083, 14981285, 32934047, 262884057, 281379762, 227479236, 105879398, 272619394, 284712017, 190200546, 171093156, 34108414, 325985663, 199935697, 224245523, 144111576, | |||||
153321671, 286621872, 35462788, 214206730, 126269934, 65652966, 284070510, 6662486, 325197743, 38006257, 50224836, 124340354, 154428934, 7450140, 287185643, 33705971, | |||||
141469584, 272829155, 286510306, 246444258, 170097677, 319718232, 330523682, 140140378, 10364444, 160580247, 27785987, 34570969, 134913023, 14901862, 115728895, 78609524, | |||||
201919710, 13838972, 34092541, 198733493, 47482665, 251494232, 16132931, 38972371, 240063876, 117596199, 162911865, 262860640, 52977050, 77007819, 254322574, 230917793, | |||||
56907315, 187536671, 158797937, 155087075, 285406963, 223869101, 209999057, 86990953, 177275895, 51531987, 75323133, 136095883, 79458852, 284976460, 336503820, 248522042, | |||||
242449238, 205641666, 53426246, 117730324, 10035786, 176235396, 119572778, 246212637, 259359873, 106810129, 68701183, 223062848, 116203489, 128109911, 250671079, 143144811, | |||||
122946724, 97778773, 14445551, 298865154, 220279089, 290608179, 139788422, 238668396, 208042792, 131609015, 171512662, 87566759, 307515865, 299411860, 322981913, 275319558, | |||||
215000538, 298680114, 174004783, 223088200, 81687275, 147683374, 191654034, 69991164, 17002068, 330618625, 9609529, 80888816, 152614860, 150884999, 256151599, 329060317, | |||||
211562488, 80002392, 53630089, 14783054, 243458064, 201989694, 173499211, 84231350, 173331941, 304685475, 186888301, 246560832, 235755640, 112845732, 306533221, 45346390, | |||||
159933829, 204549617, 65072539, 250813869, 230816883, 281589467, 307369918, 341418978, 323140252, 73855972, 83202333, 37507398, 171449539, 2278644, 159569463, 171528205, | |||||
}; |
@@ -0,0 +1,44 @@ | |||||
/************************************************************************************* | |||||
* qTESLA: an efficient post-quantum signature scheme based on the R-LWE problem | |||||
* | |||||
* Abstract: portable, constant-time Gaussian sampler | |||||
**************************************************************************************/ | |||||
#include "api.h" | |||||
#include "CDT32.h" | |||||
#include "gauss.h" | |||||
#include "sp800-185.h" | |||||
#include <string.h> | |||||
void PQCLEAN_QTESLAPI_CLEAN_sample_gauss_poly(poly z, const uint8_t *seed, uint16_t nonce) { | |||||
uint16_t dmsp = (uint16_t)(nonce << 8); | |||||
int32_t samp[CHUNK_SIZE * CDT_COLS], c[CDT_COLS], borrow, sign; | |||||
const int32_t mask = (int32_t)((uint32_t)(-1) >> 1); | |||||
uint8_t buf[CHUNK_SIZE * CDT_COLS * sizeof(int32_t)]; | |||||
for (size_t chunk = 0; chunk < PARAM_N; chunk += CHUNK_SIZE) { | |||||
uint8_t dmsp_bytes[2]; | |||||
dmsp_bytes[0] = (uint8_t)(dmsp & 0xff); | |||||
dmsp_bytes[1] = (uint8_t)(dmsp >> 8); | |||||
cSHAKE(buf, CHUNK_SIZE * CDT_COLS * sizeof(int32_t), (uint8_t *)NULL, 0, dmsp_bytes, 2, seed, CRYPTO_RANDOMBYTES); | |||||
++dmsp; | |||||
for (size_t i = 0, j = 0; i < CHUNK_SIZE * CDT_COLS; i += 1, j += 4) { | |||||
samp[i] = (int32_t)(buf[j] | (buf[j + 1] << 8) | (buf[j + 2] << 16) | (buf[j + 3] << 24)); | |||||
} | |||||
for (size_t i = 0; i < CHUNK_SIZE; i++) { | |||||
z[chunk + i] = 0; | |||||
for (size_t j = 1; j < CDT_ROWS; j++) { | |||||
borrow = 0; | |||||
for (size_t k = CDT_COLS; k > 0; ) { | |||||
k--; | |||||
c[k] = (samp[i * CDT_COLS + k] & mask) - (cdt_v[j * CDT_COLS + k] + borrow); | |||||
borrow = c[k] >> (RADIX32 - 1); | |||||
} | |||||
z[chunk + i] += ~borrow & 1; | |||||
} | |||||
sign = samp[i * CDT_COLS] >> (RADIX32 - 1); | |||||
z[chunk + i] = (sign & -z[chunk + i]) | (~sign & z[chunk + i]); | |||||
} | |||||
} | |||||
} | |||||
@@ -0,0 +1,13 @@ | |||||
#ifndef PQCLEAN_QTESLAPI_CLEAN_GAUSS_H | |||||
#define PQCLEAN_QTESLAPI_CLEAN_GAUSS_H | |||||
#include "config.h" | |||||
#include "params.h" | |||||
#include "poly.h" | |||||
#include <stdint.h> | |||||
#define CHUNK_SIZE 512 // Fix chunk size for sampling | |||||
void PQCLEAN_QTESLAPI_CLEAN_sample_gauss_poly(poly z, const uint8_t *seed, uint16_t nonce); | |||||
#endif |
@@ -0,0 +1,118 @@ | |||||
/************************************************************************************* | |||||
* qTESLA: an efficient post-quantum signature scheme based on the R-LWE problem | |||||
* | |||||
* Abstract: packing functions | |||||
**************************************************************************************/ | |||||
#include "api.h" | |||||
#include "pack.h" | |||||
#include "params.h" | |||||
#include "poly.h" | |||||
#include <string.h> | |||||
void PQCLEAN_QTESLAPI_CLEAN_pack_sk(uint8_t *sk, const poly s, const poly_k e, uint8_t *seeds) { | |||||
// Pack secret key sk | |||||
size_t i, k; | |||||
for (i = 0; i < PARAM_N; i++) { | |||||
sk[i] = (uint8_t)s[i]; | |||||
} | |||||
sk += PARAM_N; | |||||
for (k = 0; k < PARAM_K; k++) { | |||||
for (i = 0; i < PARAM_N; i++) { | |||||
sk[k * PARAM_N + i] = (uint8_t)e[k * PARAM_N + i]; | |||||
} | |||||
} | |||||
memcpy(&sk[PARAM_K * PARAM_N], seeds, 2 * CRYPTO_SEEDBYTES); | |||||
} | |||||
void PQCLEAN_QTESLAPI_CLEAN_encode_pk(uint8_t *pk, const poly_k t, const uint8_t *seedA) { | |||||
// Encode public key pk | |||||
size_t i, j; | |||||
for (i = 0, j = 0; i < PARAM_N * PARAM_K; i += 8, j += 29) { | |||||
pk[j ] = (uint8_t)( t[i ] ); | |||||
pk[j + 1] = (uint8_t)( t[i ] >> 8); | |||||
pk[j + 2] = (uint8_t)( t[i ] >> 16); | |||||
pk[j + 3] = (uint8_t)((t[i ] >> 24) | (t[i + 1] << 5)); | |||||
pk[j + 4] = (uint8_t)( t[i + 1] >> 3); | |||||
pk[j + 5] = (uint8_t)( t[i + 1] >> 11); | |||||
pk[j + 6] = (uint8_t)( t[i + 1] >> 19); | |||||
pk[j + 7] = (uint8_t)((t[i + 1] >> 27) | (t[i + 2] << 2)); | |||||
pk[j + 8] = (uint8_t)( t[i + 2] >> 6); | |||||
pk[j + 9] = (uint8_t)( t[i + 2] >> 14); | |||||
pk[j + 10] = (uint8_t)((t[i + 2] >> 22) | (t[i + 3] << 7)); | |||||
pk[j + 11] = (uint8_t)( t[i + 3] >> 1); | |||||
pk[j + 12] = (uint8_t)( t[i + 3] >> 9); | |||||
pk[j + 13] = (uint8_t)( t[i + 3] >> 17); | |||||
pk[j + 14] = (uint8_t)((t[i + 3] >> 25) | (t[i + 4] << 4)); | |||||
pk[j + 15] = (uint8_t)( t[i + 4] >> 4); | |||||
pk[j + 16] = (uint8_t)( t[i + 4] >> 12); | |||||
pk[j + 17] = (uint8_t)( t[i + 4] >> 20); | |||||
pk[j + 18] = (uint8_t)((t[i + 4] >> 28) | (t[i + 5] << 1)); | |||||
pk[j + 19] = (uint8_t)( t[i + 5] >> 7); | |||||
pk[j + 20] = (uint8_t)( t[i + 5] >> 15); | |||||
pk[j + 21] = (uint8_t)((t[i + 5] >> 23) | (t[i + 6] << 6)); | |||||
pk[j + 22] = (uint8_t)( t[i + 6] >> 2); | |||||
pk[j + 23] = (uint8_t)( t[i + 6] >> 10); | |||||
pk[j + 24] = (uint8_t)( t[i + 6] >> 18); | |||||
pk[j + 25] = (uint8_t)((t[i + 6] >> 26) | (t[i + 7] << 3)); | |||||
pk[j + 26] = (uint8_t)( t[i + 7] >> 5); | |||||
pk[j + 27] = (uint8_t)( t[i + 7] >> 13); | |||||
pk[j + 28] = (uint8_t)( t[i + 7] >> 21); | |||||
} | |||||
memcpy(&pk[j], seedA, CRYPTO_SEEDBYTES); | |||||
} | |||||
void PQCLEAN_QTESLAPI_CLEAN_decode_pk(int32_t *pk, uint8_t *seedA, const uint8_t *pk_in) { | |||||
// Decode public key pk | |||||
size_t i, j; | |||||
int32_t mask29 = (1 << PARAM_Q_LOG) - 1; | |||||
const uint8_t *a = pk_in; | |||||
for (i = 0, j = 0; i < PARAM_N * PARAM_K; i += 8, j += 29) { | |||||
pk[i ] = (int32_t)(( a[j ] | (a[j + 1] << 8) | (a[j + 2] << 16) | (a[j + 3] << 24) ) & mask29); | |||||
pk[i + 1] = (int32_t)(((a[j + 3] >> 5) | (a[j + 4] << 3) | (a[j + 5] << 11) | (a[j + 6] << 19) | (a[j + 7] << 27)) & mask29); | |||||
pk[i + 2] = (int32_t)(((a[j + 7] >> 2) | (a[j + 8] << 6) | (a[j + 9] << 14) | (a[j + 10] << 22) ) & mask29); | |||||
pk[i + 3] = (int32_t)(((a[j + 10] >> 7) | (a[j + 11] << 1) | (a[j + 12] << 9) | (a[j + 13] << 17) | (a[j + 14] << 25)) & mask29); | |||||
pk[i + 4] = (int32_t)(((a[j + 14] >> 4) | (a[j + 15] << 4) | (a[j + 16] << 12) | (a[j + 17] << 20) | (a[j + 18] << 28)) & mask29); | |||||
pk[i + 5] = (int32_t)(((a[j + 18] >> 1) | (a[j + 19] << 7) | (a[j + 20] << 15) | (a[j + 21] << 23) ) & mask29); | |||||
pk[i + 6] = (int32_t)(((a[j + 21] >> 6) | (a[j + 22] << 2) | (a[j + 23] << 10) | (a[j + 24] << 18) | (a[j + 25] << 26)) & mask29); | |||||
pk[i + 7] = (int32_t)( (a[j + 25] >> 3) | (a[j + 26] << 5) | (a[j + 27] << 13) | (a[j + 28] << 21) ); | |||||
} | |||||
memcpy(seedA, &pk_in[j], CRYPTO_SEEDBYTES); | |||||
} | |||||
void PQCLEAN_QTESLAPI_CLEAN_encode_sig(uint8_t *sm, uint8_t *c, const poly z) { | |||||
// Encode signature sm | |||||
size_t i, j; | |||||
for (i = 0, j = 0; i < PARAM_N; i += 2, j += 5) { | |||||
sm[j ] = (uint8_t)( z[i ] ); | |||||
sm[j + 1] = (uint8_t)( z[i ] >> 8); | |||||
sm[j + 2] = (uint8_t)(((z[i ] >> 16) & 0x0F) | (z[i + 1] << 4)); | |||||
sm[j + 3] = (uint8_t)( z[i + 1] >> 4); | |||||
sm[j + 4] = (uint8_t)( z[i + 1] >> 12); | |||||
} | |||||
memcpy(&sm[j], c, CRYPTO_C_BYTES); | |||||
} | |||||
void PQCLEAN_QTESLAPI_CLEAN_decode_sig(uint8_t *c, poly z, const uint8_t *sm) { | |||||
// Decode signature sm | |||||
size_t i, j; | |||||
for (i = 0, j = 0; i < PARAM_N; i += 2, j += 5) { | |||||
z[i ] = sm[j ] | (sm[j + 1] << 8) | (((int64_t)sm[j + 2] << 60) >> 44); | |||||
z[i + 1] = (sm[j + 2] >> 4) | (sm[j + 3] << 4) | (((int64_t)sm[j + 4] << 56) >> 44); | |||||
} | |||||
memcpy(c, &sm[j], CRYPTO_C_BYTES); | |||||
} | |||||
@@ -0,0 +1,13 @@ | |||||
#ifndef PQCLEAN_QTESLAPI_CLEAN_PACK_H | |||||
#define PQCLEAN_QTESLAPI_CLEAN_PACK_H | |||||
#include "poly.h" | |||||
#include <stdint.h> | |||||
void PQCLEAN_QTESLAPI_CLEAN_pack_sk(uint8_t *sk, const poly s, const poly_k e, uint8_t *seeds); | |||||
void PQCLEAN_QTESLAPI_CLEAN_encode_pk(uint8_t *pk, const poly_k t, const uint8_t *seedA); | |||||
void PQCLEAN_QTESLAPI_CLEAN_decode_pk(int32_t *pk, uint8_t *seedA, const uint8_t *pk_in); | |||||
void PQCLEAN_QTESLAPI_CLEAN_encode_sig(uint8_t *sm, uint8_t *c, const poly z); | |||||
void PQCLEAN_QTESLAPI_CLEAN_decode_sig(uint8_t *c, poly z, const uint8_t *sm); | |||||
#endif |
@@ -0,0 +1,42 @@ | |||||
#ifndef PQCLEAN_QTESLAPI_CLEAN_PARAMS_H | |||||
#define PQCLEAN_QTESLAPI_CLEAN_PARAMS_H | |||||
/************************************************************************************* | |||||
* qTESLA: an efficient post-quantum signature scheme based on the R-LWE problem | |||||
* | |||||
* Abstract: provably-secure qTESLA parameters | |||||
**************************************************************************************/ | |||||
#define PARAM_N 1024 | |||||
#define PARAM_N_LOG 10 | |||||
#define PARAM_SIGMA 8.5 | |||||
#define PARAM_Q 343576577 | |||||
#define PARAM_Q_LOG 29 | |||||
#define PARAM_QINV 2205847551 | |||||
#define PARAM_BARR_MULT 3 | |||||
#define PARAM_BARR_DIV 30 | |||||
#define PARAM_B 524287 | |||||
#define PARAM_B_BITS 19 | |||||
#define PARAM_S_BITS 8 | |||||
#define PARAM_K 4 | |||||
#define PARAM_SIGMA_E PARAM_SIGMA | |||||
#define PARAM_H 25 | |||||
#define PARAM_D 22 | |||||
#define PARAM_GEN_A 108 | |||||
#define PARAM_KEYGEN_BOUND_E 554 | |||||
#define PARAM_E PARAM_KEYGEN_BOUND_E | |||||
#define PARAM_KEYGEN_BOUND_S 554 | |||||
#define PARAM_S PARAM_KEYGEN_BOUND_S | |||||
#define PARAM_R2_INVN 13632409 | |||||
#define PARAM_R 172048372 | |||||
#define SHAKE shake128 | |||||
#define cSHAKE cshake128 | |||||
#define SHAKE_RATE SHAKE128_RATE | |||||
#define CRYPTO_RANDOMBYTES 32 | |||||
#define CRYPTO_SEEDBYTES 32 | |||||
#define CRYPTO_C_BYTES 32 | |||||
#define HM_BYTES 64 | |||||
#endif |
@@ -0,0 +1,255 @@ | |||||
/************************************************************************************* | |||||
* qTESLA: an efficient post-quantum signature scheme based on the R-LWE problem | |||||
* | |||||
* Abstract: NTT, modular reduction and polynomial functions | |||||
**************************************************************************************/ | |||||
#include "api.h" | |||||
#include "poly.h" | |||||
#include "sp800-185.h" | |||||
extern const poly PQCLEAN_QTESLAPI_CLEAN_zeta; | |||||
extern const poly PQCLEAN_QTESLAPI_CLEAN_zetainv; | |||||
static int64_t reduce(int64_t a) { | |||||
// Montgomery reduction | |||||
int64_t u; | |||||
u = ((uint64_t)a * PARAM_QINV) & 0xFFFFFFFF; | |||||
u *= PARAM_Q; | |||||
a += u; | |||||
return a >> 32; | |||||
} | |||||
static int64_t barr_reduce(int64_t a) { | |||||
// Barrett reduction | |||||
int64_t u = (a * PARAM_BARR_MULT) >> PARAM_BARR_DIV; | |||||
return a - u * PARAM_Q; | |||||
} | |||||
static void ntt(poly a, const poly w) { | |||||
// Forward NTT transform | |||||
size_t NumoProblems = PARAM_N >> 1, jTwiddle = 0; | |||||
for (; NumoProblems > 0; NumoProblems >>= 1) { | |||||
size_t jFirst, j = 0; | |||||
for (jFirst = 0; jFirst < PARAM_N; jFirst = j + NumoProblems) { | |||||
sdigit_t W = (sdigit_t)w[jTwiddle++]; | |||||
for (j = jFirst; j < jFirst + NumoProblems; j++) { | |||||
int64_t temp = reduce((int64_t)W * a[j + NumoProblems]); | |||||
a[j + NumoProblems] = a[j] + (PARAM_Q - temp); | |||||
a[j] = temp + a[j]; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
static void nttinv(poly a, const poly w) { | |||||
// Inverse NTT transform | |||||
size_t NumoProblems = 1, jTwiddle = 0; | |||||
for (; NumoProblems < PARAM_N; NumoProblems *= 2) { | |||||
size_t jFirst, j = 0; | |||||
for (jFirst = 0; jFirst < PARAM_N; jFirst = j + NumoProblems) { | |||||
sdigit_t W = (sdigit_t)w[jTwiddle++]; | |||||
for (j = jFirst; j < jFirst + NumoProblems; j++) { | |||||
int64_t temp = a[j]; | |||||
a[j] = (temp + a[j + NumoProblems]); | |||||
a[j + NumoProblems] = reduce((int64_t)W * (temp + (2 * PARAM_Q - a[j + NumoProblems]))); | |||||
} | |||||
} | |||||
NumoProblems *= 2; | |||||
for (jFirst = 0; jFirst < PARAM_N; jFirst = j + NumoProblems) { | |||||
sdigit_t W = (sdigit_t)w[jTwiddle++]; | |||||
for (j = jFirst; j < jFirst + NumoProblems; j++) { | |||||
int64_t temp = a[j]; | |||||
a[j] = barr_reduce(temp + a[j + NumoProblems]); | |||||
a[j + NumoProblems] = reduce((int64_t)W * (temp + (2 * PARAM_Q - a[j + NumoProblems]))); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
static void poly_pointwise(poly result, const poly x, const poly y) { | |||||
// Pointwise polynomial multiplication result = x.y | |||||
for (size_t i = 0; i < PARAM_N; i++) { | |||||
result[i] = reduce(x[i] * y[i]); | |||||
} | |||||
} | |||||
void PQCLEAN_QTESLAPI_CLEAN_poly_ntt(poly x_ntt, const poly x) { | |||||
// Call to NTT function. Avoids input destruction | |||||
for (size_t i = 0; i < PARAM_N; i++) { | |||||
x_ntt[i] = x[i]; | |||||
} | |||||
ntt(x_ntt, PQCLEAN_QTESLAPI_CLEAN_zeta); | |||||
} | |||||
void PQCLEAN_QTESLAPI_CLEAN_poly_mul(poly result, const poly x, const poly y) { | |||||
// Polynomial multiplication result = x*y, with in place reduction for (X^N+1) | |||||
// The inputs x and y are assumed to be in NTT form | |||||
poly_pointwise(result, x, y); | |||||
nttinv(result, PQCLEAN_QTESLAPI_CLEAN_zetainv); | |||||
} | |||||
void PQCLEAN_QTESLAPI_CLEAN_poly_add(poly result, const poly x, const poly y) { | |||||
// Polynomial addition result = x+y | |||||
for (size_t i = 0; i < PARAM_N; i++) { | |||||
result[i] = x[i] + y[i]; | |||||
} | |||||
} | |||||
void PQCLEAN_QTESLAPI_CLEAN_poly_add_correct(poly result, const poly x, const poly y) { | |||||
// Polynomial addition result = x+y with correction | |||||
for (size_t i = 0; i < PARAM_N; i++) { | |||||
result[i] = x[i] + y[i]; | |||||
result[i] -= PARAM_Q; | |||||
result[i] += (result[i] >> (RADIX32 - 1)) & PARAM_Q; // If result[i] >= q then subtract q | |||||
} | |||||
} | |||||
void PQCLEAN_QTESLAPI_CLEAN_poly_sub(poly result, const poly x, const poly y) { | |||||
// Polynomial subtraction result = x-y | |||||
for (size_t i = 0; i < PARAM_N; i++) { | |||||
result[i] = barr_reduce(x[i] - y[i]); | |||||
} | |||||
} | |||||
/******************************************************************************************** | |||||
* Name: sparse_mul8 | |||||
* Description: performs sparse polynomial multiplication | |||||
* Parameters: inputs: | |||||
* - const uint8_t *s: part of the secret key | |||||
* - const uint32_t pos_list[PARAM_H]: list of indices of nonzero elements in c | |||||
* - const int16_t sign_list[PARAM_H]: list of signs of nonzero elements in c | |||||
* outputs: | |||||
* - poly prod: product of 2 polynomials | |||||
* | |||||
* Note: pos_list[] and sign_list[] contain public information since c is public | |||||
*********************************************************************************************/ | |||||
void PQCLEAN_QTESLAPI_CLEAN_sparse_mul8(poly prod, const uint8_t *s, const uint32_t pos_list[PARAM_H], const int16_t sign_list[PARAM_H]) { | |||||
size_t i, j, pos; | |||||
int8_t *t = (int8_t *)s; | |||||
for (i = 0; i < PARAM_N; i++) { | |||||
prod[i] = 0; | |||||
} | |||||
for (i = 0; i < PARAM_H; i++) { | |||||
pos = pos_list[i]; | |||||
for (j = 0; j < pos; j++) { | |||||
prod[j] = prod[j] - sign_list[i] * t[j + PARAM_N - pos]; | |||||
} | |||||
for (j = pos; j < PARAM_N; j++) { | |||||
prod[j] = prod[j] + sign_list[i] * t[j - pos]; | |||||
} | |||||
} | |||||
} | |||||
/******************************************************************************************** | |||||
* Name: sparse_mul32 | |||||
* Description: performs sparse polynomial multiplication | |||||
* Parameters: inputs: | |||||
* - const int32_t* pk: part of the public key | |||||
* - const uint32_t pos_list[PARAM_H]: list of indices of nonzero elements in c | |||||
* - const int16_t sign_list[PARAM_H]: list of signs of nonzero elements in c | |||||
* outputs: | |||||
* - poly prod: product of 2 polynomials | |||||
*********************************************************************************************/ | |||||
void PQCLEAN_QTESLAPI_CLEAN_sparse_mul32(poly prod, const int32_t *pk, const uint32_t pos_list[PARAM_H], const int16_t sign_list[PARAM_H]) { | |||||
size_t i, j, pos; | |||||
for (i = 0; i < PARAM_N; i++) { | |||||
prod[i] = 0; | |||||
} | |||||
for (i = 0; i < PARAM_H; i++) { | |||||
pos = pos_list[i]; | |||||
for (j = 0; j < pos; j++) { | |||||
prod[j] = prod[j] - sign_list[i] * pk[j + PARAM_N - pos]; | |||||
} | |||||
for (j = pos; j < PARAM_N; j++) { | |||||
prod[j] = prod[j] + sign_list[i] * pk[j - pos]; | |||||
} | |||||
} | |||||
for (i = 0; i < PARAM_N; i++) { | |||||
prod[i] = barr_reduce(prod[i]); | |||||
} | |||||
} | |||||
void PQCLEAN_QTESLAPI_CLEAN_poly_uniform(poly_k a, const uint8_t *seed) { | |||||
// Generation of polynomials "a_i" | |||||
size_t pos = 0, i = 0, nbytes = (PARAM_Q_LOG + 7) / 8; | |||||
size_t nblocks = PARAM_GEN_A; | |||||
uint32_t val1, val2, val3, val4, mask = (uint32_t)(1 << PARAM_Q_LOG) - 1; | |||||
uint8_t buf[SHAKE128_RATE * PARAM_GEN_A]; | |||||
uint16_t dmsp = 0; | |||||
uint8_t dmsp_bytes[2]; | |||||
dmsp_bytes[0] = (uint8_t)(dmsp & 0xff); | |||||
dmsp_bytes[1] = (uint8_t)(dmsp >> 8); | |||||
cshake128(buf, SHAKE128_RATE * PARAM_GEN_A, (uint8_t *)NULL, 0, dmsp_bytes, 2, seed, CRYPTO_RANDOMBYTES); | |||||
++dmsp; | |||||
while (i < PARAM_K * PARAM_N) { | |||||
if (pos > SHAKE128_RATE * nblocks - 4 * nbytes) { | |||||
nblocks = 1; | |||||
dmsp_bytes[0] = (uint8_t)(dmsp & 0xff); | |||||
dmsp_bytes[1] = (uint8_t)(dmsp >> 8); | |||||
cshake128(buf, SHAKE128_RATE * nblocks, (uint8_t *)NULL, 0, dmsp_bytes, 2, seed, CRYPTO_RANDOMBYTES); | |||||
++dmsp; | |||||
pos = 0; | |||||
} | |||||
val1 = ((uint32_t)(buf[pos]) | |||||
| (uint32_t)(buf[pos + 1] << 8) | |||||
| (uint32_t)(buf[pos + 2] << 16) | |||||
| (uint32_t)(buf[pos + 3] << 24)) | |||||
& mask; | |||||
pos += nbytes; | |||||
val2 = ((uint32_t)(buf[pos]) | |||||
| (uint32_t)(buf[pos + 1] << 8) | |||||
| (uint32_t)(buf[pos + 2] << 16) | |||||
| (uint32_t)(buf[pos + 3] << 24)) | |||||
& mask; | |||||
pos += nbytes; | |||||
val3 = ((uint32_t)(buf[pos]) | |||||
| (uint32_t)(buf[pos + 1] << 8) | |||||
| (uint32_t)(buf[pos + 2] << 16) | |||||
| (uint32_t)(buf[pos + 3] << 24)) | |||||
& mask; | |||||
pos += nbytes; | |||||
val4 = ((uint32_t)(buf[pos]) | |||||
| (uint32_t)(buf[pos + 1] << 8) | |||||
| (uint32_t)(buf[pos + 2] << 16) | |||||
| (uint32_t)(buf[pos + 3] << 24)) | |||||
& mask; | |||||
pos += nbytes; | |||||
if (val1 < PARAM_Q && i < PARAM_K * PARAM_N) { | |||||
a[i++] = reduce((int64_t)val1 * PARAM_R2_INVN); | |||||
} | |||||
if (val2 < PARAM_Q && i < PARAM_K * PARAM_N) { | |||||
a[i++] = reduce((int64_t)val2 * PARAM_R2_INVN); | |||||
} | |||||
if (val3 < PARAM_Q && i < PARAM_K * PARAM_N) { | |||||
a[i++] = reduce((int64_t)val3 * PARAM_R2_INVN); | |||||
} | |||||
if (val4 < PARAM_Q && i < PARAM_K * PARAM_N) { | |||||
a[i++] = reduce((int64_t)val4 * PARAM_R2_INVN); | |||||
} | |||||
} | |||||
} | |||||
@@ -0,0 +1,20 @@ | |||||
#ifndef PQCLEAN_QTESLAPI_CLEAN_POLY_H | |||||
#define PQCLEAN_QTESLAPI_CLEAN_POLY_H | |||||
#include "config.h" | |||||
#include "params.h" | |||||
#include <stdint.h> | |||||
typedef int64_t poly[PARAM_N]; | |||||
typedef int64_t poly_k[PARAM_N * PARAM_K]; | |||||
void PQCLEAN_QTESLAPI_CLEAN_poly_ntt(poly x_ntt, const poly x); | |||||
void PQCLEAN_QTESLAPI_CLEAN_poly_mul(poly result, const poly x, const poly y); | |||||
void PQCLEAN_QTESLAPI_CLEAN_poly_add(poly result, const poly x, const poly y); | |||||
void PQCLEAN_QTESLAPI_CLEAN_poly_add_correct(poly result, const poly x, const poly y); | |||||
void PQCLEAN_QTESLAPI_CLEAN_poly_sub(poly result, const poly x, const poly y); | |||||
void PQCLEAN_QTESLAPI_CLEAN_sparse_mul8(poly prod, const uint8_t *s, const uint32_t pos_list[PARAM_H], const int16_t sign_list[PARAM_H]); | |||||
void PQCLEAN_QTESLAPI_CLEAN_sparse_mul32(poly prod, const int32_t *pk, const uint32_t pos_list[PARAM_H], const int16_t sign_list[PARAM_H]); | |||||
void PQCLEAN_QTESLAPI_CLEAN_poly_uniform(poly_k a, const uint8_t *seed); | |||||
#endif |
@@ -0,0 +1,89 @@ | |||||
/************************************************************************************* | |||||
* qTESLA: an efficient post-quantum signature scheme based on the R-LWE problem | |||||
* | |||||
* Abstract: sampling functions | |||||
**************************************************************************************/ | |||||
#include "api.h" | |||||
#include "params.h" | |||||
#include "sample.h" | |||||
#include "sp800-185.h" | |||||
#define NBLOCKS_SHAKE (SHAKE_RATE/(((PARAM_B_BITS+1)+7)/8)) | |||||
#define BPLUS1BYTES (((PARAM_B_BITS+1)+7)/8) | |||||
void PQCLEAN_QTESLAPI_CLEAN_sample_y(poly y, const uint8_t *seed, uint16_t nonce) { | |||||
// Sample polynomial y, such that each coefficient is in the range [-B,B] | |||||
size_t i = 0, pos = 0, nblocks = PARAM_N; | |||||
uint8_t buf[PARAM_N * BPLUS1BYTES + 1]; | |||||
uint16_t dmsp = (uint16_t)(nonce << 8); | |||||
uint8_t dmsp_bytes[2]; | |||||
dmsp_bytes[0] = (uint8_t)(dmsp & 0xff); | |||||
dmsp_bytes[1] = (uint8_t)(dmsp >> 8); | |||||
cSHAKE(buf, PARAM_N * BPLUS1BYTES, (uint8_t *)NULL, 0, dmsp_bytes, 2, seed, CRYPTO_RANDOMBYTES); | |||||
++dmsp; | |||||
while (i < PARAM_N) { | |||||
if (pos >= nblocks * BPLUS1BYTES) { | |||||
nblocks = NBLOCKS_SHAKE; | |||||
dmsp_bytes[0] = (uint8_t)(dmsp & 0xff); | |||||
dmsp_bytes[1] = (uint8_t)(dmsp >> 8); | |||||
cSHAKE(buf, SHAKE_RATE, (uint8_t *)NULL, 0, dmsp_bytes, 2, seed, CRYPTO_RANDOMBYTES); | |||||
++dmsp; | |||||
pos = 0; | |||||
} | |||||
y[i] = (uint32_t)((buf[pos] | (buf[pos + 1] << 8) | (buf[pos + 2] << 16)) & ((1 << (PARAM_B_BITS + 1)) - 1)); | |||||
y[i] -= PARAM_B; | |||||
if (y[i] != (1 << PARAM_B_BITS)) { | |||||
i++; | |||||
} | |||||
pos += BPLUS1BYTES; | |||||
} | |||||
} | |||||
void PQCLEAN_QTESLAPI_CLEAN_encode_c(uint32_t *pos_list, int16_t *sign_list, uint8_t *c_bin) { | |||||
// Encoding of c' by mapping the output of the hash function H to an N-element vector with entries {-1,0,1} | |||||
size_t i, pos, cnt = 0; | |||||
int16_t c[PARAM_N]; | |||||
uint8_t r[SHAKE128_RATE]; | |||||
uint16_t dmsp = 0; | |||||
uint8_t dmsp_bytes[2]; | |||||
// Use the hash value as key to generate some randomness | |||||
dmsp_bytes[0] = (uint8_t)(dmsp & 0xff); | |||||
dmsp_bytes[1] = (uint8_t)(dmsp >> 8); | |||||
cshake128(r, SHAKE128_RATE, (uint8_t *)NULL, 0, dmsp_bytes, 2, c_bin, CRYPTO_RANDOMBYTES); | |||||
++dmsp; | |||||
// Use rejection sampling to determine positions to be set in the new vector | |||||
for (i = 0; i < PARAM_N; i++) { | |||||
c[i] = 0; | |||||
} | |||||
for (i = 0; i < PARAM_H;) { // Sample a unique position k times. Use two bytes | |||||
if (cnt > (SHAKE128_RATE - 3)) { | |||||
dmsp_bytes[0] = (uint8_t)(dmsp & 0xff); | |||||
dmsp_bytes[1] = (uint8_t)(dmsp >> 8); | |||||
cshake128(r, SHAKE128_RATE, (uint8_t *)NULL, 0, dmsp_bytes, 2, c_bin, CRYPTO_RANDOMBYTES); | |||||
++dmsp; | |||||
cnt = 0; | |||||
} | |||||
pos = (size_t)((r[cnt] << 8) | (r[cnt + 1])); | |||||
pos = pos & (PARAM_N - 1); // Position is in the range [0,N-1] | |||||
if (c[pos] == 0) { // Position has not been set yet. Determine sign | |||||
if ((r[cnt + 2] & 1) == 1) { | |||||
c[pos] = -1; | |||||
} else { | |||||
c[pos] = 1; | |||||
} | |||||
pos_list[i] = (uint32_t)pos; | |||||
sign_list[i] = c[pos]; | |||||
i++; | |||||
} | |||||
cnt += 3; | |||||
} | |||||
} |
@@ -0,0 +1,11 @@ | |||||
#ifndef PQCLEAN_QTESLAPI_CLEAN_SAMPLE_H | |||||
#define PQCLEAN_QTESLAPI_CLEAN_SAMPLE_H | |||||
#include "params.h" | |||||
#include "poly.h" | |||||
#include <stdint.h> | |||||
void PQCLEAN_QTESLAPI_CLEAN_sample_y(poly y, const uint8_t *seed, uint16_t nonce); | |||||
void PQCLEAN_QTESLAPI_CLEAN_encode_c(uint32_t *pos_list, int16_t *sign_list, uint8_t *c_bin); | |||||
#endif |
@@ -0,0 +1,403 @@ | |||||
/************************************************************************************* | |||||
* qTESLA: an efficient post-quantum signature scheme based on the R-LWE problem | |||||
* | |||||
* Abstract: high-level functions of the signature scheme | |||||
**************************************************************************************/ | |||||
#include "api.h" | |||||
#include "fips202.h" | |||||
#include "gauss.h" | |||||
#include "pack.h" | |||||
#include "params.h" | |||||
#include "poly.h" | |||||
#include "randombytes.h" | |||||
#include "sample.h" | |||||
#include <stdlib.h> | |||||
#include <string.h> | |||||
static void hash_H(uint8_t *c_bin, const poly_k v, const uint8_t *hm) { | |||||
// Hash-based function H to generate c' | |||||
uint8_t t[PARAM_K * PARAM_N + HM_BYTES]; | |||||
int32_t mask, cL, temp; | |||||
size_t i, k, index; | |||||
for (k = 0; k < PARAM_K; k++) { | |||||
index = k * PARAM_N; | |||||
for (i = 0; i < PARAM_N; i++) { | |||||
temp = (int32_t)v[index]; | |||||
// If v[i] > PARAM_Q/2 then v[i] -= PARAM_Q | |||||
mask = (PARAM_Q / 2 - temp) >> (RADIX32 - 1); | |||||
temp = ((temp - PARAM_Q) & mask) | (temp & ~mask); | |||||
cL = temp & ((1 << PARAM_D) - 1); | |||||
// If cL > 2^(d-1) then cL -= 2^d | |||||
mask = ((1 << (PARAM_D - 1)) - cL) >> (RADIX32 - 1); | |||||
cL = ((cL - (1 << PARAM_D)) & mask) | (cL & ~mask); | |||||
t[index++] = (uint8_t)((temp - cL) >> PARAM_D); | |||||
} | |||||
} | |||||
memcpy(&t[PARAM_K * PARAM_N], hm, HM_BYTES); | |||||
SHAKE(c_bin, CRYPTO_C_BYTES, t, PARAM_K * PARAM_N + HM_BYTES); | |||||
} | |||||
static inline int32_t Abs(int32_t value) { | |||||
// Compute absolute value | |||||
int32_t mask = value >> (RADIX32 - 1); | |||||
return (mask ^ value) - mask; | |||||
} | |||||
static int test_rejection(const poly z) { | |||||
// Check bounds for signature vector z during signing. Returns 0 if valid, otherwise outputs 1 if invalid (rejected). | |||||
// This function does not leak any information about the coefficient that fails the test. | |||||
uint32_t valid = 0; | |||||
for (size_t i = 0; i < PARAM_N; i++) { | |||||
valid |= (PARAM_B - PARAM_S) - (uint32_t)Abs((int32_t)z[i]); | |||||
} | |||||
return (int)(valid >> 31); | |||||
} | |||||
static int test_correctness(const poly v) { | |||||
// Check bounds for w = v - ec during signature verification. Returns 0 if valid, otherwise outputs 1 if invalid (rejected). | |||||
// This function leaks the position of the coefficient that fails the test (but this is independent of the secret data). | |||||
// It does not leak the sign of the coefficients. | |||||
int32_t mask, left, val; | |||||
uint32_t t0, t1; | |||||
for (size_t i = 0; i < PARAM_N; i++) { | |||||
// If v[i] > PARAM_Q/2 then v[i] -= PARAM_Q | |||||
mask = (int32_t)(PARAM_Q / 2 - v[i]) >> (RADIX32 - 1); | |||||
val = (int32_t)(((v[i] - PARAM_Q) & mask) | (v[i] & ~mask)); | |||||
// If (Abs(val) < PARAM_Q/2 - PARAM_E) then t0 = 0, else t0 = 1 | |||||
t0 = (uint32_t)(~(Abs(val) - (PARAM_Q / 2 - PARAM_E))) >> (RADIX32 - 1); | |||||
left = val; | |||||
val = (val + (1 << (PARAM_D - 1)) - 1) >> PARAM_D; | |||||
val = left - (val << PARAM_D); | |||||
// If (Abs(val) < (1<<(PARAM_D-1))-PARAM_E) then t1 = 0, else t1 = 1 | |||||
t1 = (uint32_t)(~(Abs(val) - ((1 << (PARAM_D - 1)) - PARAM_E))) >> (RADIX32 - 1); | |||||
if ((t0 | t1) == 1) { // Returns 1 if any of the two tests failed | |||||
return 1; | |||||
} | |||||
} | |||||
return 0; | |||||
} | |||||
static int test_z(const poly z) { | |||||
// Check bounds for signature vector z during signature verification | |||||
// Returns 0 if valid, otherwise outputs 1 if invalid (rejected) | |||||
for (size_t i = 0; i < PARAM_N; i++) { | |||||
if (z[i] < -(PARAM_B - PARAM_S) || z[i] > (PARAM_B - PARAM_S)) { | |||||
return 1; | |||||
} | |||||
} | |||||
return 0; | |||||
} | |||||
static int check_ES(poly p, unsigned int bound) { | |||||
// Checks the generated polynomial e or s | |||||
// Returns 0 if ok, otherwise returns 1 | |||||
unsigned int sum = 0; | |||||
size_t i, j, limit = PARAM_N; | |||||
int32_t temp, mask, list[PARAM_N]; | |||||
for (j = 0; j < PARAM_N; j++) { | |||||
list[j] = Abs((int32_t)p[j]); | |||||
} | |||||
for (j = 0; j < PARAM_H; j++) { | |||||
for (i = 0; i < limit - 1; i++) { | |||||
// If list[i+1] > list[i] then exchange contents | |||||
mask = (list[i + 1] - list[i]) >> (RADIX32 - 1); | |||||
temp = (list[i + 1] & mask) | (list[i] & ~mask); | |||||
list[i + 1] = (list[i] & mask) | (list[i + 1] & ~mask); | |||||
list[i] = temp; | |||||
} | |||||
sum += (unsigned int)list[limit - 1]; | |||||
limit -= 1; | |||||
} | |||||
if (sum > bound) { | |||||
return 1; | |||||
} | |||||
return 0; | |||||
} | |||||
/********************************************************* | |||||
* Name: crypto_sign_keypair | |||||
* Description: generates a public and private key pair | |||||
* Parameters: inputs: none | |||||
* outputs: | |||||
* - uint8_t *pk: public key | |||||
* - uint8_t *sk: secret key | |||||
* Returns: 0 for successful execution | |||||
**********************************************************/ | |||||
int PQCLEAN_QTESLAPI_CLEAN_crypto_sign_keypair(uint8_t *pk, uint8_t *sk) { | |||||
uint8_t randomness[CRYPTO_RANDOMBYTES], randomness_extended[(PARAM_K + 3)*CRYPTO_SEEDBYTES]; | |||||
poly s, s_ntt; | |||||
poly_k e, a, t; | |||||
size_t k; // Initialize domain separator for error and secret polynomials | |||||
uint16_t nonce = 0; | |||||
// Get randomness_extended <- seed_e, seed_s, seed_a, seed_y | |||||
randombytes(randomness, CRYPTO_RANDOMBYTES); | |||||
SHAKE(randomness_extended, (PARAM_K + 3)*CRYPTO_SEEDBYTES, randomness, CRYPTO_RANDOMBYTES); | |||||
for (k = 0; k < PARAM_K; k++) { | |||||
do { // Sample the error polynomials | |||||
PQCLEAN_QTESLAPI_CLEAN_sample_gauss_poly(&e[k * PARAM_N], &randomness_extended[k * CRYPTO_SEEDBYTES], ++nonce); | |||||
} while (check_ES(&e[k * PARAM_N], PARAM_KEYGEN_BOUND_E) != 0); | |||||
} | |||||
do { // Sample the secret polynomial | |||||
PQCLEAN_QTESLAPI_CLEAN_sample_gauss_poly(s, &randomness_extended[PARAM_K * CRYPTO_SEEDBYTES], ++nonce); | |||||
} while (check_ES(s, PARAM_KEYGEN_BOUND_S) != 0); | |||||
// Generate uniform polynomial "a" | |||||
PQCLEAN_QTESLAPI_CLEAN_poly_uniform(a, &randomness_extended[(PARAM_K + 1)*CRYPTO_SEEDBYTES]); | |||||
PQCLEAN_QTESLAPI_CLEAN_poly_ntt(s_ntt, s); | |||||
// Compute the public key t = as+e | |||||
for (k = 0; k < PARAM_K; k++) { | |||||
PQCLEAN_QTESLAPI_CLEAN_poly_mul(&t[k * PARAM_N], &a[k * PARAM_N], s_ntt); | |||||
PQCLEAN_QTESLAPI_CLEAN_poly_add_correct(&t[k * PARAM_N], &t[k * PARAM_N], &e[k * PARAM_N]); | |||||
} | |||||
// Pack public and private keys | |||||
PQCLEAN_QTESLAPI_CLEAN_pack_sk(sk, s, e, &randomness_extended[(PARAM_K + 1)*CRYPTO_SEEDBYTES]); | |||||
PQCLEAN_QTESLAPI_CLEAN_encode_pk(pk, t, &randomness_extended[(PARAM_K + 1)*CRYPTO_SEEDBYTES]); | |||||
return 0; | |||||
} | |||||
/*************************************************************** | |||||
* Name: crypto_sign | |||||
* Description: outputs a signature for a given message m | |||||
* Parameters: inputs: | |||||
* - const uint8_t *m: message to be signed | |||||
* - size_t mlen: message length | |||||
* - const uint8_t* sk: secret key | |||||
* outputs: | |||||
* - uint8_t *sm: signature | |||||
* - size_t *smlen: signature length* | |||||
* Returns: 0 for successful execution | |||||
***************************************************************/ | |||||
int PQCLEAN_QTESLAPI_CLEAN_crypto_sign(uint8_t *sm, size_t *smlen, const uint8_t *m, size_t mlen, const uint8_t *sk) { | |||||
uint8_t c[CRYPTO_C_BYTES], randomness[CRYPTO_SEEDBYTES], randomness_input[CRYPTO_RANDOMBYTES + CRYPTO_SEEDBYTES + HM_BYTES]; | |||||
uint32_t pos_list[PARAM_H]; | |||||
int16_t sign_list[PARAM_H]; | |||||
poly y, y_ntt, Sc, z; | |||||
poly_k v, Ec, a; | |||||
size_t k; | |||||
int rsp; | |||||
uint16_t nonce = 0; // Initialize domain separator for sampling y | |||||
// Get H(seed_y, r, H(m)) to sample y | |||||
randombytes(randomness_input + CRYPTO_RANDOMBYTES, CRYPTO_RANDOMBYTES); | |||||
memcpy(randomness_input, &sk[PQCLEAN_QTESLAPI_CLEAN_CRYPTO_SECRETKEYBYTES - CRYPTO_SEEDBYTES], CRYPTO_SEEDBYTES); | |||||
SHAKE(randomness_input + CRYPTO_RANDOMBYTES + CRYPTO_SEEDBYTES, HM_BYTES, m, mlen); | |||||
SHAKE(randomness, CRYPTO_SEEDBYTES, randomness_input, CRYPTO_RANDOMBYTES + CRYPTO_SEEDBYTES + HM_BYTES); | |||||
PQCLEAN_QTESLAPI_CLEAN_poly_uniform(a, &sk[PQCLEAN_QTESLAPI_CLEAN_CRYPTO_SECRETKEYBYTES - 2 * CRYPTO_SEEDBYTES]); | |||||
while (1) { | |||||
PQCLEAN_QTESLAPI_CLEAN_sample_y(y, randomness, ++nonce); // Sample y uniformly at random from [-B,B] | |||||
PQCLEAN_QTESLAPI_CLEAN_poly_ntt (y_ntt, y); | |||||
for (k = 0; k < PARAM_K; k++) { | |||||
PQCLEAN_QTESLAPI_CLEAN_poly_mul(&v[k * PARAM_N], &a[k * PARAM_N], y_ntt); | |||||
} | |||||
hash_H(c, v, randomness_input + CRYPTO_RANDOMBYTES + CRYPTO_SEEDBYTES); | |||||
PQCLEAN_QTESLAPI_CLEAN_encode_c(pos_list, sign_list, c); // Generate c = Enc(c'), where c' is the hashing of v together with m | |||||
PQCLEAN_QTESLAPI_CLEAN_sparse_mul8(Sc, sk, pos_list, sign_list); | |||||
PQCLEAN_QTESLAPI_CLEAN_poly_add(z, y, Sc); // Compute z = y + sc | |||||
if (test_rejection(z) != 0) { // Rejection sampling | |||||
continue; | |||||
} | |||||
for (k = 0; k < PARAM_K; k++) { | |||||
PQCLEAN_QTESLAPI_CLEAN_sparse_mul8(&Ec[k * PARAM_N], sk + (sizeof(int8_t)*PARAM_N * (k + 1)), pos_list, sign_list); | |||||
PQCLEAN_QTESLAPI_CLEAN_poly_sub(&v[k * PARAM_N], &v[k * PARAM_N], &Ec[k * PARAM_N]); | |||||
rsp = test_correctness(&v[k * PARAM_N]); | |||||
if (rsp != 0) { | |||||
break; | |||||
} | |||||
} | |||||
if (rsp != 0) { | |||||
continue; | |||||
} | |||||
// Copy message to signature package, and pack signature | |||||
for (size_t i = 0; i < mlen; i++) { | |||||
sm[PQCLEAN_QTESLAPI_CLEAN_CRYPTO_BYTES + i] = m[i]; | |||||
} | |||||
*smlen = PQCLEAN_QTESLAPI_CLEAN_CRYPTO_BYTES + mlen; | |||||
PQCLEAN_QTESLAPI_CLEAN_encode_sig(sm, c, z); | |||||
return 0; | |||||
} | |||||
} | |||||
/************************************************************ | |||||
* Name: crypto_sign_open | |||||
* Description: verification of a signature sm | |||||
* Parameters: inputs: | |||||
* - const uint8_t *sm: signature | |||||
* - size_t smlen: signature length | |||||
* - const uint8_t* pk: public Key | |||||
* outputs: | |||||
* - uint8_t *m: original (signed) message | |||||
* - size_t *mlen: message length* | |||||
* Returns: 0 for valid signature | |||||
* <0 for invalid signature | |||||
************************************************************/ | |||||
int PQCLEAN_QTESLAPI_CLEAN_crypto_sign_open(uint8_t *m, size_t *mlen, const uint8_t *sm, size_t smlen, const uint8_t *pk) { | |||||
uint8_t c[CRYPTO_C_BYTES], c_sig[CRYPTO_C_BYTES], seed[CRYPTO_SEEDBYTES], hm[HM_BYTES]; | |||||
uint32_t pos_list[PARAM_H]; | |||||
int16_t sign_list[PARAM_H]; | |||||
int32_t pk_t[PARAM_N * PARAM_K]; | |||||
poly_k w, a, Tc; | |||||
poly z, z_ntt; | |||||
size_t k; | |||||
if (smlen < PQCLEAN_QTESLAPI_CLEAN_CRYPTO_BYTES) { | |||||
return -1; | |||||
} | |||||
PQCLEAN_QTESLAPI_CLEAN_decode_sig(c, z, sm); | |||||
if (test_z(z) != 0) { | |||||
return -2; // Check norm of z | |||||
} | |||||
PQCLEAN_QTESLAPI_CLEAN_decode_pk(pk_t, seed, pk); | |||||
PQCLEAN_QTESLAPI_CLEAN_poly_uniform(a, seed); | |||||
PQCLEAN_QTESLAPI_CLEAN_encode_c(pos_list, sign_list, c); | |||||
PQCLEAN_QTESLAPI_CLEAN_poly_ntt(z_ntt, z); | |||||
for (k = 0; k < PARAM_K; k++) { // Compute w = az - tc | |||||
PQCLEAN_QTESLAPI_CLEAN_sparse_mul32(&Tc[k * PARAM_N], &pk_t[k * PARAM_N], pos_list, sign_list); | |||||
PQCLEAN_QTESLAPI_CLEAN_poly_mul(&w[k * PARAM_N], &a[k * PARAM_N], z_ntt); | |||||
PQCLEAN_QTESLAPI_CLEAN_poly_sub(&w[k * PARAM_N], &w[k * PARAM_N], &Tc[k * PARAM_N]); | |||||
} | |||||
SHAKE(hm, HM_BYTES, sm + PQCLEAN_QTESLAPI_CLEAN_CRYPTO_BYTES, smlen - PQCLEAN_QTESLAPI_CLEAN_CRYPTO_BYTES); | |||||
hash_H(c_sig, w, hm); | |||||
// Check if the calculated c matches c from the signature | |||||
if (memcmp(c, c_sig, CRYPTO_C_BYTES) != 0) { | |||||
return -3; | |||||
} | |||||
*mlen = smlen - PQCLEAN_QTESLAPI_CLEAN_CRYPTO_BYTES; | |||||
for (size_t i = 0; i < *mlen; i++) { | |||||
m[i] = sm[PQCLEAN_QTESLAPI_CLEAN_CRYPTO_BYTES + i]; | |||||
} | |||||
return 0; | |||||
} | |||||
int PQCLEAN_QTESLAPI_CLEAN_crypto_sign_signature( | |||||
uint8_t *sig, size_t *siglen, | |||||
const uint8_t *m, size_t mlen, | |||||
const uint8_t *sk) { | |||||
uint8_t c[CRYPTO_C_BYTES], randomness[CRYPTO_SEEDBYTES], randomness_input[CRYPTO_RANDOMBYTES + CRYPTO_SEEDBYTES + HM_BYTES]; | |||||
uint32_t pos_list[PARAM_H]; | |||||
int16_t sign_list[PARAM_H]; | |||||
poly y, y_ntt, Sc, z; | |||||
poly_k v, Ec, a; | |||||
size_t k; | |||||
int rsp; | |||||
uint16_t nonce = 0; // Initialize domain separator for sampling y | |||||
// Get H(seed_y, r, H(m)) to sample y | |||||
randombytes(randomness_input + CRYPTO_RANDOMBYTES, CRYPTO_RANDOMBYTES); | |||||
memcpy(randomness_input, &sk[PQCLEAN_QTESLAPI_CLEAN_CRYPTO_SECRETKEYBYTES - CRYPTO_SEEDBYTES], CRYPTO_SEEDBYTES); | |||||
SHAKE(randomness_input + CRYPTO_RANDOMBYTES + CRYPTO_SEEDBYTES, HM_BYTES, m, mlen); | |||||
SHAKE(randomness, CRYPTO_SEEDBYTES, randomness_input, CRYPTO_RANDOMBYTES + CRYPTO_SEEDBYTES + HM_BYTES); | |||||
PQCLEAN_QTESLAPI_CLEAN_poly_uniform(a, &sk[PQCLEAN_QTESLAPI_CLEAN_CRYPTO_SECRETKEYBYTES - 2 * CRYPTO_SEEDBYTES]); | |||||
while (1) { | |||||
PQCLEAN_QTESLAPI_CLEAN_sample_y(y, randomness, ++nonce); // Sample y uniformly at random from [-B,B] | |||||
PQCLEAN_QTESLAPI_CLEAN_poly_ntt (y_ntt, y); | |||||
for (k = 0; k < PARAM_K; k++) { | |||||
PQCLEAN_QTESLAPI_CLEAN_poly_mul(&v[k * PARAM_N], &a[k * PARAM_N], y_ntt); | |||||
} | |||||
hash_H(c, v, randomness_input + CRYPTO_RANDOMBYTES + CRYPTO_SEEDBYTES); | |||||
PQCLEAN_QTESLAPI_CLEAN_encode_c(pos_list, sign_list, c); // Generate c = Enc(c'), where c' is the hashing of v together with m | |||||
PQCLEAN_QTESLAPI_CLEAN_sparse_mul8(Sc, sk, pos_list, sign_list); | |||||
PQCLEAN_QTESLAPI_CLEAN_poly_add(z, y, Sc); // Compute z = y + sc | |||||
if (test_rejection(z) != 0) { // Rejection sampling | |||||
continue; | |||||
} | |||||
for (k = 0; k < PARAM_K; k++) { | |||||
PQCLEAN_QTESLAPI_CLEAN_sparse_mul8(&Ec[k * PARAM_N], sk + (sizeof(int8_t)*PARAM_N * (k + 1)), pos_list, sign_list); | |||||
PQCLEAN_QTESLAPI_CLEAN_poly_sub(&v[k * PARAM_N], &v[k * PARAM_N], &Ec[k * PARAM_N]); | |||||
rsp = test_correctness(&v[k * PARAM_N]); | |||||
if (rsp != 0) { | |||||
break; | |||||
} | |||||
} | |||||
if (rsp != 0) { | |||||
continue; | |||||
} | |||||
// pack signature | |||||
*siglen = PQCLEAN_QTESLAPI_CLEAN_CRYPTO_BYTES; | |||||
PQCLEAN_QTESLAPI_CLEAN_encode_sig(sig, c, z); | |||||
return 0; | |||||
} | |||||
} | |||||
int PQCLEAN_QTESLAPI_CLEAN_crypto_sign_verify( | |||||
const uint8_t *sig, size_t siglen, | |||||
const uint8_t *m, size_t mlen, | |||||
const uint8_t *pk) { | |||||
uint8_t c[CRYPTO_C_BYTES], c_sig[CRYPTO_C_BYTES], seed[CRYPTO_SEEDBYTES], hm[HM_BYTES]; | |||||
uint32_t pos_list[PARAM_H]; | |||||
int16_t sign_list[PARAM_H]; | |||||
int32_t pk_t[PARAM_N * PARAM_K]; | |||||
poly_k w, a, Tc; | |||||
poly z, z_ntt; | |||||
size_t k; | |||||
if (siglen < PQCLEAN_QTESLAPI_CLEAN_CRYPTO_BYTES) { | |||||
return -1; | |||||
} | |||||
PQCLEAN_QTESLAPI_CLEAN_decode_sig(c, z, sig); | |||||
if (test_z(z) != 0) { | |||||
return -2; // Check norm of z | |||||
} | |||||
PQCLEAN_QTESLAPI_CLEAN_decode_pk(pk_t, seed, pk); | |||||
PQCLEAN_QTESLAPI_CLEAN_poly_uniform(a, seed); | |||||
PQCLEAN_QTESLAPI_CLEAN_encode_c(pos_list, sign_list, c); | |||||
PQCLEAN_QTESLAPI_CLEAN_poly_ntt(z_ntt, z); | |||||
for (k = 0; k < PARAM_K; k++) { // Compute w = az - tc | |||||
PQCLEAN_QTESLAPI_CLEAN_sparse_mul32(&Tc[k * PARAM_N], &pk_t[k * PARAM_N], pos_list, sign_list); | |||||
PQCLEAN_QTESLAPI_CLEAN_poly_mul(&w[k * PARAM_N], &a[k * PARAM_N], z_ntt); | |||||
PQCLEAN_QTESLAPI_CLEAN_poly_sub(&w[k * PARAM_N], &w[k * PARAM_N], &Tc[k * PARAM_N]); | |||||
} | |||||
SHAKE(hm, HM_BYTES, m, mlen); | |||||
hash_H(c_sig, w, hm); | |||||
// Check if the calculated c matches c from the signature | |||||
if (memcmp(c, c_sig, CRYPTO_C_BYTES) != 0) { | |||||
return -3; | |||||
} | |||||
return 0; | |||||
} |
@@ -0,0 +1,25 @@ | |||||
name: qTESLA-p-III | |||||
type: signature | |||||
claimed-nist-level: 3 | |||||
length-public-key: 38432 | |||||
length-secret-key: 12352 | |||||
length-signature: 5664 | |||||
nistkat-sha256: f2c0c872ab5bcb9276205f09364bf5cd6705141899360d2e231e42fce0a06b59 | |||||
testvectors-sha256: 484cb7f79dade34857c58845842893a6dc60b6c4a80557b4500b604e1d07fe87 | |||||
principal-submitters: | |||||
- Nina Bindel | |||||
auxiliary-submitters: | |||||
- Sedat Akleylek | |||||
- Erdem Alkim | |||||
- Paulo S. L. M. Barreto | |||||
- Johannes Buchmann | |||||
- Edward Eaton | |||||
- Gus Gutoski | |||||
- Juliane Krämer | |||||
- Patrick Longa | |||||
- Harun Polat | |||||
- Jefferson E. Ricardini | |||||
- Gustavo Zanon | |||||
implementations: | |||||
- name: clean | |||||
version: https://qtesla.org/wp-content/uploads/2019/08/qTESLA_NIST_update_08.19.2019.zip |
@@ -0,0 +1,142 @@ | |||||
#ifndef PQCLEAN_QTESLAPIII_CLEAN_CDTSAMP | |||||
#define PQCLEAN_QTESLAPIII_CLEAN_CDTSAMP | |||||
/************************************************************************************* | |||||
* qTESLA: an efficient post-quantum signature scheme based on the R-LWE problem | |||||
* | |||||
* Abstract: CDT constants for the Gaussian sampler | |||||
**************************************************************************************/ | |||||
#include "params.h" | |||||
#include <stdint.h> | |||||
// Sigma = 8.5, 128-bit precision | |||||
#define CDT_ROWS 111 | |||||
#define CDT_COLS 4 | |||||
static const int32_t cdt_v[CDT_ROWS * CDT_COLS] = { | |||||
0x00000000L, 0x00000000L, 0x00000000L, 0x00000000L, // 0 | |||||
0x0601F22AL, 0x280663D4L, 0x2E1B038CL, 0x1E75FCA7L, // 1 | |||||
0x11F09FFAL, 0x162FE23DL, 0x403739B4L, 0x3F2AA531L, // 2 | |||||
0x1DA089E9L, 0x437226E8L, 0x115E99C8L, 0x68C472A6L, // 3 | |||||
0x28EAB25DL, 0x04C51FE2L, 0x13F63FD0L, 0x1E56BF40L, // 4 | |||||
0x33AC2F26L, 0x14FDBA70L, 0x6618880FL, 0x792CE93EL, // 5 | |||||
0x3DC767DCL, 0x4565C95FL, 0x7EAC4790L, 0x163F4D99L, // 6 | |||||
0x4724FC62L, 0x3342C78AL, 0x390873B2L, 0x13A12ACEL, // 7 | |||||
0x4FB448F4L, 0x5229D06DL, 0x09A6C84BL, 0x1D13CB0DL, // 8 | |||||
0x576B8599L, 0x7423407FL, 0x1287EE2FL, 0x7B908556L, // 9 | |||||
0x5E4786DAL, 0x3210BAF6L, 0x6881795CL, 0x13DF4F59L, // 10 | |||||
0x644B2C92L, 0x431B3946L, 0x63F188D9L, 0x22AFB6DEL, // 11 | |||||
0x697E90CEL, 0x77C362C3L, 0x600A627EL, 0x66AEDF96L, // 12 | |||||
0x6DEE0B96L, 0x2798C9CEL, 0x147A98F9L, 0x27427F24L, // 13 | |||||
0x71A92144L, 0x5765FCE4L, 0x0FF04C94L, 0x74183C18L, // 14 | |||||
0x74C16FD5L, 0x1E2A0990L, 0x13EB545FL, 0x1CD9A2ADL, // 15 | |||||
0x7749AC92L, 0x0DF36EEBL, 0x414629E5L, 0x66610A51L, // 16 | |||||
0x7954BFA4L, 0x28079289L, 0x29D5B127L, 0x29B69601L, // 17 | |||||
0x7AF5067AL, 0x2EDC2050L, 0x2B486556L, 0x43BF4664L, // 18 | |||||
0x7C3BC17CL, 0x123D5E7AL, 0x63D4DD26L, 0x3B1E3755L, // 19 | |||||
0x7D38AD76L, 0x2A9381D9L, 0x1D20D034L, 0x77C09C55L, // 20 | |||||
0x7DF9C5DFL, 0x0E868CA7L, 0x23627687L, 0x78864423L, // 21 | |||||
0x7E8B2ABAL, 0x18E5C810L, 0x7C85B42CL, 0x7AC98BCCL, // 22 | |||||
0x7EF7237CL, 0x00908272L, 0x3D4B170EL, 0x3CD572E3L, // 23 | |||||
0x7F4637C5L, 0x6DBA5125L, 0x5B0285ECL, 0x46661EB9L, // 24 | |||||
0x7F7F5707L, 0x4A52EDEBL, 0x50ECECB1L, 0x7384DC42L, // 25 | |||||
0x7FA808CCL, 0x23290598L, 0x704F7A4DL, 0x08532154L, // 26 | |||||
0x7FC4A083L, 0x69BDF2D4L, 0x73B67B27L, 0x3AE237ADL, // 27 | |||||
0x7FD870CAL, 0x42275557L, 0x6F2AE034L, 0x4E4B0395L, // 28 | |||||
0x7FE5FB5DL, 0x3EF82C1BL, 0x256E2EB0L, 0x09E42B11L, // 29 | |||||
0x7FEF1BFAL, 0x6C03A362L, 0x07334BD4L, 0x22B6B15FL, // 30 | |||||
0x7FF52D4EL, 0x316C2C8CL, 0x1C77A4C3L, 0x1C3A974EL, // 31 | |||||
0x7FF927BAL, 0x12AE54AEL, 0x6CC24956L, 0x3BA9A3E4L, // 32 | |||||
0x7FFBBA43L, 0x749CC0E2L, 0x044B3068L, 0x620F14DAL, // 33 | |||||
0x7FFD5E3DL, 0x4524AD91L, 0x31F84A1FL, 0x4D23AF51L, // 34 | |||||
0x7FFE6664L, 0x535785B4L, 0x683C9E5EL, 0x2BD857DFL, // 35 | |||||
0x7FFF0A41L, 0x0B291681L, 0x1CB4CE6FL, 0x32B314B9L, // 36 | |||||
0x7FFF6E81L, 0x132C3D6FL, 0x4C8771CCL, 0x67421A75L, // 37 | |||||
0x7FFFAAFEL, 0x4DBC6BEDL, 0x4E8644D2L, 0x5158A208L, // 38 | |||||
0x7FFFCEFDL, 0x7A1E2D14L, 0x2CF905AAL, 0x79BFABD9L, // 39 | |||||
0x7FFFE41EL, 0x4C6EC115L, 0x2D648F1AL, 0x4B01BA3EL, // 40 | |||||
0x7FFFF059L, 0x319503C8L, 0x2CBEB96AL, 0x52FF656EL, // 41 | |||||
0x7FFFF754L, 0x5DDD0D40L, 0x09D07206L, 0x6BF97EB5L, // 42 | |||||
0x7FFFFB43L, 0x0B9E9822L, 0x5B584BE0L, 0x4974ED83L, // 43 | |||||
0x7FFFFD71L, 0x76B81AE1L, 0x3C93755CL, 0x375F857BL, // 44 | |||||
0x7FFFFEA3L, 0x7E66A1ECL, 0x3E342087L, 0x44ED1696L, // 45 | |||||
0x7FFFFF49L, 0x26F6E190L, 0x7E3625F9L, 0x2F4F5849L, // 46 | |||||
0x7FFFFFA1L, 0x2FA31694L, 0x0D53F684L, 0x59931C0DL, // 47 | |||||
0x7FFFFFCFL, 0x5247BEC8L, 0x5CC20735L, 0x397CE966L, // 48 | |||||
0x7FFFFFE7L, 0x4F4127C6L, 0x64926788L, 0x01CFEF66L, // 49 | |||||
0x7FFFFFF3L, 0x6FAA69FDL, 0x26A67DC3L, 0x1FFA2528L, // 50 | |||||
0x7FFFFFFAL, 0x0630D072L, 0x7AA0C1B7L, 0x7E90AAE6L, // 51 | |||||
0x7FFFFFFDL, 0x0F2957BBL, 0x3ADCE1E6L, 0x5A311C28L, // 52 | |||||
0x7FFFFFFEL, 0x4FD29431L, 0x6429F9EDL, 0x04653965L, // 53 | |||||
0x7FFFFFFFL, 0x2CFAD60DL, 0x52ED82D1L, 0x26455881L, // 54 | |||||
0x7FFFFFFFL, 0x5967A92FL, 0x5C85AB2DL, 0x188033BEL, // 55 | |||||
0x7FFFFFFFL, 0x6E4C9DFEL, 0x76798EAFL, 0x0DC0BA65L, // 56 | |||||
0x7FFFFFFFL, 0x77FDCCC8L, 0x194FF9ACL, 0x2C3FA855L, // 57 | |||||
0x7FFFFFFFL, 0x7C6CE89EL, 0x01FA1A72L, 0x6C3DC40BL, // 58 | |||||
0x7FFFFFFFL, 0x7E6D116EL, 0x5F82B352L, 0x57B67FCEL, // 59 | |||||
0x7FFFFFFFL, 0x7F50FA31L, 0x31856599L, 0x579DC24BL, // 60 | |||||
0x7FFFFFFFL, 0x7FB50089L, 0x43E64BB5L, 0x7F498E42L, // 61 | |||||
0x7FFFFFFFL, 0x7FE04C2CL, 0x56CBFAEFL, 0x7FC9C15FL, // 62 | |||||
0x7FFFFFFFL, 0x7FF2C7C0L, 0x5D509634L, 0x41DCA82BL, // 63 | |||||
0x7FFFFFFFL, 0x7FFA8FE3L, 0x24F6020DL, 0x7B594401L, // 64 | |||||
0x7FFFFFFFL, 0x7FFDCB1BL, 0x2D294BB3L, 0x1D1631BFL, // 65 | |||||
0x7FFFFFFFL, 0x7FFF1DE1L, 0x5D75B704L, 0x323B12FEL, // 66 | |||||
0x7FFFFFFFL, 0x7FFFA6B6L, 0x7E983E86L, 0x23392636L, // 67 | |||||
0x7FFFFFFFL, 0x7FFFDD39L, 0x029CCA2CL, 0x035F7017L, // 68 | |||||
0x7FFFFFFFL, 0x7FFFF2A3L, 0x205DBF7BL, 0x173D7F90L, // 69 | |||||
0x7FFFFFFFL, 0x7FFFFAEFL, 0x3F79145BL, 0x642F005DL, // 70 | |||||
0x7FFFFFFFL, 0x7FFFFE1BL, 0x23B2C7E4L, 0x6CA216CFL, // 71 | |||||
0x7FFFFFFFL, 0x7FFFFF4DL, 0x1E959E3FL, 0x4A29BB03L, // 72 | |||||
0x7FFFFFFFL, 0x7FFFFFBEL, 0x7C23D3D9L, 0x71DC92E4L, // 73 | |||||
0x7FFFFFFFL, 0x7FFFFFE8L, 0x55110485L, 0x0E1813E2L, // 74 | |||||
0x7FFFFFFFL, 0x7FFFFFF7L, 0x5EBC7B7BL, 0x2DFEE922L, // 75 | |||||
0x7FFFFFFFL, 0x7FFFFFFDL, 0x0EDB0975L, 0x0C9F1639L, // 76 | |||||
0x7FFFFFFFL, 0x7FFFFFFFL, 0x00DDA1A1L, 0x6DE86AA0L, // 77 | |||||
0x7FFFFFFFL, 0x7FFFFFFFL, 0x54CF6D87L, 0x023F1F47L, // 78 | |||||
0x7FFFFFFFL, 0x7FFFFFFFL, 0x7186FF6AL, 0x5B71BF8CL, // 79 | |||||
0x7FFFFFFFL, 0x7FFFFFFFL, 0x7B375EBCL, 0x767A89DCL, // 80 | |||||
0x7FFFFFFFL, 0x7FFFFFFFL, 0x7E70BA89L, 0x44EBCEAAL, // 81 | |||||
0x7FFFFFFFL, 0x7FFFFFFFL, 0x7F7F98B5L, 0x44C8E44AL, // 82 | |||||
0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FD744C2L, 0x448EE5A4L, // 83 | |||||
0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FF34165L, 0x008855D0L, // 84 | |||||
0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFC1110L, 0x754A60B6L, // 85 | |||||
0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFECD77L, 0x44BE6D4AL, // 86 | |||||
0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFFA3F4L, 0x7400A73EL, // 87 | |||||
0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFFE4BDL, 0x1143830BL, // 88 | |||||
0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFFF809L, 0x1A385059L, // 89 | |||||
0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFFFDB4L, 0x41CA0794L, // 90 | |||||
0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFFFF59L, 0x02FFB605L, // 91 | |||||
0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFFFFD1L, 0x18360E8DL, // 92 | |||||
0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFFFFF3L, 0x072A0E9AL, // 93 | |||||
0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFFFFFCL, 0x3C1BFEB0L, // 94 | |||||
0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFFFFFFL, 0x066EBCDDL, // 95 | |||||
0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFFFFFFL, 0x5FBE171AL, // 96 | |||||
0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFFFFFFL, 0x778EB81FL, // 97 | |||||
0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFFFFFFL, 0x7DD211FEL, // 98 | |||||
0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFFFFFFL, 0x7F71F071L, // 99 | |||||
0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FDC528FL, // 100 | |||||
0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FF7298CL, // 101 | |||||
0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFDD739L, // 102 | |||||
0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFF7ACAL, // 103 | |||||
0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFFE056L, // 104 | |||||
0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFFF893L, // 105 | |||||
0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFFFE48L, // 106 | |||||
0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFFFF9CL, // 107 | |||||
0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFFFFE9L, // 108 | |||||
0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFFFFFBL, // 109 | |||||
0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFFFFFFL, // 110 | |||||
}; // cdt_v | |||||
// memory requirements: | |||||
// 2048 samples: 43180 bytes | |||||
// 1024 samples: 22700 bytes | |||||
// 512 samples: 12460 bytes | |||||
// 256 samples: 7340 bytes | |||||
// 128 samples: 4780 bytes | |||||
// 64 samples: 3500 bytes | |||||
// 32 samples: 2860 bytes | |||||
// table alone: 1776 bytes | |||||
#endif |
@@ -0,0 +1,28 @@ | |||||
Lattice-based digital signature scheme qTESLA | |||||
The qTESLA source code and header files in this package are released with an MIT license. | |||||
MIT License | |||||
Copyright (c) Microsoft Corporation and qTESLA implementation owners: | |||||
Sedat Akleylek, Erdem Alkim, Paulo Barreto, Patrick Longa, Harun Polat, | |||||
Jefferson Ricardini, and Gustavo Zanon. All rights reserved. | |||||
Permission is hereby granted, free of charge, to any person obtaining a copy | |||||
of this software and associated documentation files (the "Software"), to deal | |||||
in the Software without restriction, including without limitation the rights | |||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||||
copies of the Software, and to permit persons to whom the Software is | |||||
furnished to do so, subject to the following conditions: | |||||
The above copyright notice and this permission notice shall be included in all | |||||
copies or substantial portions of the Software. | |||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||||
SOFTWARE | |||||
@@ -0,0 +1,20 @@ | |||||
# This Makefile can be used with GNU Make or BSD Make | |||||
LIB=libqtesla-p-III_clean.a | |||||
HEADERS = api.h CDT32.h config.h gauss.h pack.h params.h poly.h sample.h | |||||
OBJECTS = consts.o gauss.o pack.o poly.o sample.o sign.o | |||||
CFLAGS=-O3 -Wall -Wconversion -Wextra -Wpedantic -Wvla -Werror -Wmissing-prototypes -Wredundant-decls -std=c99 -I../../../common $(EXTRAFLAGS) | |||||
all: $(LIB) | |||||
%.o: %.c $(HEADERS) | |||||
$(CC) $(CFLAGS) -c -o $@ $< | |||||
$(LIB): $(OBJECTS) | |||||
$(AR) -r $@ $(OBJECTS) | |||||
clean: | |||||
$(RM) $(OBJECTS) | |||||
$(RM) $(LIB) |
@@ -0,0 +1,19 @@ | |||||
# This Makefile can be used with Microsoft Visual Studio's nmake using the command: | |||||
# nmake /f Makefile.Microsoft_nmake | |||||
LIBRARY=libqtesla-p-III_clean.lib | |||||
OBJECTS=consts.obj gauss.obj pack.obj poly.obj sample.obj sign.obj | |||||
CFLAGS=/nologo /I ..\..\..\common /W4 /WX | |||||
all: $(LIBRARY) | |||||
# Make sure objects are recompiled if headers change. | |||||
$(OBJECTS): *.h | |||||
$(LIBRARY): $(OBJECTS) | |||||
LIB.EXE /NOLOGO /WX /OUT:$@ $** | |||||
clean: | |||||
-DEL $(OBJECTS) | |||||
-DEL $(LIBRARY) |
@@ -0,0 +1,42 @@ | |||||
#ifndef PQCLEAN_QTESLAPIII_CLEAN_API_H | |||||
#define PQCLEAN_QTESLAPIII_CLEAN_API_H | |||||
/************************************************************************************* | |||||
* qTESLA: an efficient post-quantum signature scheme based on the R-LWE problem | |||||
* | |||||
* Abstract: API header file | |||||
**************************************************************************************/ | |||||
#include <stddef.h> | |||||
#include <stdint.h> | |||||
#define PQCLEAN_QTESLAPIII_CLEAN_CRYPTO_SECRETKEYBYTES 12352 | |||||
#define PQCLEAN_QTESLAPIII_CLEAN_CRYPTO_PUBLICKEYBYTES 38432 | |||||
#define PQCLEAN_QTESLAPIII_CLEAN_CRYPTO_BYTES 5664 | |||||
#define PQCLEAN_QTESLAPIII_CLEAN_CRYPTO_ALGNAME "qTESLA-p-III" | |||||
int PQCLEAN_QTESLAPIII_CLEAN_crypto_sign_keypair( | |||||
uint8_t *pk, uint8_t *sk); | |||||
int PQCLEAN_QTESLAPIII_CLEAN_crypto_sign( | |||||
uint8_t *sm, size_t *smlen, | |||||
const uint8_t *m, size_t mlen, | |||||
const uint8_t *sk); | |||||
int PQCLEAN_QTESLAPIII_CLEAN_crypto_sign_open( | |||||
uint8_t *m, size_t *mlen, | |||||
const uint8_t *sm, size_t smlen, | |||||
const uint8_t *pk | |||||
); | |||||
int PQCLEAN_QTESLAPIII_CLEAN_crypto_sign_signature( | |||||
uint8_t *sig, size_t *siglen, | |||||
const uint8_t *m, size_t mlen, | |||||
const uint8_t *sk); | |||||
int PQCLEAN_QTESLAPIII_CLEAN_crypto_sign_verify( | |||||
const uint8_t *sig, size_t siglen, | |||||
const uint8_t *m, size_t mlen, | |||||
const uint8_t *pk); | |||||
#endif |
@@ -0,0 +1,19 @@ | |||||
#ifndef PQCLEAN_QTESLAPIII_CLEAN_CONFIG_H | |||||
#define PQCLEAN_QTESLAPIII_CLEAN_CONFIG_H | |||||
/************************************************************************************* | |||||
* qTESLA: an efficient post-quantum signature scheme based on the R-LWE problem | |||||
* | |||||
* Abstract: configuration file | |||||
**************************************************************************************/ | |||||
#include <stdbool.h> | |||||
#include <stddef.h> | |||||
#include <stdint.h> | |||||
#define RADIX 32 | |||||
#define RADIX32 32 | |||||
typedef uint32_t digit_t; | |||||
typedef int32_t sdigit_t; | |||||
#endif |
@@ -0,0 +1,274 @@ | |||||
/************************************************************************************* | |||||
* qTESLA: an efficient post-quantum signature scheme based on the R-LWE problem | |||||
* | |||||
* Abstract: constants for the NTT | |||||
**************************************************************************************/ | |||||
#include "params.h" | |||||
#include "poly.h" | |||||
#include <stdint.h> | |||||
const poly PQCLEAN_QTESLAPIII_CLEAN_zeta = { | |||||
147314272, 762289503, 284789571, 461457674, 723990704, 123382358, 685457283, 458774590, 644795450, 723622678, 441493948, 676062368, 648739792, 214990524, 261899220, 138474554, | |||||
205277234, 788000393, 541334956, 769530525, 786231394, 812002793, 251385069, 152717354, 674883688, 458756880, 323745289, 823881240, 686340396, 716163820, 107735873, 144028791, | |||||
586327243, 71257244, 739303131, 487030542, 313626215, 396596783, 664640087, 728258996, 854656117, 567834989, 2315110, 210792230, 795895843, 433034260, 432732757, 480454055, | |||||
750130006, 47628047, 2271301, 98590211, 729637734, 683553815, 476917424, 121851414, 296210757, 820475433, 403416438, 605633242, 804828963, 435181077, 781182803, 276684653, | |||||
329135201, 697859430, 248472020, 396579594, 109340098, 97605675, 755271019, 565755143, 534799496, 378374148, 85686225, 298978496, 650100484, 712463562, 818417023, 283716467, | |||||
269132585, 153024538, 223768950, 331863760, 761523727, 586019306, 805044248, 810909760, 77905343, 401203343, 162625701, 616243024, 659789238, 385270982, 720521140, 545633566, | |||||
688663167, 740046782, 257189758, 115795491, 101106443, 409863172, 622399622, 405606434, 498832246, 730567206, 350755879, 41236295, 561547732, 525723591, 18655497, 3396399, | |||||
289694332, 221478904, 738940554, 769726362, 32128402, 693016435, 275431006, 65292213, 601823865, 469363520, 480544944, 607230206, 473150754, 267072604, 463615065, 412972775, | |||||
197544577, 770873783, 189036815, 407973558, 110878446, 442760341, 667560342, 756992079, 663708407, 585601880, 763637579, 660019224, 424935088, 249313490, 844593983, 664952705, | |||||
274981537, 40233161, 655530034, 742724096, 8926394, 67709207, 616610795, 539664358, 306118645, 741629065, 283521858, 621397947, 369041534, 162477412, 258256937, 269480966, | |||||
75469364, 815614830, 724060729, 510819743, 489239410, 265607303, 103024793, 434961090, 474838542, 234701483, 505818866, 450427360, 188113529, 650423376, 599263141, 720479782, | |||||
755079140, 469798456, 745591660, 432033717, 530128582, 94480771, 722477467, 169342233, 35413255, 89769525, 424389771, 240236288, 360665614, 66702784, 76128663, 565345206, | |||||
605031892, 393503210, 249841967, 485930917, 45880284, 746120091, 684031522, 537926896, 408749937, 608644803, 692593939, 515424474, 748771159, 155377700, 347101257, 393516280, | |||||
708186062, 809233270, 562547654, 768251664, 651110951, 574473323, 588028067, 352359235, 646902518, 410726541, 134129459, 460099853, 829152883, 819102028, 7270760, 562515302, | |||||
419641762, 347973450, 161011009, 401974733, 619807719, 559105457, 276126568, 165473862, 380215069, 356617900, 347744328, 615885981, 824819772, 811367929, 6451967, 515345658, | |||||
648239021, 56427040, 709160497, 71545092, 390921213, 17177139, 194174898, 825533429, 497469884, 88988508, 64227614, 641021859, 159258883, 529265733, 823190295, 567280997, | |||||
414094239, 238392498, 695610059, 416342151, 90807038, 206865379, 568337348, 168011486, 844375038, 777332780, 147582038, 199025846, 396231915, 151630666, 466807217, 12672521, | |||||
570774644, 764098787, 283719496, 779154504, 383628791, 851035387, 395488461, 291115871, 52707730, 776449280, 479801706, 73403989, 402014636, 255214342, 56904698, 446531030, | |||||
639487570, 848061696, 202732901, 739018922, 653983847, 453022791, 391722680, 584290855, 270911670, 390838431, 653070075, 535876472, 83207555, 131151682, 505677504, 778583044, | |||||
472363568, 734419459, 768500943, 321131696, 371745445, 751887879, 51797676, 157604159, 838805925, 358099697, 763440819, 776721566, 719570904, 304610785, 656838485, 239522278, | |||||
796234199, 659506535, 825373307, 674901303, 250484891, 54612517, 410236408, 111976920, 728940855, 720463104, 559960962, 514189554, 637176165, 436151981, 485801800, 802811374, | |||||
549456481, 808832355, 112672706, 199163132, 807410080, 645955491, 365378122, 222316474, 381896744, 693909930, 402130292, 199856804, 277639257, 6848838, 648262319, 601521139, | |||||
108516632, 392382841, 563420106, 475932203, 249861415, 99274558, 152886431, 744977783, 269184267, 562674804, 760959275, 733098096, 771348891, 674288361, 631521272, 513632066, | |||||
476339117, 621937967, 206834230, 507101607, 420341698, 528715580, 853092790, 580174958, 278044321, 432350205, 603769437, 144426940, 733518338, 365468467, 848983278, 385382826, | |||||
846062026, 593903051, 216589699, 219997638, 350708517, 733669279, 624754239, 499821820, 772548008, 199677439, 287505007, 144199205, 215073292, 825467700, 101591831, 571728784, | |||||
841898341, 420897808, 61323616, 823475752, 72494861, 89946011, 236594097, 379582577, 539401967, 221244669, 479250487, 100726882, 263096036, 647161225, 491060387, 419890898, | |||||
816149055, 546441322, 690509770, 215789647, 5870948, 821456387, 294091098, 783700004, 278643020, 520754327, 813718894, 123610053, 157045201, 265331664, 807174256, 258134244, | |||||
703519669, 300265991, 41892125, 662173055, 439638698, 494124024, 700655120, 535348417, 37146186, 379568907, 644973451, 554904963, 594757858, 477812802, 266085643, 46337543, | |||||
454847754, 496027901, 701947604, 5722633, 790588605, 233501932, 728956461, 462020148, 214013660, 155806979, 159935426, 423504958, 638889309, 602641304, 277759403, 71654804, | |||||
710920410, 108337831, 641924564, 252946326, 463082282, 23277660, 142056200, 263317553, 9044238, 367816044, 349695658, 291597086, 230031083, 385106216, 281069679, 644033142, | |||||
134221740, 212497862, 686686078, 787489098, 781698667, 748299513, 774414792, 380836293, 114027649, 766161763, 10536612, 707355910, 100516219, 637517297, 21478533, 769067854, | |||||
668364559, 410803198, 64949715, 643421522, 525590993, 585289785, 423839840, 554109325, 450599860, 295350132, 435789550, 306634115, 611298620, 777817576, 553655202, 804525538, | |||||
794474290, 138542076, 780958763, 62228371, 738032107, 684994110, 661486955, 67099069, 68865906, 32413094, 358393763, 205008770, 849715545, 289798348, 384767209, 787328590, | |||||
823677120, 47455925, 706001331, 612392717, 487804928, 731804935, 520572665, 442307581, 351275150, 726042356, 667657829, 254929787, 459520026, 625393223, 319307882, 77267096, | |||||
815224795, 335964550, 408353208, 604252110, 574953308, 563501897, 515015302, 313600371, 178773384, 417549087, 510834475, 167049599, 488791556, 664276219, 82933775, 822541833, | |||||
17111190, 409659978, 96304098, 500484311, 269766378, 327037310, 584926256, 538611363, 404132255, 170931824, 744460626, 154011192, 322194096, 215888234, 258344560, 702851111, | |||||
192046250, 738511820, 530780560, 57197515, 335425579, 410968369, 830078545, 448351649, 208921555, 356653676, 718038774, 424362596, 158929491, 420096666, 387056270, 797383293, | |||||
381201911, 466480709, 373815662, 84912008, 4969808, 524614597, 93448903, 559481007, 400813998, 665223025, 601707338, 466022707, 192709574, 615503265, 822863744, 639854175, | |||||
158713505, 12757666, 389196370, 823105438, 682974863, 468401586, 93508626, 402414043, 806357152, 180544963, 27876186, 321527031, 329857607, 669501423, 829809824, 333202822, | |||||
106923493, 368991112, 282317903, 790323774, 517381333, 548329656, 236147848, 700119793, 404187488, 343578810, 798813301, 497964535, 656188346, 678161787, 736817175, 518031339, | |||||
716647183, 674797219, 308643560, 714308544, 516103468, 605229646, 564549717, 47650358, 706404486, 494887760, 152496104, 54954356, 271435602, 76951527, 136123931, 601823638, | |||||
329273401, 252710411, 754980731, 351648254, 49239731, 837833233, 88830509, 598216539, 155534490, 669603727, 418388693, 79322074, 636251444, 703683994, 796989459, 126497707, | |||||
644863316, 730359063, 265213001, 64483814, 552208981, 8135537, 782474322, 780853310, 733976806, 395661138, 128188419, 266691358, 407092046, 447349747, 526245954, 119272088, | |||||
359659635, 812410956, 669835517, 565139408, 248981831, 139910745, 685462294, 406991131, 709944045, 589819925, 714299787, 72923680, 648836181, 145321778, 392775383, 243093077, | |||||
412955839, 174619485, 310936394, 699727061, 421087619, 745421519, 539546394, 29471558, 116471631, 852650639, 443777703, 773131303, 81618669, 756719012, 702785073, 847088653, | |||||
851830586, 300908692, 430974543, 463215976, 668971423, 414271988, 108350516, 345933325, 716417649, 174980945, 679092437, 384030489, 814050910, 506580116, 249434097, 178438885, | |||||
146797119, 10369463, 296359082, 215645133, 149545847, 483689845, 322009569, 308978588, 38531178, 328571637, 815396967, 709744233, 765487128, 645413104, 564779557, 213794315, | |||||
280607549, 124792697, 423470554, 631348430, 21223627, 220718413, 598791979, 47797633, 734556299, 590321944, 168292920, 484802055, 340999812, 769601438, 42675060, 116026587, | |||||
227462622, 543574607, 444066479, 467277895, 278798674, 597413704, 350168725, 301936652, 82885511, 656047519, 765110538, 52228202, 533005731, 621989298, 148235931, 317833915, | |||||
118463894, 522391939, 451332724, 548031654, 73854149, 527786213, 583308898, 840663438, 275278054, 362931963, 587861579, 830807449, 431695707, 178004048, 75513216, 60681147, | |||||
638603143, 470791469, 490903319, 527370962, 102981857, 224220555, 756514239, 293859807, 797926303, 620196520, 466126507, 646136763, 265504163, 213257337, 92270416, 398713724, | |||||
91810366, 724247342, 855386762, 631553083, 376095634, 833728623, 636218061, 510719408, 378530670, 737821436, 127781731, 3443282, 770116208, 769633348, 430675947, 40370755, | |||||
52361322, 844601468, 442556599, 128290354, 494328514, 405616679, 651440882, 421541290, 171560170, 386143493, 284277254, 450756213, 248305939, 526718005, 300780198, 714218239, | |||||
68021827, 527353904, 236472015, 309320156, 683815803, 527980097, 598849444, 779607597, 339852811, 845420163, 96001931, 326760873, 609319751, 520803868, 140143851, 766988701, | |||||
844896794, 532008178, 388459130, 574799295, 760406065, 773758517, 453271555, 134636434, 155747417, 105505251, 796987277, 399016325, 71156680, 709579308, 274279004, 96962867, | |||||
476741915, 585319990, 709143538, 721328791, 293159344, 640577897, 138404614, 572892015, 394460832, 465897068, 325895331, 413861636, 447337182, 376950267, 721061932, 181671909, | |||||
272138750, 247768905, 634973622, 280653872, 165108426, 134241779, 15142090, 153256717, 783424845, 773227607, 172477802, 504458250, 349868083, 461422806, 487725644, 586146740, | |||||
561546455, 815406759, 468110471, 126476456, 285774551, 522013234, 801943660, 79684345, 654558548, 188038414, 249923934, 551812615, 562560206, 407120348, 384535446, 176837117, | |||||
433155458, 82591339, 459412819, 435604627, 312211805, 98158590, 752137480, 446017293, 666480139, 60261988, 275386848, 642778031, 8582401, 677484160, 819506256, 333441964, | |||||
25465219, 190315429, 91529631, 754681170, 563660271, 167135649, 20270015, 115773732, 658954441, 132923202, 844102455, 453432758, 250487209, 423813160, 632223296, 537494486, | |||||
158265753, 327949044, 494109748, 659672289, 67984726, 422358258, 345141182, 164372996, 338500924, 41400311, 207638305, 832074651, 50853458, 228267776, 621895888, 635834787, | |||||
484972544, 181125024, 558134871, 282159878, 788157855, 145576343, 194837894, 501440949, 63641414, 252098681, 835930645, 662856247, 456140980, 206147937, 565198503, 449503819, | |||||
684013129, 494002381, 793836418, 649296754, 444313288, 136544068, 540002286, 355912945, 613175147, 134541429, 843111781, 672612536, 541098995, 734996181, 211869705, 620777828, | |||||
756152791, 242128346, 795442420, 73925532, 735232214, 738668090, 530800757, 266183732, 97165934, 803231879, 10057267, 175942047, 181460965, 320684297, 637472526, 213840116, | |||||
182671953, 152704513, 388004388, 597349323, 473851493, 445333546, 679315863, 267078568, 46538491, 530171754, 698082287, 75308587, 266467406, 96440883, 759196579, 470119952, | |||||
381731475, 428392158, 10628712, 173921356, 116809433, 323843928, 812172630, 403459283, 655501128, 261944441, 774418023, 790520709, 589149480, 264133112, 806274256, 752372117, | |||||
66236193, 713859568, 90804933, 551864345, 843839891, 600244073, 719230074, 803646506, 254956426, 138935723, 738829647, 109576220, 105819621, 249706947, 110623114, 10002331, | |||||
795710911, 547062229, 721440199, 820747461, 397666160, 685179945, 463869301, 470338753, 641244231, 652990696, 698429485, 41147155, 638072709, 515832968, 241130026, 314161759, | |||||
526815813, 529167244, 53391331, 782008115, 822962086, 337706389, 648197286, 209496506, 760818531, 781900302, 717270807, 709143641, 740503641, 734328409, 514061476, 844010670, | |||||
67993787, 712083588, 319801387, 338260400, 48758556, 304195768, 478833380, 841413917, 710197685, 196321647, 777595184, 775983866, 147506314, 620961439, 399972264, 398715644, | |||||
684489092, 659918078, 664075287, 723890579, 643103903, 508525962, 375409248, 501237729, 740609783, 639854810, 510797913, 521151016, 421045341, 193698327, 800266392, 93518128, | |||||
443879633, 699245445, 194001794, 123905867, 75572337, 242620749, 463111940, 755239011, 31718790, 162155292, 386689240, 381413538, 745322913, 367897558, 343088005, 31706107, | |||||
10842029, 404961623, 537521191, 281624684, 372852160, 55286017, 534907560, 264398082, 667644310, 486871690, 716964533, 734731419, 143593638, 293949413, 760014789, 594443755, | |||||
147804127, 537704286, 460110740, 596458323, 577775570, 333025386, 260094086, 711487611, 359384182, 323339045, 716675075, 248179763, 525311626, 76326208, 559009987, 548139736, | |||||
541721430, 31450329, 653923741, 676193285, 295171241, 558845563, 387079118, 403184480, 807941436, 501042343, 284608894, 705710380, 82388415, 763336555, 126077422, 438548854, | |||||
606252517, 144569238, 126964439, 809559381, 263253751, 547929033, 236704198, 377978058, 59501955, 749500335, 254242336, 605755194, 408388953, 116242711, 116340056, 691021496, | |||||
48100285, 371076069, 638156108, 211570763, 185945242, 653505761, 667569173, 335131755, 736662207, 572078378, 755939949, 840393623, 322934679, 520522390, 252068808, 491370519, | |||||
200565770, 552637112, 182345569, 394747039, 822229467, 817698102, 644484388, 156591766, 729600982, 695826242, 509682463, 785132583, 746139100, 188369785, 628995003, 406654440, | |||||
650660075, 676485042, 540766742, 493428142, 753346328, 82608613, 670846442, 145894970, 770907988, 621807160, 14676199, 793865193, 36579515, 619741404, 303691972, 794920577, | |||||
134684826, 190038753, 538889970, 836657477, 643017556, 316870164, 464572481, 305395359, 446406992, 587814221, 423552502, 122802120, 146043780, 173756097, 130720237, 445515559, | |||||
109884833, 133119099, 804139234, 834841519, 458514524, 74213698, 490363622, 119287122, 165016718, 351506713, 433750226, 439149867, 348281119, 319795826, 320785867, 446561207, | |||||
705678831, 714536161, 172299381, 552925586, 635421942, 851853231, 208071525, 142303096, 93164236, 207534795, 655906672, 558127940, 98870558, 388322132, 87475979, 835970665, | |||||
61996500, 298060757, 256194194, 563529863, 249184704, 451295997, 73892211, 559049908, 44006160, 832886345, 720732161, 255948582, 827295342, 629663637, 323103159, 155698755, | |||||
598913314, 586685341, 761273875, 135225209, 324099714, 391112815, 493469140, 796490769, 667498514, 148390126, 721802249, 781884558, 309264043, 603401759, 503111668, 563611748, | |||||
363342598, 383209405, 108340736, 758017880, 145907493, 312330194, 608895549, 45540348, 143092704, 772401556, 806068040, 853177536, 662120004, 463347842, 495085709, 560431884, | |||||
274002454, 76985308, 519320299, 253092838, 727478114, 593752634, 490277266, 206283832, 701277908, 504787112, 816832531, 730997507, 27807749, 58254704, 584933136, 515463756, | |||||
241104222, 251881934, 566567573, 592887586, 528932268, 88111104, 523103099, 448331392, 351083975, 157811347, 758866581, 802151021, 843579185, 481417280, 507414106, 462708367, | |||||
461501222, 790988186, 462220673, 727683888, 159759683, 59757110, 310746434, 326369241, 305829588, 457718309, 529317279, 503631310, 661769334, 343160359, 472216278, 740498212, | |||||
11312284, 760170115, 513391009, 538224236, 710934956, 491998229, 539829044, 610387964, 86624968, 72542777, 493966272, 132327984, 371526334, 182549152, 51622114, 173997077, | |||||
550633787, 205437301, 435219235, 406409162, 414751325, 33371226, 40899348, 77245052, 763383124, 817701136, 598256078, 357440859, 468418959, 353612800, 721601331, 262567156, | |||||
521577430, 232027892, 75986872, 443113391, 107360999, 482079354, 563502258, 782475535, 402866161, 515580626, 742688144, 677398836, 425899303, 42066550, 537192943, 430672016, | |||||
115368023, 64053241, 92008456, 74327791, 572607165, 681138002, 378104858, 695786430, 844827190, 436817825, 751393351, 142965259, 81300919, 688342617, 433082724, 221191094, | |||||
712003270, 301076404, 747091407, 514191589, 814985450, 260951422, 187161058, 22316970, 806106670, 759397054, 158423624, 419813636, 462241316, 438231460, 108466764, 212745115, | |||||
386264342, 176072326, 767127195, 399981627, 762991681, 173125691, 464627163, 770046798, 179369718, 829917528, 693004603, 178596003, 422852852, 182684967, 662425026, 713404098, | |||||
766206683, 130088738, 321282752, 134898541, 86701214, 120555423, 464987852, 82865891, 758340585, 138256323, 308997895, 659614345, 510091933, 822699180, 464631718, 819896232, | |||||
120792059, 160708255, 462868879, 72974246, 260451492, 120601343, 228097712, 369436704, 155304088, 74380537, 732305166, 203294189, 307421597, 96510570, 634243454, 486539430, | |||||
16204477, 241987531, 317824421, 510180366, 794475492, 262770124, 441034891, 741864347, 205569410, 684844547, 340863522, 440616421, 454438375, 26285496, 141886125, 648947081, | |||||
3791510, 529746935, 317826713, 411458050, 661690316, 45696331, 679684665, 184597094, 829228068, 375683582, 591739456, 855242340, 628594662, 30968619, 363932244, 103091463, | |||||
614269714, 465960778, 791477766, 332731888, 853151007, 266045534, 132189407, 435008168, 65667470, 669304246, 760035868, 481409581, 36650645, 523634336, 702968013, 351902214, | |||||
284360680, 34261165, 593134528, 337534074, 239112910, 710342799, 163287447, 20209506, 780785984, 480727309, 125776519, 691236193, 603228570, 48261672, 183120677, 73638683, | |||||
3430616, 568026489, 808739797, 298585898, 64471573, 724550960, 568093636, 187449517, 655699449, 672689645, 829049456, 263525899, 612969883, 621652807, 186362075, 731851539, | |||||
377104257, 39335761, 210768226, 253965025, 201921517, 715681274, 369453531, 18897741, 612559390, 660723864, 476963596, 585483298, 318614839, 227626072, 298891387, 110505944, | |||||
814885802, 177563961, 443724544, 374856237, 577963338, 617516835, 475669105, 633353115, 12579943, 796644307, 569746680, 22381253, 343603333, 724567543, 845363898, 4023795, | |||||
801359177, 347489967, 214644600, 78674056, 131782857, 284041623, 660502381, 161470286, 668158595, 765738294, 715872268, 678418089, 280458288, 758715787, 9311288, 490771912, | |||||
757112000, 253990619, 698573830, 390611635, 52593584, 421202448, 494394112, 386893540, 29349323, 533111491, 774401558, 108660117, 405990553, 143728136, 852741683, 354532633, | |||||
440222591, 663461253, 593338391, 298882952, 758170600, 660294062, 332348846, 541714172, 77716403, 169377728, 71932929, 110210904, 776771173, 645222398, 162195941, 792388932, | |||||
502165627, 146897021, 243625970, 139123400, 462352793, 409369440, 247509680, 270865496, 539140627, 16949766, 245869282, 637926655, 37386603, 383033875, 316560876, 707909555, | |||||
367315004, 173821041, 529529257, 227507318, 831716891, 830055847, 228911074, 205127100, 178872273, 819938491, 129875615, 764680417, 97028082, 560682982, 433649390, 727508847, | |||||
494848582, 81279272, 435186566, 174468080, 69172161, 241860102, 692179355, 333985572, 788895276, 469576414, 594155471, 157828532, 182105752, 310394758, 673085082, 695719789, | |||||
39004854, 251000641, 98748282, 744318650, 815050298, 622456803, 240419561, 403871914, 202214044, 627433637, 649505808, 668918393, 334630440, 386856024, 352649543, 135139523, | |||||
216499252, 736376783, 269223150, 468318208, 801808348, 180378366, 640086372, 672618369, 291378195, 732195369, 805632553, 518515631, 603280165, 629836417, 59712833, 531020081, | |||||
708771168, 539819295, 179149444, 552251927, 458994127, 584987693, 238644928, 640603619, 46728500, 843989005, 688747457, 236924093, 261539965, 705411056, 765907765, 38095657, | |||||
382461698, 146650814, 351462947, 749417520, 628887925, 800857475, 790554154, 695483946, 160495923, 40896482, 471385785, 535516195, 197056285, 622795937, 368016917, 696525353, | |||||
377315918, 58087122, 246518254, 431338589, 795949654, 611141265, 406307405, 365750089, 396243561, 843849531, 33802729, 573076974, 557841126, 411725124, 109489622, 370935707, | |||||
372610558, 769825999, 367932152, 231499145, 240819898, 22648665, 418344529, 142438794, 552806180, 669450690, 614608056, 784369586, 258710636, 474742428, 166021530, 805595815, | |||||
603578176, 686703780, 412868426, 26588048, 379895115, 77550061, 751188758, 294447541, 433574579, 234362222, 821492181, 23912038, 681093196, 483584545, 404339808, 396405029, | |||||
744756742, 702481685, 413127074, 204115019, 187381271, 633523978, 433629465, 628184183, 783160918, 268799033, 646479372, 160458176, 602612912, 644506365, 391554011, 676966578, | |||||
386430153, 98736426, 412745127, 296141927, 685909285, 355152260, 361415843, 127323093, 586337666, 1734791, 368678692, 155431915, 597290023, 109507713, 291804866, 135016081, | |||||
144077689, 35054937, 16808265, 431962815, 534195521, 629326143, 309352001, 319948849, 443083246, 336744161, 100845182, 314804947, 476736581, 468528479, 416978018, 35141019, | |||||
43314058, 384847955, 665126798, 295857628, 768013680, 741182796, 157855570, 695547618, 145251639, 818473396, 708640763, 87460130, 736400748, 465173936, 376720282, 437268868, | |||||
137236663, 693860377, 247960644, 402124416, 656418852, 231401654, 248187016, 628418583, 224261112, 120581342, 49749199, 588812480, 309599954, 111357387, 14507354, 754564049, | |||||
513444423, 816496110, 509193085, 361635970, 190608265, 697367838, 230953561, 140447357, 27745100, 163340427, 607823059, 325305463, 383028479, 269707244, 475022415, 708990989, | |||||
738971809, 797646021, 126610937, 589310701, 191123172, 819715815, 337443183, 432224976, 337343783, 257301390, 172631141, 560659319, 646332329, 55110483, 467212803, 442977895, | |||||
311159578, 569890333, 669396086, 536323022, 542648615, 366162176, 88951009, 408335586, 276237497, 384733042, 525960156, 74199534, 338209206, 676233089, 264342641, 241682204, | |||||
226505461, 165013960, 129858819, 664852498, 432090291, 165700308, 382150900, 537002255, 368893910, 61006155, 238726881, 92317627, 632392147, 404715651, 802622348, 126100061, | |||||
306024238, 397891265, 214661020, 211132870, 783722518, 149847645, 665379914, 624725195, 85864665, 496272723, 304811252, 29995710, 410500887, 756406394, 31206753, 647154006, | |||||
596539568, 783214792, 286381882, 24560691, 681500270, 774933112, 506538708, 850347997, 611696036, 512607061, 251719669, 367108021, 456442965, 636694730, 399940257, 73870039, | |||||
85190759, 264953709, 238854238, 395048514, 612738126, 27417876, 652695826, 188238483, 324168828, 736238139, 789061724, 529275445, 382304068, 176318391, 709989466, 14237691, | |||||
}; | |||||
const poly PQCLEAN_QTESLAPIII_CLEAN_zetainv = { | |||||
146156455, 679827530, 473841853, 326870476, 67084197, 119907782, 531977093, 667907438, 203450095, 828728045, 243407795, 461097407, 617291683, 591192212, 770955162, 782275882, | |||||
456205664, 219451191, 399702956, 489037900, 604426252, 343538860, 244449885, 5797924, 349607213, 81212809, 174645651, 831585230, 569764039, 72931129, 259606353, 208991915, | |||||
824939168, 99739527, 445645034, 826150211, 551334669, 359873198, 770281256, 231420726, 190766007, 706298276, 72423403, 645013051, 641484901, 458254656, 550121683, 730045860, | |||||
53523573, 451430270, 223753774, 763828294, 617419040, 795139766, 487252011, 319143666, 473995021, 690445613, 424055630, 191293423, 726287102, 691131961, 629640460, 614463717, | |||||
591803280, 179912832, 517936715, 781946387, 330185765, 471412879, 579908424, 447810335, 767194912, 489983745, 313497306, 319822899, 186749835, 286255588, 544986343, 413168026, | |||||
388933118, 801035438, 209813592, 295486602, 683514780, 598844531, 518802138, 423920945, 518702738, 36430106, 665022749, 266835220, 729534984, 58499900, 117174112, 147154932, | |||||
381123506, 586438677, 473117442, 530840458, 248322862, 692805494, 828400821, 715698564, 625192360, 158778083, 665537656, 494509951, 346952836, 39649811, 342701498, 101581872, | |||||
841638567, 744788534, 546545967, 267333441, 806396722, 735564579, 631884809, 227727338, 607958905, 624744267, 199727069, 454021505, 608185277, 162285544, 718909258, 418877053, | |||||
479425639, 390971985, 119745173, 768685791, 147505158, 37672525, 710894282, 160598303, 698290351, 114963125, 88132241, 560288293, 191019123, 471297966, 812831863, 821004902, | |||||
439167903, 387617442, 379409340, 541340974, 755300739, 519401760, 413062675, 536197072, 546793920, 226819778, 321950400, 424183106, 839337656, 821090984, 712068232, 721129840, | |||||
564341055, 746638208, 258855898, 700714006, 487467229, 854411130, 269808255, 728822828, 494730078, 500993661, 170236636, 560003994, 443400794, 757409495, 469715768, 179179343, | |||||
464591910, 211639556, 253533009, 695687745, 209666549, 587346888, 72985003, 227961738, 422516456, 222621943, 668764650, 652030902, 443018847, 153664236, 111389179, 459740892, | |||||
451806113, 372561376, 175052725, 832233883, 34653740, 621783699, 422571342, 561698380, 104957163, 778595860, 476250806, 829557873, 443277495, 169442141, 252567745, 50550106, | |||||
690124391, 381403493, 597435285, 71776335, 241537865, 186695231, 303339741, 713707127, 437801392, 833497256, 615326023, 624646776, 488213769, 86319922, 483535363, 485210214, | |||||
746656299, 444420797, 298304795, 283068947, 822343192, 12296390, 459902360, 490395832, 449838516, 245004656, 60196267, 424807332, 609627667, 798058799, 478830003, 159620568, | |||||
488129004, 233349984, 659089636, 320629726, 384760136, 815249439, 695649998, 160661975, 65591767, 55288446, 227257996, 106728401, 504682974, 709495107, 473684223, 818050264, | |||||
90238156, 150734865, 594605956, 619221828, 167398464, 12156916, 809417421, 215542302, 617500993, 271158228, 397151794, 303893994, 676996477, 316326626, 147374753, 325125840, | |||||
796433088, 226309504, 252865756, 337630290, 50513368, 123950552, 564767726, 183527552, 216059549, 675767555, 54337573, 387827713, 586922771, 119769138, 639646669, 721006398, | |||||
503496378, 469289897, 521515481, 187227528, 206640113, 228712284, 653931877, 452274007, 615726360, 233689118, 41095623, 111827271, 757397639, 605145280, 817141067, 160426132, | |||||
183060839, 545751163, 674040169, 698317389, 261990450, 386569507, 67250645, 522160349, 163966566, 614285819, 786973760, 681677841, 420959355, 774866649, 361297339, 128637074, | |||||
422496531, 295462939, 759117839, 91465504, 726270306, 36207430, 677273648, 651018821, 627234847, 26090074, 24429030, 628638603, 326616664, 682324880, 488830917, 148236366, | |||||
539585045, 473112046, 818759318, 218219266, 610276639, 839196155, 317005294, 585280425, 608636241, 446776481, 393793128, 717022521, 612519951, 709248900, 353980294, 63756989, | |||||
693949980, 210923523, 79374748, 745935017, 784212992, 686768193, 778429518, 314431749, 523797075, 195851859, 97975321, 557262969, 262807530, 192684668, 415923330, 501613288, | |||||
3404238, 712417785, 450155368, 747485804, 81744363, 323034430, 826796598, 469252381, 361751809, 434943473, 803552337, 465534286, 157572091, 602155302, 99033921, 365374009, | |||||
846834633, 97430134, 575687633, 177727832, 140273653, 90407627, 187987326, 694675635, 195643540, 572104298, 724363064, 777471865, 641501321, 508655954, 54786744, 852122126, | |||||
10782023, 131578378, 512542588, 833764668, 286399241, 59501614, 843565978, 222792806, 380476816, 238629086, 278182583, 481289684, 412421377, 678581960, 41260119, 745639977, | |||||
557254534, 628519849, 537531082, 270662623, 379182325, 195422057, 243586531, 837248180, 486692390, 140464647, 654224404, 602180896, 645377695, 816810160, 479041664, 124294382, | |||||
669783846, 234493114, 243176038, 592620022, 27096465, 183456276, 200446472, 668696404, 288052285, 131594961, 791674348, 557560023, 47406124, 288119432, 852715305, 782507238, | |||||
673025244, 807884249, 252917351, 164909728, 730369402, 375418612, 75359937, 835936415, 692858474, 145803122, 617033011, 518611847, 263011393, 821884756, 571785241, 504243707, | |||||
153177908, 332511585, 819495276, 374736340, 96110053, 186841675, 790478451, 421137753, 723956514, 590100387, 2994914, 523414033, 64668155, 390185143, 241876207, 753054458, | |||||
492213677, 825177302, 227551259, 903581, 264406465, 480462339, 26917853, 671548827, 176461256, 810449590, 194455605, 444687871, 538319208, 326398986, 852354411, 207198840, | |||||
714259796, 829860425, 401707546, 415529500, 515282399, 171301374, 650576511, 114281574, 415111030, 593375797, 61670429, 345965555, 538321500, 614158390, 839941444, 369606491, | |||||
221902467, 759635351, 548724324, 652851732, 123840755, 781765384, 700841833, 486709217, 628048209, 735544578, 595694429, 783171675, 393277042, 695437666, 735353862, 36249689, | |||||
391514203, 33446741, 346053988, 196531576, 547148026, 717889598, 97805336, 773280030, 391158069, 735590498, 769444707, 721247380, 534863169, 726057183, 89939238, 142741823, | |||||
193720895, 673460954, 433293069, 677549918, 163141318, 26228393, 676776203, 86099123, 391518758, 683020230, 93154240, 456164294, 89018726, 680073595, 469881579, 643400806, | |||||
747679157, 417914461, 393904605, 436332285, 697722297, 96748867, 50039251, 833828951, 668984863, 595194499, 41160471, 341954332, 109054514, 555069517, 144142651, 634954827, | |||||
423063197, 167803304, 774845002, 713180662, 104752570, 419328096, 11318731, 160359491, 478041063, 175007919, 283538756, 781818130, 764137465, 792092680, 740777898, 425473905, | |||||
318952978, 814079371, 430246618, 178747085, 113457777, 340565295, 453279760, 73670386, 292643663, 374066567, 748784922, 413032530, 780159049, 624118029, 334568491, 593578765, | |||||
134544590, 502533121, 387726962, 498705062, 257889843, 38444785, 92762797, 778900869, 815246573, 822774695, 441394596, 449736759, 420926686, 650708620, 305512134, 682148844, | |||||
804523807, 673596769, 484619587, 723817937, 362179649, 783603144, 769520953, 245757957, 316316877, 364147692, 145210965, 317921685, 342754912, 95975806, 844833637, 115647709, | |||||
383929643, 512985562, 194376587, 352514611, 326828642, 398427612, 550316333, 529776680, 545399487, 796388811, 696386238, 128462033, 393925248, 65157735, 394644699, 393437554, | |||||
348731815, 374728641, 12566736, 53994900, 97279340, 698334574, 505061946, 407814529, 333042822, 768034817, 327213653, 263258335, 289578348, 604263987, 615041699, 340682165, | |||||
271212785, 797891217, 828338172, 125148414, 39313390, 351358809, 154868013, 649862089, 365868655, 262393287, 128667807, 603053083, 336825622, 779160613, 582143467, 295714037, | |||||
361060212, 392798079, 194025917, 2968385, 50077881, 83744365, 713053217, 810605573, 247250372, 543815727, 710238428, 98128041, 747805185, 472936516, 492803323, 292534173, | |||||
353034253, 252744162, 546881878, 74261363, 134343672, 707755795, 188647407, 59655152, 362676781, 465033106, 532046207, 720920712, 94872046, 269460580, 257232607, 700447166, | |||||
533042762, 226482284, 28850579, 600197339, 135413760, 23259576, 812139761, 297096013, 782253710, 404849924, 606961217, 292616058, 599951727, 558085164, 794149421, 20175256, | |||||
768669942, 467823789, 757275363, 298017981, 200239249, 648611126, 762981685, 713842825, 648074396, 4292690, 220723979, 303220335, 683846540, 141609760, 150467090, 409584714, | |||||
535360054, 536350095, 507864802, 416996054, 422395695, 504639208, 691129203, 736858799, 365782299, 781932223, 397631397, 21304402, 52006687, 723026822, 746261088, 410630362, | |||||
725425684, 682389824, 710102141, 733343801, 432593419, 268331700, 409738929, 550750562, 391573440, 539275757, 213128365, 19488444, 317255951, 666107168, 721461095, 61225344, | |||||
552453949, 236404517, 819566406, 62280728, 841469722, 234338761, 85237933, 710250951, 185299479, 773537308, 102799593, 362717779, 315379179, 179660879, 205485846, 449491481, | |||||
227150918, 667776136, 110006821, 71013338, 346463458, 160319679, 126544939, 699554155, 211661533, 38447819, 33916454, 461398882, 673800352, 303508809, 655580151, 364775402, | |||||
604077113, 335623531, 533211242, 15752298, 100205972, 284067543, 119483714, 521014166, 188576748, 202640160, 670200679, 644575158, 217989813, 485069852, 808045636, 165124425, | |||||
739805865, 739903210, 447756968, 250390727, 601903585, 106645586, 796643966, 478167863, 619441723, 308216888, 592892170, 46586540, 729181482, 711576683, 249893404, 417597067, | |||||
730068499, 92809366, 773757506, 150435541, 571537027, 355103578, 48204485, 452961441, 469066803, 297300358, 560974680, 179952636, 202222180, 824695592, 314424491, 308006185, | |||||
297135934, 779819713, 330834295, 607966158, 139470846, 532806876, 496761739, 144658310, 596051835, 523120535, 278370351, 259687598, 396035181, 318441635, 708341794, 261702166, | |||||
96131132, 562196508, 712552283, 121414502, 139181388, 369274231, 188501611, 591747839, 321238361, 800859904, 483293761, 574521237, 318624730, 451184298, 845303892, 824439814, | |||||
513057916, 488248363, 110823008, 474732383, 469456681, 693990629, 824427131, 100906910, 393033981, 613525172, 780573584, 732240054, 662144127, 156900476, 412266288, 762627793, | |||||
55879529, 662447594, 435100580, 334994905, 345348008, 216291111, 115536138, 354908192, 480736673, 347619959, 213042018, 132255342, 192070634, 196227843, 171656829, 457430277, | |||||
456173657, 235184482, 708639607, 80162055, 78550737, 659824274, 145948236, 14732004, 377312541, 551950153, 807387365, 517885521, 536344534, 144062333, 788152134, 12135251, | |||||
342084445, 121817512, 115642280, 147002280, 138875114, 74245619, 95327390, 646649415, 207948635, 518439532, 33183835, 74137806, 802754590, 326978677, 329330108, 541984162, | |||||
615015895, 340312953, 218073212, 814998766, 157716436, 203155225, 214901690, 385807168, 392276620, 170965976, 458479761, 35398460, 134705722, 309083692, 60435010, 846143590, | |||||
745522807, 606438974, 750326300, 746569701, 117316274, 717210198, 601189495, 52499415, 136915847, 255901848, 12306030, 304281576, 765340988, 142286353, 789909728, 103773804, | |||||
49871665, 592012809, 266996441, 65625212, 81727898, 594201480, 200644793, 452686638, 43973291, 532301993, 739336488, 682224565, 845517209, 427753763, 474414446, 386025969, | |||||
96949342, 759705038, 589678515, 780837334, 158063634, 325974167, 809607430, 589067353, 176830058, 410812375, 382294428, 258796598, 468141533, 703441408, 673473968, 642305805, | |||||
218673395, 535461624, 674684956, 680203874, 846088654, 52914042, 758979987, 589962189, 325345164, 117477831, 120913707, 782220389, 60703501, 614017575, 99993130, 235368093, | |||||
644276216, 121149740, 315046926, 183533385, 13034140, 721604492, 242970774, 500232976, 316143635, 719601853, 411832633, 206849167, 62309503, 362143540, 172132792, 406642102, | |||||
290947418, 649997984, 400004941, 193289674, 20215276, 604047240, 792504507, 354704972, 661308027, 710569578, 67988066, 573986043, 298011050, 675020897, 371173377, 220311134, | |||||
234250033, 627878145, 805292463, 24071270, 648507616, 814745610, 517644997, 691772925, 511004739, 433787663, 788161195, 196473632, 362036173, 528196877, 697880168, 318651435, | |||||
223922625, 432332761, 605658712, 402713163, 12043466, 723222719, 197191480, 740372189, 835875906, 689010272, 292485650, 101464751, 764616290, 665830492, 830680702, 522703957, | |||||
36639665, 178661761, 847563520, 213367890, 580759073, 795883933, 189665782, 410128628, 104008441, 757987331, 543934116, 420541294, 396733102, 773554582, 422990463, 679308804, | |||||
471610475, 449025573, 293585715, 304333306, 606221987, 668107507, 201587373, 776461576, 54202261, 334132687, 570371370, 729669465, 388035450, 40739162, 294599466, 269999181, | |||||
368420277, 394723115, 506277838, 351687671, 683668119, 82918314, 72721076, 702889204, 841003831, 721904142, 691037495, 575492049, 221172299, 608377016, 584007171, 674474012, | |||||
135083989, 479195654, 408808739, 442284285, 530250590, 390248853, 461685089, 283253906, 717741307, 215568024, 562986577, 134817130, 147002383, 270825931, 379404006, 759183054, | |||||
581866917, 146566613, 784989241, 457129596, 59158644, 750640670, 700398504, 721509487, 402874366, 82387404, 95739856, 281346626, 467686791, 324137743, 11249127, 89157220, | |||||
716002070, 335342053, 246826170, 529385048, 760143990, 10725758, 516293110, 76538324, 257296477, 328165824, 172330118, 546825765, 619673906, 328792017, 788124094, 141927682, | |||||
555365723, 329427916, 607839982, 405389708, 571868667, 470002428, 684585751, 434604631, 204705039, 450529242, 361817407, 727855567, 413589322, 11544453, 803784599, 815775166, | |||||
425469974, 86512573, 86029713, 852702639, 728364190, 118324485, 477615251, 345426513, 219927860, 22417298, 480050287, 224592838, 759159, 131898579, 764335555, 457432197, | |||||
763875505, 642888584, 590641758, 210009158, 390019414, 235949401, 58219618, 562286114, 99631682, 631925366, 753164064, 328774959, 365242602, 385354452, 217542778, 795464774, | |||||
780632705, 678141873, 424450214, 25338472, 268284342, 493213958, 580867867, 15482483, 272837023, 328359708, 782291772, 308114267, 404813197, 333753982, 737682027, 538312006, | |||||
707909990, 234156623, 323140190, 803917719, 91035383, 200098402, 773260410, 554209269, 505977196, 258732217, 577347247, 388868026, 412079442, 312571314, 628683299, 740119334, | |||||
813470861, 86544483, 515146109, 371343866, 687853001, 265823977, 121589622, 808348288, 257353942, 635427508, 834922294, 224797491, 432675367, 731353224, 575538372, 642351606, | |||||
291366364, 210732817, 90658793, 146401688, 40748954, 527574284, 817614743, 547167333, 534136352, 372456076, 706600074, 640500788, 559786839, 845776458, 709348802, 677707036, | |||||
606711824, 349565805, 42095011, 472115432, 177053484, 681164976, 139728272, 510212596, 747795405, 441873933, 187174498, 392929945, 425171378, 555237229, 4315335, 9057268, | |||||
153360848, 99426909, 774527252, 83014618, 412368218, 3495282, 739674290, 826674363, 316599527, 110724402, 435058302, 156418860, 545209527, 681526436, 443190082, 613052844, | |||||
463370538, 710824143, 207309740, 783222241, 141846134, 266325996, 146201876, 449154790, 170683627, 716235176, 607164090, 291006513, 186310404, 43734965, 496486286, 736873833, | |||||
329899967, 408796174, 449053875, 589454563, 727957502, 460484783, 122169115, 75292611, 73671599, 848010384, 303936940, 791662107, 590932920, 125786858, 211282605, 729648214, | |||||
59156462, 152461927, 219894477, 776823847, 437757228, 186542194, 700611431, 257929382, 767315412, 18312688, 806906190, 504497667, 101165190, 603435510, 526872520, 254322283, | |||||
720021990, 779194394, 584710319, 801191565, 703649817, 361258161, 149741435, 808495563, 291596204, 250916275, 340042453, 141837377, 547502361, 181348702, 139498738, 338114582, | |||||
119328746, 177984134, 199957575, 358181386, 57332620, 512567111, 451958433, 156026128, 619998073, 307816265, 338764588, 65822147, 573828018, 487154809, 749222428, 522943099, | |||||
26336097, 186644498, 526288314, 534618890, 828269735, 675600958, 49788769, 453731878, 762637295, 387744335, 173171058, 33040483, 466949551, 843388255, 697432416, 216291746, | |||||
33282177, 240642656, 663436347, 390123214, 254438583, 190922896, 455331923, 296664914, 762697018, 331531324, 851176113, 771233913, 482330259, 389665212, 474944010, 58762628, | |||||
469089651, 436049255, 697216430, 431783325, 138107147, 499492245, 647224366, 407794272, 26067376, 445177552, 520720342, 798948406, 325365361, 117634101, 664099671, 153294810, | |||||
597801361, 640257687, 533951825, 702134729, 111685295, 685214097, 452013666, 317534558, 271219665, 529108611, 586379543, 355661610, 759841823, 446485943, 839034731, 33604088, | |||||
773212146, 191869702, 367354365, 689096322, 345311446, 438596834, 677372537, 542545550, 341130619, 292644024, 281192613, 251893811, 447792713, 520181371, 40921126, 778878825, | |||||
536838039, 230752698, 396625895, 601216134, 188488092, 130103565, 504870771, 413838340, 335573256, 124340986, 368340993, 243753204, 150144590, 808689996, 32468801, 68817331, | |||||
471378712, 566347573, 6430376, 651137151, 497752158, 823732827, 787280015, 789046852, 194658966, 171151811, 118113814, 793917550, 75187158, 717603845, 61671631, 51620383, | |||||
302490719, 78328345, 244847301, 549511806, 420356371, 560795789, 405546061, 302036596, 432306081, 270856136, 330554928, 212724399, 791196206, 445342723, 187781362, 87078067, | |||||
834667388, 218628624, 755629702, 148790011, 845609309, 89984158, 742118272, 475309628, 81731129, 107846408, 74447254, 68656823, 169459843, 643648059, 721924181, 212112779, | |||||
575076242, 471039705, 626114838, 564548835, 506450263, 488329877, 847101683, 592828368, 714089721, 832868261, 393063639, 603199595, 214221357, 747808090, 145225511, 784491117, | |||||
578386518, 253504617, 217256612, 432640963, 696210495, 700338942, 642132261, 394125773, 127189460, 622643989, 65557316, 850423288, 154198317, 360118020, 401298167, 809808378, | |||||
590060278, 378333119, 261388063, 301240958, 211172470, 476577014, 818999735, 320797504, 155490801, 362021897, 416507223, 193972866, 814253796, 555879930, 152626252, 598011677, | |||||
48971665, 590814257, 699100720, 732535868, 42427027, 335391594, 577502901, 72445917, 562054823, 34689534, 850274973, 640356274, 165636151, 309704599, 39996866, 436255023, | |||||
365085534, 208984696, 593049885, 755419039, 376895434, 634901252, 316743954, 476563344, 619551824, 766199910, 783651060, 32670169, 794822305, 435248113, 14247580, 284417137, | |||||
754554090, 30678221, 641072629, 711946716, 568640914, 656468482, 83597913, 356324101, 231391682, 122476642, 505437404, 636148283, 639556222, 262242870, 10083895, 470763095, | |||||
7162643, 490677454, 122627583, 711718981, 252376484, 423795716, 578101600, 275970963, 3053131, 327430341, 435804223, 349044314, 649311691, 234207954, 379806804, 342513855, | |||||
224624649, 181857560, 84797030, 123047825, 95186646, 293471117, 586961654, 111168138, 703259490, 756871363, 606284506, 380213718, 292725815, 463763080, 747629289, 254624782, | |||||
207883602, 849297083, 578506664, 656289117, 454015629, 162235991, 474249177, 633829447, 490767799, 210190430, 48735841, 656982789, 743473215, 47313566, 306689440, 53334547, | |||||
370344121, 419993940, 218969756, 341956367, 296184959, 135682817, 127205066, 744169001, 445909513, 801533404, 605661030, 181244618, 30772614, 196639386, 59911722, 616623643, | |||||
199307436, 551535136, 136575017, 79424355, 92705102, 498046224, 17339996, 698541762, 804348245, 104258042, 484400476, 535014225, 87644978, 121726462, 383782353, 77562877, | |||||
350468417, 724994239, 772938366, 320269449, 203075846, 465307490, 585234251, 271855066, 464423241, 403123130, 202162074, 117126999, 653413020, 8084225, 216658351, 409614891, | |||||
799241223, 600931579, 454131285, 782741932, 376344215, 79696641, 803438191, 565030050, 460657460, 5110534, 472517130, 76991417, 572426425, 92047134, 285371277, 843473400, | |||||
389338704, 704515255, 459914006, 657120075, 708563883, 78813141, 11770883, 688134435, 287808573, 649280542, 765338883, 439803770, 160535862, 617753423, 442051682, 288864924, | |||||
32955626, 326880188, 696887038, 215124062, 791918307, 767157413, 358676037, 30612492, 661971023, 838968782, 465224708, 784600829, 146985424, 799718881, 207906900, 340800263, | |||||
849693954, 44777992, 31326149, 240259940, 508401593, 499528021, 475930852, 690672059, 580019353, 297040464, 236338202, 454171188, 695134912, 508172471, 436504159, 293630619, | |||||
848875161, 37043893, 26993038, 396046068, 722016462, 445419380, 209243403, 503786686, 268117854, 281672598, 205034970, 87894257, 293598267, 46912651, 147959859, 462629641, | |||||
509044664, 700768221, 107374762, 340721447, 163551982, 247501118, 447395984, 318219025, 172114399, 110025830, 810265637, 370215004, 606303954, 462642711, 251114029, 290800715, | |||||
780017258, 789443137, 495480307, 615909633, 431756150, 766376396, 820732666, 686803688, 133668454, 761665150, 326017339, 424112204, 110554261, 386347465, 101066781, 135666139, | |||||
256882780, 205722545, 668032392, 405718561, 350327055, 621444438, 381307379, 421184831, 753121128, 590538618, 366906511, 345326178, 132085192, 40531091, 780676557, 586664955, | |||||
597888984, 693668509, 487104387, 234747974, 572624063, 114516856, 550027276, 316481563, 239535126, 788436714, 847219527, 113421825, 200615887, 815912760, 581164384, 191193216, | |||||
11551938, 606832431, 431210833, 196126697, 92508342, 270544041, 192437514, 99153842, 188585579, 413385580, 745267475, 448172363, 667109106, 85272138, 658601344, 443173146, | |||||
392530856, 589073317, 382995167, 248915715, 375600977, 386782401, 254322056, 790853708, 580714915, 163129486, 824017519, 86419559, 117205367, 634667017, 566451589, 852749522, | |||||
837490424, 330422330, 294598189, 814909626, 505390042, 125578715, 357313675, 450539487, 233746299, 446282749, 755039478, 740350430, 598956163, 116099139, 167482754, 310512355, | |||||
135624781, 470874939, 196356683, 239902897, 693520220, 454942578, 778240578, 45236161, 51101673, 270126615, 94622194, 524282161, 632376971, 703121383, 587013336, 572429454, | |||||
37728898, 143682359, 206045437, 557167425, 770459696, 477771773, 321346425, 290390778, 100874902, 758540246, 746805823, 459566327, 607673901, 158286491, 527010720, 579461268, | |||||
74963118, 420964844, 51316958, 250512679, 452729483, 35670488, 559935164, 734294507, 379228497, 172592106, 126508187, 757555710, 853874620, 808517874, 106015915, 375691866, | |||||
423413164, 423111661, 60250078, 645353691, 853830811, 288310932, 1489804, 127886925, 191505834, 459549138, 542519706, 369115379, 116842790, 784888677, 269818678, 712117130, | |||||
748410048, 139982101, 169805525, 32264681, 532400632, 397389041, 181262233, 703428567, 604760852, 44143128, 69914527, 86615396, 314810965, 68145528, 650868687, 717671367, | |||||
594246701, 641155397, 207406129, 180083553, 414651973, 132523243, 211350471, 397371331, 170688638, 732763563, 132155217, 394688247, 571356350, 93856418, 708831649, 841908230, | |||||
}; | |||||
@@ -0,0 +1,44 @@ | |||||
/************************************************************************************* | |||||
* qTESLA: an efficient post-quantum signature scheme based on the R-LWE problem | |||||
* | |||||
* Abstract: portable, constant-time Gaussian sampler | |||||
**************************************************************************************/ | |||||
#include "api.h" | |||||
#include "CDT32.h" | |||||
#include "gauss.h" | |||||
#include "sp800-185.h" | |||||
#include <string.h> | |||||
void PQCLEAN_QTESLAPIII_CLEAN_sample_gauss_poly(poly z, const uint8_t *seed, uint16_t nonce) { | |||||
uint16_t dmsp = (uint16_t)(nonce << 8); | |||||
int32_t samp[CHUNK_SIZE * CDT_COLS], c[CDT_COLS], borrow, sign; | |||||
const int32_t mask = (int32_t)((uint32_t)(-1) >> 1); | |||||
uint8_t buf[CHUNK_SIZE * CDT_COLS * sizeof(int32_t)]; | |||||
for (size_t chunk = 0; chunk < PARAM_N; chunk += CHUNK_SIZE) { | |||||
uint8_t dmsp_bytes[2]; | |||||
dmsp_bytes[0] = (uint8_t)(dmsp & 0xff); | |||||
dmsp_bytes[1] = (uint8_t)(dmsp >> 8); | |||||
cSHAKE(buf, CHUNK_SIZE * CDT_COLS * sizeof(int32_t), (uint8_t *)NULL, 0, dmsp_bytes, 2, seed, CRYPTO_RANDOMBYTES); | |||||
++dmsp; | |||||
for (size_t i = 0, j = 0; i < CHUNK_SIZE * CDT_COLS; i += 1, j += 4) { | |||||
samp[i] = (int32_t)(buf[j] | (buf[j + 1] << 8) | (buf[j + 2] << 16) | (buf[j + 3] << 24)); | |||||
} | |||||
for (size_t i = 0; i < CHUNK_SIZE; i++) { | |||||
z[chunk + i] = 0; | |||||
for (size_t j = 1; j < CDT_ROWS; j++) { | |||||
borrow = 0; | |||||
for (size_t k = CDT_COLS; k > 0; ) { | |||||
k--; | |||||
c[k] = (samp[i * CDT_COLS + k] & mask) - (cdt_v[j * CDT_COLS + k] + borrow); | |||||
borrow = c[k] >> (RADIX32 - 1); | |||||
} | |||||
z[chunk + i] += ~borrow & 1; | |||||
} | |||||
sign = samp[i * CDT_COLS] >> (RADIX32 - 1); | |||||
z[chunk + i] = (sign & -z[chunk + i]) | (~sign & z[chunk + i]); | |||||
} | |||||
} | |||||
} | |||||
@@ -0,0 +1,13 @@ | |||||
#ifndef PQCLEAN_QTESLAPIII_CLEAN_GAUSS_H | |||||
#define PQCLEAN_QTESLAPIII_CLEAN_GAUSS_H | |||||
#include "config.h" | |||||
#include "params.h" | |||||
#include "poly.h" | |||||
#include <stdint.h> | |||||
#define CHUNK_SIZE 512 // Fix chunk size for sampling | |||||
void PQCLEAN_QTESLAPIII_CLEAN_sample_gauss_poly(poly z, const uint8_t *seed, uint16_t nonce); | |||||
#endif |
@@ -0,0 +1,108 @@ | |||||
/************************************************************************************* | |||||
* qTESLA: an efficient post-quantum signature scheme based on the R-LWE problem | |||||
* | |||||
* Abstract: packing functions | |||||
**************************************************************************************/ | |||||
#include "api.h" | |||||
#include "pack.h" | |||||
#include "params.h" | |||||
#include "poly.h" | |||||
#include <string.h> | |||||
void PQCLEAN_QTESLAPIII_CLEAN_pack_sk(uint8_t *sk, const poly s, const poly_k e, uint8_t *seeds) { | |||||
// Pack secret key sk | |||||
size_t i, k; | |||||
for (i = 0; i < PARAM_N; i++) { | |||||
sk[i] = (uint8_t)s[i]; | |||||
} | |||||
sk += PARAM_N; | |||||
for (k = 0; k < PARAM_K; k++) { | |||||
for (i = 0; i < PARAM_N; i++) { | |||||
sk[k * PARAM_N + i] = (uint8_t)e[k * PARAM_N + i]; | |||||
} | |||||
} | |||||
memcpy(&sk[PARAM_K * PARAM_N], seeds, 2 * CRYPTO_SEEDBYTES); | |||||
} | |||||
void PQCLEAN_QTESLAPIII_CLEAN_encode_pk(uint8_t *pk, const poly_k t, const uint8_t *seedA) { | |||||
// Encode public key pk | |||||
size_t i, j; | |||||
for (i = 0, j = 0; i < PARAM_N * PARAM_K; i += 4, j += 15) { | |||||
pk[j ] = (uint8_t)( t[i ] ); | |||||
pk[j + 1] = (uint8_t)( t[i ] >> 8 ); | |||||
pk[j + 2] = (uint8_t)( t[i ] >> 16 ); | |||||
pk[j + 3] = (uint8_t)((t[i ] >> 24) | (t[i + 1] << 6)); | |||||
pk[j + 4] = (uint8_t)( t[i + 1] >> 2 ); | |||||
pk[j + 5] = (uint8_t)( t[i + 1] >> 10 ); | |||||
pk[j + 6] = (uint8_t)( t[i + 1] >> 18 ); | |||||
pk[j + 7] = (uint8_t)((t[i + 1] >> 26) | (t[i + 2] << 4)); | |||||
pk[j + 8] = (uint8_t)( t[i + 2] >> 4 ); | |||||
pk[j + 9] = (uint8_t)( t[i + 2] >> 12 ); | |||||
pk[j + 10] = (uint8_t)( t[i + 2] >> 20 ); | |||||
pk[j + 11] = (uint8_t)((t[i + 2] >> 28) | (t[i + 3] << 2)); | |||||
pk[j + 12] = (uint8_t)( t[i + 3] >> 6 ); | |||||
pk[j + 13] = (uint8_t)( t[i + 3] >> 14 ); | |||||
pk[j + 14] = (uint8_t)( t[i + 3] >> 22 ); | |||||
} | |||||
memcpy(&pk[j], seedA, CRYPTO_SEEDBYTES); | |||||
} | |||||
void PQCLEAN_QTESLAPIII_CLEAN_decode_pk(int32_t *pk, uint8_t *seedA, const uint8_t *pk_in) { | |||||
// Decode public key pk | |||||
size_t i, j; | |||||
int32_t mask30 = (1 << PARAM_Q_LOG) - 1; | |||||
const uint8_t *a = pk_in; | |||||
for (i = 0, j = 0; i < PARAM_N * PARAM_K; i += 4, j += 15) { | |||||
pk[i ] = (int32_t)(( a[j ] | (a[j + 1] << 8) | (a[j + 2] << 16) | (a[j + 3] << 24) ) & mask30); | |||||
pk[i + 1] = (int32_t)(((a[j + 3] >> 6) | (a[j + 4] << 2) | (a[j + 5] << 10) | (a[j + 6] << 18) | (a[j + 7] << 26)) & mask30); | |||||
pk[i + 2] = (int32_t)(((a[j + 7] >> 4) | (a[j + 8] << 4) | (a[j + 9] << 12) | (a[j + 10] << 20) | (a[j + 11] << 28)) & mask30); | |||||
pk[i + 3] = (int32_t)( (a[j + 11] >> 2) | (a[j + 12] << 6) | (a[j + 13] << 14) | (a[j + 14] << 22) ); | |||||
} | |||||
memcpy(seedA, &pk_in[j], CRYPTO_SEEDBYTES); | |||||
} | |||||
void PQCLEAN_QTESLAPIII_CLEAN_encode_sig(uint8_t *sm, uint8_t *c, const poly z) { | |||||
// Encode signature sm | |||||
size_t i, j; | |||||
for (i = 0, j = 0; i < PARAM_N; i += 4, j += 11) { | |||||
sm[j ] = (uint8_t)( z[i ] ); | |||||
sm[j + 1] = (uint8_t)( z[i ] >> 8); | |||||
sm[j + 2] = (uint8_t)(((z[i ] >> 16) & 0x3F) | (z[i + 1] << 6)); | |||||
sm[j + 3] = (uint8_t)( z[i + 1] >> 2); | |||||
sm[j + 4] = (uint8_t)( z[i + 1] >> 10); | |||||
sm[j + 5] = (uint8_t)(((z[i + 1] >> 18) & 0x0F) | (z[i + 2] << 4)); | |||||
sm[j + 6] = (uint8_t)( z[i + 2] >> 4); | |||||
sm[j + 7] = (uint8_t)( z[i + 2] >> 12); | |||||
sm[j + 8] = (uint8_t)(((z[i + 2] >> 20) & 0x03) | (z[i + 3] << 2)); | |||||
sm[j + 9] = (uint8_t)( z[i + 3] >> 6); | |||||
sm[j + 10] = (uint8_t)( z[i + 3] >> 14); | |||||
} | |||||
memcpy(&sm[j], c, CRYPTO_C_BYTES); | |||||
} | |||||
void PQCLEAN_QTESLAPIII_CLEAN_decode_sig(uint8_t *c, poly z, const uint8_t *sm) { | |||||
// Decode signature sm | |||||
size_t i, j; | |||||
for (i = 0, j = 0; i < PARAM_N; i += 4, j += 11) { | |||||
z[i ] = sm[j ] | (sm[j + 1] << 8) | (((int64_t)sm[j + 2] << 58) >> 42); | |||||
z[i + 1] = (sm[j + 2] >> 6) | (sm[j + 3] << 2) | (sm[j + 4] << 10) | (((int64_t)sm[j + 5] << 60) >> 42); | |||||
z[i + 2] = (sm[j + 5] >> 4) | (sm[j + 6] << 4) | (sm[j + 7] << 12) | (((int64_t)sm[j + 8] << 62) >> 42); | |||||
z[i + 3] = (sm[j + 8] >> 2) | (sm[j + 9] << 6) | (((int64_t)sm[j + 10] << 56) >> 42); | |||||
} | |||||
memcpy(c, &sm[j], CRYPTO_C_BYTES); | |||||
} |
@@ -0,0 +1,13 @@ | |||||
#ifndef PQCLEAN_QTESLAPIII_CLEAN_PACK_H | |||||
#define PQCLEAN_QTESLAPIII_CLEAN_PACK_H | |||||
#include "poly.h" | |||||
#include <stdint.h> | |||||
void PQCLEAN_QTESLAPIII_CLEAN_pack_sk(uint8_t *sk, const poly s, const poly_k e, uint8_t *seeds); | |||||
void PQCLEAN_QTESLAPIII_CLEAN_encode_pk(uint8_t *pk, const poly_k t, const uint8_t *seedA); | |||||
void PQCLEAN_QTESLAPIII_CLEAN_decode_pk(int32_t *pk, uint8_t *seedA, const uint8_t *pk_in); | |||||
void PQCLEAN_QTESLAPIII_CLEAN_encode_sig(uint8_t *sm, uint8_t *c, const poly z); | |||||
void PQCLEAN_QTESLAPIII_CLEAN_decode_sig(uint8_t *c, poly z, const uint8_t *sm); | |||||
#endif |
@@ -0,0 +1,42 @@ | |||||
#ifndef PQCLEAN_QTESLAPIII_CLEAN_PARAMS_H | |||||
#define PQCLEAN_QTESLAPIII_CLEAN_PARAMS_H | |||||
/************************************************************************************* | |||||
* qTESLA: an efficient post-quantum signature scheme based on the R-LWE problem | |||||
* | |||||
* Abstract: provably-secure qTESLA parameters | |||||
**************************************************************************************/ | |||||
#define PARAM_N 2048 | |||||
#define PARAM_N_LOG 11 | |||||
#define PARAM_SIGMA 8.5 | |||||
#define PARAM_Q 856145921 | |||||
#define PARAM_Q_LOG 30 | |||||
#define PARAM_QINV 587710463 | |||||
#define PARAM_BARR_MULT 5 | |||||
#define PARAM_BARR_DIV 32 | |||||
#define PARAM_B 2097151 | |||||
#define PARAM_B_BITS 21 | |||||
#define PARAM_S_BITS 8 | |||||
#define PARAM_K 5 | |||||
#define PARAM_SIGMA_E PARAM_SIGMA | |||||
#define PARAM_H 40 | |||||
#define PARAM_D 24 | |||||
#define PARAM_GEN_A 180 | |||||
#define PARAM_KEYGEN_BOUND_E 901 | |||||
#define PARAM_E PARAM_KEYGEN_BOUND_E | |||||
#define PARAM_KEYGEN_BOUND_S 901 | |||||
#define PARAM_S PARAM_KEYGEN_BOUND_S | |||||
#define PARAM_R2_INVN 513161157 | |||||
#define PARAM_R 14237691 | |||||
#define SHAKE shake256 | |||||
#define cSHAKE cshake256 | |||||
#define SHAKE_RATE SHAKE256_RATE | |||||
#define CRYPTO_RANDOMBYTES 32 | |||||
#define CRYPTO_SEEDBYTES 32 | |||||
#define CRYPTO_C_BYTES 32 | |||||
#define HM_BYTES 64 | |||||
#endif |
@@ -0,0 +1,246 @@ | |||||
/************************************************************************************* | |||||
* qTESLA: an efficient post-quantum signature scheme based on the R-LWE problem | |||||
* | |||||
* Abstract: NTT, modular reduction and polynomial functions | |||||
**************************************************************************************/ | |||||
#include "api.h" | |||||
#include "poly.h" | |||||
#include "sp800-185.h" | |||||
extern const poly PQCLEAN_QTESLAPIII_CLEAN_zeta; | |||||
extern const poly PQCLEAN_QTESLAPIII_CLEAN_zetainv; | |||||
static int64_t reduce(int64_t a) { | |||||
// Montgomery reduction | |||||
int64_t u; | |||||
u = ((uint64_t)a * PARAM_QINV) & 0xFFFFFFFF; | |||||
u *= PARAM_Q; | |||||
a += u; | |||||
return a >> 32; | |||||
} | |||||
static int64_t barr_reduce(int64_t a) { | |||||
// Barrett reduction | |||||
int64_t u = (int64_t)((uint64_t)a * PARAM_BARR_MULT) >> PARAM_BARR_DIV; | |||||
return a - u * PARAM_Q; | |||||
} | |||||
static void ntt(poly a, const poly w) { | |||||
// Forward NTT transform | |||||
size_t NumoProblems = PARAM_N >> 1, jTwiddle = 0; | |||||
for (; NumoProblems > 0; NumoProblems >>= 1) { | |||||
size_t jFirst, j = 0; | |||||
for (jFirst = 0; jFirst < PARAM_N; jFirst = j + NumoProblems) { | |||||
sdigit_t W = (sdigit_t)w[jTwiddle++]; | |||||
for (j = jFirst; j < jFirst + NumoProblems; j++) { | |||||
int64_t temp = barr_reduce(reduce((int64_t)W * a[j + NumoProblems])); | |||||
a[j + NumoProblems] = barr_reduce(a[j] + (2LL * PARAM_Q - temp)); | |||||
a[j] = barr_reduce(temp + a[j]); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
static void nttinv(poly a, const poly w) { | |||||
// Inverse NTT transform | |||||
size_t NumoProblems = 1, jTwiddle = 0; | |||||
for (; NumoProblems < PARAM_N; NumoProblems *= 2) { | |||||
size_t jFirst, j = 0; | |||||
for (jFirst = 0; jFirst < PARAM_N; jFirst = j + NumoProblems) { | |||||
sdigit_t W = (sdigit_t)w[jTwiddle++]; | |||||
for (j = jFirst; j < jFirst + NumoProblems; j++) { | |||||
int64_t temp = a[j]; | |||||
a[j] = barr_reduce((temp + a[j + NumoProblems])); | |||||
a[j + NumoProblems] = barr_reduce(reduce((int64_t)W * (temp + (2LL * PARAM_Q - a[j + NumoProblems])))); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
static void poly_pointwise(poly result, const poly x, const poly y) { | |||||
// Pointwise polynomial multiplication result = x.y | |||||
for (size_t i = 0; i < PARAM_N; i++) { | |||||
result[i] = reduce(x[i] * y[i]); | |||||
} | |||||
} | |||||
void PQCLEAN_QTESLAPIII_CLEAN_poly_ntt(poly x_ntt, const poly x) { | |||||
// Call to NTT function. Avoids input destruction | |||||
for (size_t i = 0; i < PARAM_N; i++) { | |||||
x_ntt[i] = x[i]; | |||||
} | |||||
ntt(x_ntt, PQCLEAN_QTESLAPIII_CLEAN_zeta); | |||||
} | |||||
void PQCLEAN_QTESLAPIII_CLEAN_poly_mul(poly result, const poly x, const poly y) { | |||||
// Polynomial multiplication result = x*y, with in place reduction for (X^N+1) | |||||
// The inputs x and y are assumed to be in NTT form | |||||
poly_pointwise(result, x, y); | |||||
nttinv(result, PQCLEAN_QTESLAPIII_CLEAN_zetainv); | |||||
} | |||||
void PQCLEAN_QTESLAPIII_CLEAN_poly_add(poly result, const poly x, const poly y) { | |||||
// Polynomial addition result = x+y | |||||
for (size_t i = 0; i < PARAM_N; i++) { | |||||
result[i] = x[i] + y[i]; | |||||
} | |||||
} | |||||
void PQCLEAN_QTESLAPIII_CLEAN_poly_add_correct(poly result, const poly x, const poly y) { | |||||
// Polynomial addition result = x+y with correction | |||||
for (size_t i = 0; i < PARAM_N; i++) { | |||||
result[i] = x[i] + y[i]; | |||||
result[i] -= PARAM_Q; | |||||
result[i] += (result[i] >> (RADIX32 - 1)) & PARAM_Q; // If result[i] >= q then subtract q | |||||
} | |||||
} | |||||
void PQCLEAN_QTESLAPIII_CLEAN_poly_sub(poly result, const poly x, const poly y) { | |||||
// Polynomial subtraction result = x-y | |||||
for (size_t i = 0; i < PARAM_N; i++) { | |||||
result[i] = barr_reduce(x[i] - y[i]); | |||||
} | |||||
} | |||||
/******************************************************************************************** | |||||
* Name: sparse_mul8 | |||||
* Description: performs sparse polynomial multiplication | |||||
* Parameters: inputs: | |||||
* - const uint8_t *s: part of the secret key | |||||
* - const uint32_t pos_list[PARAM_H]: list of indices of nonzero elements in c | |||||
* - const int16_t sign_list[PARAM_H]: list of signs of nonzero elements in c | |||||
* outputs: | |||||
* - poly prod: product of 2 polynomials | |||||
* | |||||
* Note: pos_list[] and sign_list[] contain public information since c is public | |||||
*********************************************************************************************/ | |||||
void PQCLEAN_QTESLAPIII_CLEAN_sparse_mul8(poly prod, const uint8_t *s, const uint32_t pos_list[PARAM_H], const int16_t sign_list[PARAM_H]) { | |||||
size_t i, j, pos; | |||||
int8_t *t = (int8_t *)s; | |||||
for (i = 0; i < PARAM_N; i++) { | |||||
prod[i] = 0; | |||||
} | |||||
for (i = 0; i < PARAM_H; i++) { | |||||
pos = pos_list[i]; | |||||
for (j = 0; j < pos; j++) { | |||||
prod[j] = prod[j] - sign_list[i] * t[j + PARAM_N - pos]; | |||||
} | |||||
for (j = pos; j < PARAM_N; j++) { | |||||
prod[j] = prod[j] + sign_list[i] * t[j - pos]; | |||||
} | |||||
} | |||||
} | |||||
/******************************************************************************************** | |||||
* Name: sparse_mul32 | |||||
* Description: performs sparse polynomial multiplication | |||||
* Parameters: inputs: | |||||
* - const int32_t* pk: part of the public key | |||||
* - const uint32_t pos_list[PARAM_H]: list of indices of nonzero elements in c | |||||
* - const int16_t sign_list[PARAM_H]: list of signs of nonzero elements in c | |||||
* outputs: | |||||
* - poly prod: product of 2 polynomials | |||||
*********************************************************************************************/ | |||||
void PQCLEAN_QTESLAPIII_CLEAN_sparse_mul32(poly prod, const int32_t *pk, const uint32_t pos_list[PARAM_H], const int16_t sign_list[PARAM_H]) { | |||||
size_t i, j, pos; | |||||
for (i = 0; i < PARAM_N; i++) { | |||||
prod[i] = 0; | |||||
} | |||||
for (i = 0; i < PARAM_H; i++) { | |||||
pos = pos_list[i]; | |||||
for (j = 0; j < pos; j++) { | |||||
prod[j] = prod[j] - sign_list[i] * pk[j + PARAM_N - pos]; | |||||
} | |||||
for (j = pos; j < PARAM_N; j++) { | |||||
prod[j] = prod[j] + sign_list[i] * pk[j - pos]; | |||||
} | |||||
} | |||||
for (i = 0; i < PARAM_N; i++) { | |||||
prod[i] = barr_reduce(prod[i]); | |||||
} | |||||
} | |||||
void PQCLEAN_QTESLAPIII_CLEAN_poly_uniform(poly_k a, const uint8_t *seed) { | |||||
// Generation of polynomials "a_i" | |||||
size_t pos = 0, i = 0, nbytes = (PARAM_Q_LOG + 7) / 8; | |||||
size_t nblocks = PARAM_GEN_A; | |||||
uint32_t val1, val2, val3, val4, mask = (uint32_t)(1 << PARAM_Q_LOG) - 1; | |||||
uint8_t buf[SHAKE128_RATE * PARAM_GEN_A]; | |||||
uint16_t dmsp = 0; | |||||
uint8_t dmsp_bytes[2]; | |||||
dmsp_bytes[0] = (uint8_t)(dmsp & 0xff); | |||||
dmsp_bytes[1] = (uint8_t)(dmsp >> 8); | |||||
cshake128(buf, SHAKE128_RATE * PARAM_GEN_A, (uint8_t *)NULL, 0, dmsp_bytes, 2, seed, CRYPTO_RANDOMBYTES); | |||||
++dmsp; | |||||
while (i < PARAM_K * PARAM_N) { | |||||
if (pos > SHAKE128_RATE * nblocks - 4 * nbytes) { | |||||
nblocks = 1; | |||||
dmsp_bytes[0] = (uint8_t)(dmsp & 0xff); | |||||
dmsp_bytes[1] = (uint8_t)(dmsp >> 8); | |||||
cshake128(buf, SHAKE128_RATE * nblocks, (uint8_t *)NULL, 0, dmsp_bytes, 2, seed, CRYPTO_RANDOMBYTES); | |||||
++dmsp; | |||||
pos = 0; | |||||
} | |||||
val1 = ((uint32_t)(buf[pos]) | |||||
| (uint32_t)(buf[pos + 1] << 8) | |||||
| (uint32_t)(buf[pos + 2] << 16) | |||||
| (uint32_t)(buf[pos + 3] << 24)) | |||||
& mask; | |||||
pos += nbytes; | |||||
val2 = ((uint32_t)(buf[pos]) | |||||
| (uint32_t)(buf[pos + 1] << 8) | |||||
| (uint32_t)(buf[pos + 2] << 16) | |||||
| (uint32_t)(buf[pos + 3] << 24)) | |||||
& mask; | |||||
pos += nbytes; | |||||
val3 = ((uint32_t)(buf[pos]) | |||||
| (uint32_t)(buf[pos + 1] << 8) | |||||
| (uint32_t)(buf[pos + 2] << 16) | |||||
| (uint32_t)(buf[pos + 3] << 24)) | |||||
& mask; | |||||
pos += nbytes; | |||||
val4 = ((uint32_t)(buf[pos]) | |||||
| (uint32_t)(buf[pos + 1] << 8) | |||||
| (uint32_t)(buf[pos + 2] << 16) | |||||
| (uint32_t)(buf[pos + 3] << 24)) | |||||
& mask; | |||||
pos += nbytes; | |||||
if (val1 < PARAM_Q && i < PARAM_K * PARAM_N) { | |||||
a[i++] = reduce((int64_t)val1 * PARAM_R2_INVN); | |||||
} | |||||
if (val2 < PARAM_Q && i < PARAM_K * PARAM_N) { | |||||
a[i++] = reduce((int64_t)val2 * PARAM_R2_INVN); | |||||
} | |||||
if (val3 < PARAM_Q && i < PARAM_K * PARAM_N) { | |||||
a[i++] = reduce((int64_t)val3 * PARAM_R2_INVN); | |||||
} | |||||
if (val4 < PARAM_Q && i < PARAM_K * PARAM_N) { | |||||
a[i++] = reduce((int64_t)val4 * PARAM_R2_INVN); | |||||
} | |||||
} | |||||
} | |||||
@@ -0,0 +1,20 @@ | |||||
#ifndef PQCLEAN_QTESLAPIII_CLEAN_POLY_H | |||||
#define PQCLEAN_QTESLAPIII_CLEAN_POLY_H | |||||
#include "config.h" | |||||
#include "params.h" | |||||
#include <stdint.h> | |||||
typedef int64_t poly[PARAM_N]; | |||||
typedef int64_t poly_k[PARAM_N * PARAM_K]; | |||||
void PQCLEAN_QTESLAPIII_CLEAN_poly_ntt(poly x_ntt, const poly x); | |||||
void PQCLEAN_QTESLAPIII_CLEAN_poly_mul(poly result, const poly x, const poly y); | |||||
void PQCLEAN_QTESLAPIII_CLEAN_poly_add(poly result, const poly x, const poly y); | |||||
void PQCLEAN_QTESLAPIII_CLEAN_poly_add_correct(poly result, const poly x, const poly y); | |||||
void PQCLEAN_QTESLAPIII_CLEAN_poly_sub(poly result, const poly x, const poly y); | |||||
void PQCLEAN_QTESLAPIII_CLEAN_sparse_mul8(poly prod, const uint8_t *s, const uint32_t pos_list[PARAM_H], const int16_t sign_list[PARAM_H]); | |||||
void PQCLEAN_QTESLAPIII_CLEAN_sparse_mul32(poly prod, const int32_t *pk, const uint32_t pos_list[PARAM_H], const int16_t sign_list[PARAM_H]); | |||||
void PQCLEAN_QTESLAPIII_CLEAN_poly_uniform(poly_k a, const uint8_t *seed); | |||||
#endif |
@@ -0,0 +1,89 @@ | |||||
/************************************************************************************* | |||||
* qTESLA: an efficient post-quantum signature scheme based on the R-LWE problem | |||||
* | |||||
* Abstract: sampling functions | |||||
**************************************************************************************/ | |||||
#include "api.h" | |||||
#include "params.h" | |||||
#include "sample.h" | |||||
#include "sp800-185.h" | |||||
#define NBLOCKS_SHAKE (SHAKE_RATE/(((PARAM_B_BITS+1)+7)/8)) | |||||
#define BPLUS1BYTES (((PARAM_B_BITS+1)+7)/8) | |||||
void PQCLEAN_QTESLAPIII_CLEAN_sample_y(poly y, const uint8_t *seed, uint16_t nonce) { | |||||
// Sample polynomial y, such that each coefficient is in the range [-B,B] | |||||
size_t i = 0, pos = 0, nblocks = PARAM_N; | |||||
uint8_t buf[PARAM_N * BPLUS1BYTES + 1]; | |||||
uint16_t dmsp = (uint16_t)(nonce << 8); | |||||
uint8_t dmsp_bytes[2]; | |||||
dmsp_bytes[0] = (uint8_t)(dmsp & 0xff); | |||||
dmsp_bytes[1] = (uint8_t)(dmsp >> 8); | |||||
cSHAKE(buf, PARAM_N * BPLUS1BYTES, (uint8_t *)NULL, 0, dmsp_bytes, 2, seed, CRYPTO_RANDOMBYTES); | |||||
++dmsp; | |||||
while (i < PARAM_N) { | |||||
if (pos >= nblocks * BPLUS1BYTES) { | |||||
nblocks = NBLOCKS_SHAKE; | |||||
dmsp_bytes[0] = (uint8_t)(dmsp & 0xff); | |||||
dmsp_bytes[1] = (uint8_t)(dmsp >> 8); | |||||
cSHAKE(buf, SHAKE_RATE, (uint8_t *)NULL, 0, dmsp_bytes, 2, seed, CRYPTO_RANDOMBYTES); | |||||
++dmsp; | |||||
pos = 0; | |||||
} | |||||
y[i] = (uint32_t)((buf[pos] | (buf[pos + 1] << 8) | (buf[pos + 2] << 16)) & ((1 << (PARAM_B_BITS + 1)) - 1)); | |||||
y[i] -= PARAM_B; | |||||
if (y[i] != (1 << PARAM_B_BITS)) { | |||||
i++; | |||||
} | |||||
pos += BPLUS1BYTES; | |||||
} | |||||
} | |||||
void PQCLEAN_QTESLAPIII_CLEAN_encode_c(uint32_t *pos_list, int16_t *sign_list, uint8_t *c_bin) { | |||||
// Encoding of c' by mapping the output of the hash function H to an N-element vector with entries {-1,0,1} | |||||
size_t i, pos, cnt = 0; | |||||
int16_t c[PARAM_N]; | |||||
uint8_t r[SHAKE128_RATE]; | |||||
uint16_t dmsp = 0; | |||||
uint8_t dmsp_bytes[2]; | |||||
// Use the hash value as key to generate some randomness | |||||
dmsp_bytes[0] = (uint8_t)(dmsp & 0xff); | |||||
dmsp_bytes[1] = (uint8_t)(dmsp >> 8); | |||||
cshake128(r, SHAKE128_RATE, (uint8_t *)NULL, 0, dmsp_bytes, 2, c_bin, CRYPTO_RANDOMBYTES); | |||||
++dmsp; | |||||
// Use rejection sampling to determine positions to be set in the new vector | |||||
for (i = 0; i < PARAM_N; i++) { | |||||
c[i] = 0; | |||||
} | |||||
for (i = 0; i < PARAM_H;) { // Sample a unique position k times. Use two bytes | |||||
if (cnt > (SHAKE128_RATE - 3)) { | |||||
dmsp_bytes[0] = (uint8_t)(dmsp & 0xff); | |||||
dmsp_bytes[1] = (uint8_t)(dmsp >> 8); | |||||
cshake128(r, SHAKE128_RATE, (uint8_t *)NULL, 0, dmsp_bytes, 2, c_bin, CRYPTO_RANDOMBYTES); | |||||
++dmsp; | |||||
cnt = 0; | |||||
} | |||||
pos = (size_t)((r[cnt] << 8) | (r[cnt + 1])); | |||||
pos = pos & (PARAM_N - 1); // Position is in the range [0,N-1] | |||||
if (c[pos] == 0) { // Position has not been set yet. Determine sign | |||||
if ((r[cnt + 2] & 1) == 1) { | |||||
c[pos] = -1; | |||||
} else { | |||||
c[pos] = 1; | |||||
} | |||||
pos_list[i] = (uint32_t)pos; | |||||
sign_list[i] = c[pos]; | |||||
i++; | |||||
} | |||||
cnt += 3; | |||||
} | |||||
} |
@@ -0,0 +1,11 @@ | |||||
#ifndef PQCLEAN_QTESLAPIII_CLEAN_SAMPLE_H | |||||
#define PQCLEAN_QTESLAPIII_CLEAN_SAMPLE_H | |||||
#include "params.h" | |||||
#include "poly.h" | |||||
#include <stdint.h> | |||||
void PQCLEAN_QTESLAPIII_CLEAN_sample_y(poly y, const uint8_t *seed, uint16_t nonce); | |||||
void PQCLEAN_QTESLAPIII_CLEAN_encode_c(uint32_t *pos_list, int16_t *sign_list, uint8_t *c_bin); | |||||
#endif |
@@ -0,0 +1,403 @@ | |||||
/************************************************************************************* | |||||
* qTESLA: an efficient post-quantum signature scheme based on the R-LWE problem | |||||
* | |||||
* Abstract: high-level functions of the signature scheme | |||||
**************************************************************************************/ | |||||
#include "api.h" | |||||
#include "fips202.h" | |||||
#include "gauss.h" | |||||
#include "pack.h" | |||||
#include "params.h" | |||||
#include "poly.h" | |||||
#include "randombytes.h" | |||||
#include "sample.h" | |||||
#include <stdlib.h> | |||||
#include <string.h> | |||||
static void hash_H(uint8_t *c_bin, const poly_k v, const uint8_t *hm) { | |||||
// Hash-based function H to generate c' | |||||
uint8_t t[PARAM_K * PARAM_N + HM_BYTES]; | |||||
int32_t mask, cL, temp; | |||||
size_t i, k, index; | |||||
for (k = 0; k < PARAM_K; k++) { | |||||
index = k * PARAM_N; | |||||
for (i = 0; i < PARAM_N; i++) { | |||||
temp = (int32_t)v[index]; | |||||
// If v[i] > PARAM_Q/2 then v[i] -= PARAM_Q | |||||
mask = (PARAM_Q / 2 - temp) >> (RADIX32 - 1); | |||||
temp = ((temp - PARAM_Q) & mask) | (temp & ~mask); | |||||
cL = temp & ((1 << PARAM_D) - 1); | |||||
// If cL > 2^(d-1) then cL -= 2^d | |||||
mask = ((1 << (PARAM_D - 1)) - cL) >> (RADIX32 - 1); | |||||
cL = ((cL - (1 << PARAM_D)) & mask) | (cL & ~mask); | |||||
t[index++] = (uint8_t)((temp - cL) >> PARAM_D); | |||||
} | |||||
} | |||||
memcpy(&t[PARAM_K * PARAM_N], hm, HM_BYTES); | |||||
SHAKE(c_bin, CRYPTO_C_BYTES, t, PARAM_K * PARAM_N + HM_BYTES); | |||||
} | |||||
static inline int32_t Abs(int32_t value) { | |||||
// Compute absolute value | |||||
int32_t mask = value >> (RADIX32 - 1); | |||||
return (mask ^ value) - mask; | |||||
} | |||||
static int test_rejection(const poly z) { | |||||
// Check bounds for signature vector z during signing. Returns 0 if valid, otherwise outputs 1 if invalid (rejected). | |||||
// This function does not leak any information about the coefficient that fails the test. | |||||
uint32_t valid = 0; | |||||
for (size_t i = 0; i < PARAM_N; i++) { | |||||
valid |= (PARAM_B - PARAM_S) - (uint32_t)Abs((int32_t)z[i]); | |||||
} | |||||
return (int)(valid >> 31); | |||||
} | |||||
static int test_correctness(const poly v) { | |||||
// Check bounds for w = v - ec during signature verification. Returns 0 if valid, otherwise outputs 1 if invalid (rejected). | |||||
// This function leaks the position of the coefficient that fails the test (but this is independent of the secret data). | |||||
// It does not leak the sign of the coefficients. | |||||
int32_t mask, left, val; | |||||
uint32_t t0, t1; | |||||
for (size_t i = 0; i < PARAM_N; i++) { | |||||
// If v[i] > PARAM_Q/2 then v[i] -= PARAM_Q | |||||
mask = (int32_t)(PARAM_Q / 2 - v[i]) >> (RADIX32 - 1); | |||||
val = (int32_t)(((v[i] - PARAM_Q) & mask) | (v[i] & ~mask)); | |||||
// If (Abs(val) < PARAM_Q/2 - PARAM_E) then t0 = 0, else t0 = 1 | |||||
t0 = (uint32_t)(~(Abs(val) - (PARAM_Q / 2 - PARAM_E))) >> (RADIX32 - 1); | |||||
left = val; | |||||
val = (val + (1 << (PARAM_D - 1)) - 1) >> PARAM_D; | |||||
val = left - (val << PARAM_D); | |||||
// If (Abs(val) < (1<<(PARAM_D-1))-PARAM_E) then t1 = 0, else t1 = 1 | |||||
t1 = (uint32_t)(~(Abs(val) - ((1 << (PARAM_D - 1)) - PARAM_E))) >> (RADIX32 - 1); | |||||
if ((t0 | t1) == 1) { // Returns 1 if any of the two tests failed | |||||
return 1; | |||||
} | |||||
} | |||||
return 0; | |||||
} | |||||
static int test_z(const poly z) { | |||||
// Check bounds for signature vector z during signature verification | |||||
// Returns 0 if valid, otherwise outputs 1 if invalid (rejected) | |||||
for (size_t i = 0; i < PARAM_N; i++) { | |||||
if (z[i] < -(PARAM_B - PARAM_S) || z[i] > (PARAM_B - PARAM_S)) { | |||||
return 1; | |||||
} | |||||
} | |||||
return 0; | |||||
} | |||||
static int check_ES(poly p, unsigned int bound) { | |||||
// Checks the generated polynomial e or s | |||||
// Returns 0 if ok, otherwise returns 1 | |||||
unsigned int sum = 0; | |||||
size_t i, j, limit = PARAM_N; | |||||
int32_t temp, mask, list[PARAM_N]; | |||||
for (j = 0; j < PARAM_N; j++) { | |||||
list[j] = Abs((int32_t)p[j]); | |||||
} | |||||
for (j = 0; j < PARAM_H; j++) { | |||||
for (i = 0; i < limit - 1; i++) { | |||||
// If list[i+1] > list[i] then exchange contents | |||||
mask = (list[i + 1] - list[i]) >> (RADIX32 - 1); | |||||
temp = (list[i + 1] & mask) | (list[i] & ~mask); | |||||
list[i + 1] = (list[i] & mask) | (list[i + 1] & ~mask); | |||||
list[i] = temp; | |||||
} | |||||
sum += (unsigned int)list[limit - 1]; | |||||
limit -= 1; | |||||
} | |||||
if (sum > bound) { | |||||
return 1; | |||||
} | |||||
return 0; | |||||
} | |||||
/********************************************************* | |||||
* Name: crypto_sign_keypair | |||||
* Description: generates a public and private key pair | |||||
* Parameters: inputs: none | |||||
* outputs: | |||||
* - uint8_t *pk: public key | |||||
* - uint8_t *sk: secret key | |||||
* Returns: 0 for successful execution | |||||
**********************************************************/ | |||||
int PQCLEAN_QTESLAPIII_CLEAN_crypto_sign_keypair(uint8_t *pk, uint8_t *sk) { | |||||
uint8_t randomness[CRYPTO_RANDOMBYTES], randomness_extended[(PARAM_K + 3)*CRYPTO_SEEDBYTES]; | |||||
poly s, s_ntt; | |||||
poly_k e, a, t; | |||||
size_t k; // Initialize domain separator for error and secret polynomials | |||||
uint16_t nonce = 0; | |||||
// Get randomness_extended <- seed_e, seed_s, seed_a, seed_y | |||||
randombytes(randomness, CRYPTO_RANDOMBYTES); | |||||
SHAKE(randomness_extended, (PARAM_K + 3)*CRYPTO_SEEDBYTES, randomness, CRYPTO_RANDOMBYTES); | |||||
for (k = 0; k < PARAM_K; k++) { | |||||
do { // Sample the error polynomials | |||||
PQCLEAN_QTESLAPIII_CLEAN_sample_gauss_poly(&e[k * PARAM_N], &randomness_extended[k * CRYPTO_SEEDBYTES], ++nonce); | |||||
} while (check_ES(&e[k * PARAM_N], PARAM_KEYGEN_BOUND_E) != 0); | |||||
} | |||||
do { // Sample the secret polynomial | |||||
PQCLEAN_QTESLAPIII_CLEAN_sample_gauss_poly(s, &randomness_extended[PARAM_K * CRYPTO_SEEDBYTES], ++nonce); | |||||
} while (check_ES(s, PARAM_KEYGEN_BOUND_S) != 0); | |||||
// Generate uniform polynomial "a" | |||||
PQCLEAN_QTESLAPIII_CLEAN_poly_uniform(a, &randomness_extended[(PARAM_K + 1)*CRYPTO_SEEDBYTES]); | |||||
PQCLEAN_QTESLAPIII_CLEAN_poly_ntt(s_ntt, s); | |||||
// Compute the public key t = as+e | |||||
for (k = 0; k < PARAM_K; k++) { | |||||
PQCLEAN_QTESLAPIII_CLEAN_poly_mul(&t[k * PARAM_N], &a[k * PARAM_N], s_ntt); | |||||
PQCLEAN_QTESLAPIII_CLEAN_poly_add_correct(&t[k * PARAM_N], &t[k * PARAM_N], &e[k * PARAM_N]); | |||||
} | |||||
// Pack public and private keys | |||||
PQCLEAN_QTESLAPIII_CLEAN_pack_sk(sk, s, e, &randomness_extended[(PARAM_K + 1)*CRYPTO_SEEDBYTES]); | |||||
PQCLEAN_QTESLAPIII_CLEAN_encode_pk(pk, t, &randomness_extended[(PARAM_K + 1)*CRYPTO_SEEDBYTES]); | |||||
return 0; | |||||
} | |||||
/*************************************************************** | |||||
* Name: crypto_sign | |||||
* Description: outputs a signature for a given message m | |||||
* Parameters: inputs: | |||||
* - const uint8_t *m: message to be signed | |||||
* - size_t mlen: message length | |||||
* - const uint8_t* sk: secret key | |||||
* outputs: | |||||
* - uint8_t *sm: signature | |||||
* - size_t *smlen: signature length* | |||||
* Returns: 0 for successful execution | |||||
***************************************************************/ | |||||
int PQCLEAN_QTESLAPIII_CLEAN_crypto_sign(uint8_t *sm, size_t *smlen, const uint8_t *m, size_t mlen, const uint8_t *sk) { | |||||
uint8_t c[CRYPTO_C_BYTES], randomness[CRYPTO_SEEDBYTES], randomness_input[CRYPTO_RANDOMBYTES + CRYPTO_SEEDBYTES + HM_BYTES]; | |||||
uint32_t pos_list[PARAM_H]; | |||||
int16_t sign_list[PARAM_H]; | |||||
poly y, y_ntt, Sc, z; | |||||
poly_k v, Ec, a; | |||||
size_t k; | |||||
int rsp; | |||||
uint16_t nonce = 0; // Initialize domain separator for sampling y | |||||
// Get H(seed_y, r, H(m)) to sample y | |||||
randombytes(randomness_input + CRYPTO_RANDOMBYTES, CRYPTO_RANDOMBYTES); | |||||
memcpy(randomness_input, &sk[PQCLEAN_QTESLAPIII_CLEAN_CRYPTO_SECRETKEYBYTES - CRYPTO_SEEDBYTES], CRYPTO_SEEDBYTES); | |||||
SHAKE(randomness_input + CRYPTO_RANDOMBYTES + CRYPTO_SEEDBYTES, HM_BYTES, m, mlen); | |||||
SHAKE(randomness, CRYPTO_SEEDBYTES, randomness_input, CRYPTO_RANDOMBYTES + CRYPTO_SEEDBYTES + HM_BYTES); | |||||
PQCLEAN_QTESLAPIII_CLEAN_poly_uniform(a, &sk[PQCLEAN_QTESLAPIII_CLEAN_CRYPTO_SECRETKEYBYTES - 2 * CRYPTO_SEEDBYTES]); | |||||
while (1) { | |||||
PQCLEAN_QTESLAPIII_CLEAN_sample_y(y, randomness, ++nonce); // Sample y uniformly at random from [-B,B] | |||||
PQCLEAN_QTESLAPIII_CLEAN_poly_ntt (y_ntt, y); | |||||
for (k = 0; k < PARAM_K; k++) { | |||||
PQCLEAN_QTESLAPIII_CLEAN_poly_mul(&v[k * PARAM_N], &a[k * PARAM_N], y_ntt); | |||||
} | |||||
hash_H(c, v, randomness_input + CRYPTO_RANDOMBYTES + CRYPTO_SEEDBYTES); | |||||
PQCLEAN_QTESLAPIII_CLEAN_encode_c(pos_list, sign_list, c); // Generate c = Enc(c'), where c' is the hashing of v together with m | |||||
PQCLEAN_QTESLAPIII_CLEAN_sparse_mul8(Sc, sk, pos_list, sign_list); | |||||
PQCLEAN_QTESLAPIII_CLEAN_poly_add(z, y, Sc); // Compute z = y + sc | |||||
if (test_rejection(z) != 0) { // Rejection sampling | |||||
continue; | |||||
} | |||||
for (k = 0; k < PARAM_K; k++) { | |||||
PQCLEAN_QTESLAPIII_CLEAN_sparse_mul8(&Ec[k * PARAM_N], sk + (sizeof(int8_t)*PARAM_N * (k + 1)), pos_list, sign_list); | |||||
PQCLEAN_QTESLAPIII_CLEAN_poly_sub(&v[k * PARAM_N], &v[k * PARAM_N], &Ec[k * PARAM_N]); | |||||
rsp = test_correctness(&v[k * PARAM_N]); | |||||
if (rsp != 0) { | |||||
break; | |||||
} | |||||
} | |||||
if (rsp != 0) { | |||||
continue; | |||||
} | |||||
// Copy message to signature package, and pack signature | |||||
for (size_t i = 0; i < mlen; i++) { | |||||
sm[PQCLEAN_QTESLAPIII_CLEAN_CRYPTO_BYTES + i] = m[i]; | |||||
} | |||||
*smlen = PQCLEAN_QTESLAPIII_CLEAN_CRYPTO_BYTES + mlen; | |||||
PQCLEAN_QTESLAPIII_CLEAN_encode_sig(sm, c, z); | |||||
return 0; | |||||
} | |||||
} | |||||
/************************************************************ | |||||
* Name: crypto_sign_open | |||||
* Description: verification of a signature sm | |||||
* Parameters: inputs: | |||||
* - const uint8_t *sm: signature | |||||
* - size_t smlen: signature length | |||||
* - const uint8_t* pk: public Key | |||||
* outputs: | |||||
* - uint8_t *m: original (signed) message | |||||
* - size_t *mlen: message length* | |||||
* Returns: 0 for valid signature | |||||
* <0 for invalid signature | |||||
************************************************************/ | |||||
int PQCLEAN_QTESLAPIII_CLEAN_crypto_sign_open(uint8_t *m, size_t *mlen, const uint8_t *sm, size_t smlen, const uint8_t *pk) { | |||||
uint8_t c[CRYPTO_C_BYTES], c_sig[CRYPTO_C_BYTES], seed[CRYPTO_SEEDBYTES], hm[HM_BYTES]; | |||||
uint32_t pos_list[PARAM_H]; | |||||
int16_t sign_list[PARAM_H]; | |||||
int32_t pk_t[PARAM_N * PARAM_K]; | |||||
poly_k w, a, Tc; | |||||
poly z, z_ntt; | |||||
size_t k; | |||||
if (smlen < PQCLEAN_QTESLAPIII_CLEAN_CRYPTO_BYTES) { | |||||
return -1; | |||||
} | |||||
PQCLEAN_QTESLAPIII_CLEAN_decode_sig(c, z, sm); | |||||
if (test_z(z) != 0) { | |||||
return -2; // Check norm of z | |||||
} | |||||
PQCLEAN_QTESLAPIII_CLEAN_decode_pk(pk_t, seed, pk); | |||||
PQCLEAN_QTESLAPIII_CLEAN_poly_uniform(a, seed); | |||||
PQCLEAN_QTESLAPIII_CLEAN_encode_c(pos_list, sign_list, c); | |||||
PQCLEAN_QTESLAPIII_CLEAN_poly_ntt(z_ntt, z); | |||||
for (k = 0; k < PARAM_K; k++) { // Compute w = az - tc | |||||
PQCLEAN_QTESLAPIII_CLEAN_sparse_mul32(&Tc[k * PARAM_N], &pk_t[k * PARAM_N], pos_list, sign_list); | |||||
PQCLEAN_QTESLAPIII_CLEAN_poly_mul(&w[k * PARAM_N], &a[k * PARAM_N], z_ntt); | |||||
PQCLEAN_QTESLAPIII_CLEAN_poly_sub(&w[k * PARAM_N], &w[k * PARAM_N], &Tc[k * PARAM_N]); | |||||
} | |||||
SHAKE(hm, HM_BYTES, sm + PQCLEAN_QTESLAPIII_CLEAN_CRYPTO_BYTES, smlen - PQCLEAN_QTESLAPIII_CLEAN_CRYPTO_BYTES); | |||||
hash_H(c_sig, w, hm); | |||||
// Check if the calculated c matches c from the signature | |||||
if (memcmp(c, c_sig, CRYPTO_C_BYTES) != 0) { | |||||
return -3; | |||||
} | |||||
*mlen = smlen - PQCLEAN_QTESLAPIII_CLEAN_CRYPTO_BYTES; | |||||
for (size_t i = 0; i < *mlen; i++) { | |||||
m[i] = sm[PQCLEAN_QTESLAPIII_CLEAN_CRYPTO_BYTES + i]; | |||||
} | |||||
return 0; | |||||
} | |||||
int PQCLEAN_QTESLAPIII_CLEAN_crypto_sign_signature( | |||||
uint8_t *sig, size_t *siglen, | |||||
const uint8_t *m, size_t mlen, | |||||
const uint8_t *sk) { | |||||
uint8_t c[CRYPTO_C_BYTES], randomness[CRYPTO_SEEDBYTES], randomness_input[CRYPTO_RANDOMBYTES + CRYPTO_SEEDBYTES + HM_BYTES]; | |||||
uint32_t pos_list[PARAM_H]; | |||||
int16_t sign_list[PARAM_H]; | |||||
poly y, y_ntt, Sc, z; | |||||
poly_k v, Ec, a; | |||||
size_t k; | |||||
int rsp; | |||||
uint16_t nonce = 0; // Initialize domain separator for sampling y | |||||
// Get H(seed_y, r, H(m)) to sample y | |||||
randombytes(randomness_input + CRYPTO_RANDOMBYTES, CRYPTO_RANDOMBYTES); | |||||
memcpy(randomness_input, &sk[PQCLEAN_QTESLAPIII_CLEAN_CRYPTO_SECRETKEYBYTES - CRYPTO_SEEDBYTES], CRYPTO_SEEDBYTES); | |||||
SHAKE(randomness_input + CRYPTO_RANDOMBYTES + CRYPTO_SEEDBYTES, HM_BYTES, m, mlen); | |||||
SHAKE(randomness, CRYPTO_SEEDBYTES, randomness_input, CRYPTO_RANDOMBYTES + CRYPTO_SEEDBYTES + HM_BYTES); | |||||
PQCLEAN_QTESLAPIII_CLEAN_poly_uniform(a, &sk[PQCLEAN_QTESLAPIII_CLEAN_CRYPTO_SECRETKEYBYTES - 2 * CRYPTO_SEEDBYTES]); | |||||
while (1) { | |||||
PQCLEAN_QTESLAPIII_CLEAN_sample_y(y, randomness, ++nonce); // Sample y uniformly at random from [-B,B] | |||||
PQCLEAN_QTESLAPIII_CLEAN_poly_ntt (y_ntt, y); | |||||
for (k = 0; k < PARAM_K; k++) { | |||||
PQCLEAN_QTESLAPIII_CLEAN_poly_mul(&v[k * PARAM_N], &a[k * PARAM_N], y_ntt); | |||||
} | |||||
hash_H(c, v, randomness_input + CRYPTO_RANDOMBYTES + CRYPTO_SEEDBYTES); | |||||
PQCLEAN_QTESLAPIII_CLEAN_encode_c(pos_list, sign_list, c); // Generate c = Enc(c'), where c' is the hashing of v together with m | |||||
PQCLEAN_QTESLAPIII_CLEAN_sparse_mul8(Sc, sk, pos_list, sign_list); | |||||
PQCLEAN_QTESLAPIII_CLEAN_poly_add(z, y, Sc); // Compute z = y + sc | |||||
if (test_rejection(z) != 0) { // Rejection sampling | |||||
continue; | |||||
} | |||||
for (k = 0; k < PARAM_K; k++) { | |||||
PQCLEAN_QTESLAPIII_CLEAN_sparse_mul8(&Ec[k * PARAM_N], sk + (sizeof(int8_t)*PARAM_N * (k + 1)), pos_list, sign_list); | |||||
PQCLEAN_QTESLAPIII_CLEAN_poly_sub(&v[k * PARAM_N], &v[k * PARAM_N], &Ec[k * PARAM_N]); | |||||
rsp = test_correctness(&v[k * PARAM_N]); | |||||
if (rsp != 0) { | |||||
break; | |||||
} | |||||
} | |||||
if (rsp != 0) { | |||||
continue; | |||||
} | |||||
// pack signature | |||||
*siglen = PQCLEAN_QTESLAPIII_CLEAN_CRYPTO_BYTES; | |||||
PQCLEAN_QTESLAPIII_CLEAN_encode_sig(sig, c, z); | |||||
return 0; | |||||
} | |||||
} | |||||
int PQCLEAN_QTESLAPIII_CLEAN_crypto_sign_verify( | |||||
const uint8_t *sig, size_t siglen, | |||||
const uint8_t *m, size_t mlen, | |||||
const uint8_t *pk) { | |||||
uint8_t c[CRYPTO_C_BYTES], c_sig[CRYPTO_C_BYTES], seed[CRYPTO_SEEDBYTES], hm[HM_BYTES]; | |||||
uint32_t pos_list[PARAM_H]; | |||||
int16_t sign_list[PARAM_H]; | |||||
int32_t pk_t[PARAM_N * PARAM_K]; | |||||
poly_k w, a, Tc; | |||||
poly z, z_ntt; | |||||
size_t k; | |||||
if (siglen < PQCLEAN_QTESLAPIII_CLEAN_CRYPTO_BYTES) { | |||||
return -1; | |||||
} | |||||
PQCLEAN_QTESLAPIII_CLEAN_decode_sig(c, z, sig); | |||||
if (test_z(z) != 0) { | |||||
return -2; // Check norm of z | |||||
} | |||||
PQCLEAN_QTESLAPIII_CLEAN_decode_pk(pk_t, seed, pk); | |||||
PQCLEAN_QTESLAPIII_CLEAN_poly_uniform(a, seed); | |||||
PQCLEAN_QTESLAPIII_CLEAN_encode_c(pos_list, sign_list, c); | |||||
PQCLEAN_QTESLAPIII_CLEAN_poly_ntt(z_ntt, z); | |||||
for (k = 0; k < PARAM_K; k++) { // Compute w = az - tc | |||||
PQCLEAN_QTESLAPIII_CLEAN_sparse_mul32(&Tc[k * PARAM_N], &pk_t[k * PARAM_N], pos_list, sign_list); | |||||
PQCLEAN_QTESLAPIII_CLEAN_poly_mul(&w[k * PARAM_N], &a[k * PARAM_N], z_ntt); | |||||
PQCLEAN_QTESLAPIII_CLEAN_poly_sub(&w[k * PARAM_N], &w[k * PARAM_N], &Tc[k * PARAM_N]); | |||||
} | |||||
SHAKE(hm, HM_BYTES, m, mlen); | |||||
hash_H(c_sig, w, hm); | |||||
// Check if the calculated c matches c from the signature | |||||
if (memcmp(c, c_sig, CRYPTO_C_BYTES) != 0) { | |||||
return -3; | |||||
} | |||||
return 0; | |||||
} |
@@ -0,0 +1,13 @@ | |||||
consistency_checks: | |||||
- source: | |||||
scheme: qtesla-p-I | |||||
implementation: clean | |||||
files: | |||||
- config.h | |||||
- gauss.c | |||||
- gauss.h | |||||
- pack.h | |||||
- poly.h | |||||
- sample.c | |||||
- sample.h | |||||
- sign.c |
@@ -0,0 +1,13 @@ | |||||
consistency_checks: | |||||
- source: | |||||
scheme: qtesla-p-III | |||||
implementation: clean | |||||
files: | |||||
- config.h | |||||
- gauss.c | |||||
- gauss.h | |||||
- pack.h | |||||
- poly.h | |||||
- sample.c | |||||
- sample.h | |||||
- sign.c |