purecrypto 0.6.18

A pure-Rust cryptography toolkit with no foreign-code dependencies, from constant-time primitives up to keys, X.509 and TLS.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
//! Falcon verification KATs.
//!
//! Vectors are extracted from the official Falcon round-3 NIST submission
//! Known-Answer-Test files (`falcon512-KAT.rsp` / `falcon1024-KAT.rsp`,
//! `count = 0`), as mirrored at
//! <https://github.com/QubitEthereum/falcon> (`KAT/`). The NIST `sm`
//! (signed-message) blob is `[2-byte BE siglen] || nonce(40) || msg ||
//! esig`, where `esig = header(0x20+logn) || compressed-s2`. The standalone
//! signature hardcoded here is the verifier input
//! `header || nonce(40) || compressed-s2` (the compressed / unpadded
//! format, header `0x29` for Falcon-512 and `0x2A` for Falcon-1024).

use super::{FalconPublicKey, verify};
use crate::test_util::from_hex_vec;

fn f512_pk() -> alloc::vec::Vec<u8> {
    from_hex_vec(concat!(
        "096BA86CB658A8F445C9A5E4C28374BEC879C8655F68526923240918074D0147C03162E4A49200648C652803C6FD7509",
        "AE9AA799D6310D0BD42724E0635920186207000767CA5A8546B1755308C304B84FC93B069E265985B398D6B834698287",
        "FF829AA820F17A7F4226AB21F601EBD7175226BAB256D8888F009032566D6383D68457EA155A94301870D589C678ED30",
        "4259E9D37B193BC2A7CCBCBEC51D69158C44073AEC9792630253318BC954DBF50D15028290DC2D309C7B7B02A6823744",
        "D463DA17749595CB77E6D16D20D1B4C3AAD89D320EBE5A672BB96D6CD5C1EFEC8B811200CBB062E473352540EDDEF8AF",
        "9499F8CDD1DC7C6873F0C7A6BCB7097560271F946849B7F373640BB69CA9B518AA380A6EB0A7275EE84E9C221AED88F5",
        "BFBAF43A3EDE8E6AA42558104FAF800E018441930376C6F6E751569971F47ADBCA5CA00C801988F317A18722A2929892",
        "5EA154DBC9024E120524A2D41DC0F18FD8D909F6C50977404E201767078BA9A1F9E40A8B2BA9C01B7DA3A0B73A4C2A6B",
        "4F518BBEE3455D0AF2204DDC031C805C72CCB647940B1E6794D859AAEBCEA0DEB581D61B9248BD9697B5CB974A8176E8",
        "F910469CAE0AB4ED92D2AEE9F7EB50296DAF8057476305C1189D1D9840A0944F0447FB81E511420E67891B98FA6C2570",
        "34D5A063437D379177CE8D3FA6EAF12E2DBB7EB8E498481612B1929617DA5FB45E4CDF893927D8BA842AA861D9C50471",
        "C6D0C6DF7E2BB26465A0EB6A3A709DE792AAFAAF922AA95DD5920B72B4B8856C6E632860B10F5CC08450003671AF3889",
        "61872B466400ADB815BA81EA794945D19A100622A6CA0D41C4EA620C21DC125119E372418F04402D9FA7180F7BC89AFA",
        "54F8082244A42F46E5B5ABCE87B50A7D6FEBE8D7BBBAC92657CBDA1DB7C25572A4C1D0BAEA30447A865A2B1036B88003",
        "7E2F4D26D453E9E913259779E9169B28A62EB809A5C744E04E260E1F2BBDA874F1AC674839DDB47B3148C5946DE01801",
        "48B7973D63C58193B17CD05D16E80CD7928C2A338363A23A81C0608C87505589B9DA1C617E7B70786B6754FBB30A5816",
        "810B9E126CFCC5AA49326E9D842973874B6359B5DB75610BA68A98C7B5E83F125A82522E13B83FB8F864E2A97B73B5D5",
        "44A7415B6504A13939EAB1595D64FAF41FAB25A864A574DE524405E878339877886D2FC07FA0311508252413EDFA1158",
        "466667AFF78386DAF7CB4C9B850992F96E20525330599AB601D454688E294C8C3E",
    ))
}

fn f512_msg() -> alloc::vec::Vec<u8> {
    from_hex_vec("D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8")
}

fn f512_sig() -> alloc::vec::Vec<u8> {
    from_hex_vec(concat!(
        "2933B3C07507E4201748494D832B6EE2A6C93BFF9B0EE343B550D1F85A3D0DE0D704C6D178429513090765843D1E460D",
        "17A527D2BCA405BD55BBC7DA09A8C620BE0AF4A767D9DB96B80F55E466676751EAABA7B93B86D71132DAA0EB376782B9",
        "EEE37519CE10FDD33FE9F29312C31D8736206D165CF4C528AA3DDC017845E1F0DD5B0A44FF961C42D874A95533E5B438",
        "982F524CA954D87533BFBE42C63FF2ABC77A34C79DB55A99171BBCB72C842A6530AF2F753F0C34AC632F9F1E7949F0BF",
        "6C67665B27722A8857D626B6FF1A136D923A39F4069B7477FF946E5247A6627791D49B59EDC9E2525A860E6E9828D18F",
        "64A9F17222E8166A02453859BBDA0B8186D8C9928BB571E4146401D7430E225904673AD21CCAC54C146C248A1DD69AB6",
        "491E901D6D71B152155BE97DE057F3916A3F1B4273308C29B2F4D9697167B90681B1583ED930A71E990467DEA368134B",
        "ECEEBD597F9BEC922E816F1B0570D728F4AE0464C1F797657F87A4E52DCDCAEB9272662EA66D7C6CD8781B31AF555AD9",
        "3F5F65E75816CB8DC306BB67E592B5261BACA7C509629EA2AF8ABB80CBA89EE535B76DFD9CCBBE3BF48F2BC8AA34B26E",
        "1103291053F5CB8DE3A45AFA5A76DF8B2122ED2C82FBCF2259290D41A14F86B12F35F5D49762B34CFF13EE7E42EDEC70",
        "201D7F37C33316288FA3078E36E58108865C3CFE263D563692043DECC62F3426F86061285B7B1B336F56FF41BB65E9CD",
        "6D9B92FD90F864AA1C923CB8C755F5CDE1770D862595427149D7721AAAB5D194AEA9ACDECA15BE43CBA6A62B5A33909E",
        "9FC4DA1C5814FBD7CD6A2FA572E318B42C6C319140B86E66392580A11A2B431F44C1F9270E4F7B2490F3B325A9977A71",
        "A575915636635B9969DBD6D220B24C3D99CEBBBD834B88222BD08C3ABE124E80",
    ))
}

fn f1024_pk() -> alloc::vec::Vec<u8> {
    from_hex_vec(concat!(
        "0A0441A9B73F494D16556680B12B0F446A652700E4304151BC310683C43F20AB28492FF580708068FA064275C1B0D084",
        "52FC7C324154929CA850D4E6F3425B0F149475A14468C740BE9842D2C1BBB93E2001F4202068D060C1AA9F99A5F67E86",
        "800F2E2A48FCE95A1E9F570A12D4A11B22ACB86716FB6EBB45B6CE1020E7F44E4230103713EC346055D407C969605D9F",
        "76CB8B2F0AF2BBE1AC1F4A278009266FDEEA0AFADA2598E36A492E0B40EAE12539A4B1E44D150D47C192D9895CA08D1E",
        "91D24E535C6D6490038C629045917508CA815E14F401F4A9A5C15E011204D012D0BB71876ABD5A8C75A94F32FE062828",
        "9DB4664A96B45E494D2528EA90781A3098E8DAD76FD583A890EFEFAE861E815DC26894EC5965FE8F389C14ECD77B2032",
        "7C44B202CBDE2B4566B9F73A022FA0641BF81CAAB70E822065B61F5E9FC919238DEAF80BA4C1726DD50C642E39DADA13",
        "EC8935E9936A95766FFDF868C4D95DB2C1A67097225C464EFAA8DE05D806BC5E47F79643180142D5EF53A88E7E06C364",
        "A598779C04830B08E6910495F9938AF193AC54970FED8DB696001256451F91396C67F1A90F8D5D51BA9CA90B217A8F27",
        "DC844096448F75B12C428BD0FF2984600F95B9D601CECAF967C6A062A399AB1FB67DA110239E739E6195A811459F21B4",
        "570F6C077DF858550C4FED907240442ACCFE5195BEF68C2C95756E889378D05F7EDE7223AE27618D6A91105E8C6492D9",
        "ACB30526ACA35976343FD46C1284A4675854BB44E9DCEB32499EA6A4F452DD59400BF096175B060C15E5ED501BEBB24A",
        "9C0CA96DD5F348F66E27488DF0B8954569E46B96A409ADB2D1ACE23889E17AEA253288C545F48B82C12B2956E09C008D",
        "455C93145F638348502314EB271D924CED3B4F5E9FBD3D10B3CEA6778B506121140EE25414EC56A5CE057A2422EA74C0",
        "A021352822E76436636447317A121D4AFD2541008A997B15F3A298DE7587AADC903BA644A859EC40A3D8D75254CBA581",
        "217380F95C33A4D514B946CB573A50B819F8702A35029645B008EB08DEF18552E706F4EFF147C93B683DEDBD6A7CA418",
        "3BD2F5AB3890D5B32C4780BE2054EB151D182D54A502576F395899C6D548C916B4BD058E116243887D56C462A9A616AB",
        "E28204ED5A1A3239C9859264513B02C11F0C30C976C1F6825BB152E8D4A42129A73137031724322322B7928664C32CAC",
        "D0DA7A29FC87C808A2A0CE9194424B077C1EEF54355F03F50A870889868275DBD5268C53B2C9854BBB69FF12F75D1134",
        "38DF3A6F129754CA7622B066ED5B4564266CE011A5804B7BE1C5E24DE1E1719848936A9978C0148F08B2E610090C9958",
        "5D323695AADA1A335A7590F7EE501F284DF5FD1C757E4C9B92EAAF737F20026B299351350C8AA8C1060D7861315012C5",
        "20118E27EA0890CA774205145EE7244C811ED0D2A9CF9ACCC3C5A01C94B480CBD2B41FB7B501850944C2C489089EEA9E",
        "C6639C9A1139B756C40BA120FADA904C7C06772A131858AE2986C2278E5126215E631591505EF1FF281E201BBD149D7A",
        "ACA2926D8CBB2729AA9977E679F5DE62A138EDFC9AD11F09A984E6704E5CAF3F6451010ED3DAB5E0D03573187543FCC6",
        "7AAD6D86BB56138306DE7981EE4C676B19A0ACBDA017FB14014B1E0BD4CBD989A50A9D03EF21F75DB63104EF07C04F94",
        "76167D47ECA3104517BF8DC00B018F9178437C6810E715AE603684755054649E5F8EBA2B337C28AE377674F12B02B428",
        "5CC9D1EC1F459AE88DD4486F30A8FC7FE3D5A6AC84A6DB056D05DC035DE1CB29890B74D05EF4432DE4516C0983FE1965",
        "A001D737C7DE2D885DD3D636E1B7898C9ECB6A9EA7A6A15B4A18D2A1A0F4C877EC01930A75223368A82A22B50A7681D8",
        "8970DE12985F987865F5A5898CD52370123D638AEAB37829B5ABB1DA8C2989EE532AE538535973B022491033167D51C4",
        "6A06B6E17C3183ECA65B7515F865D5308FFD8D698555525CF6D79653597F4E46D126E6D67F142519F1410ADC69589B23",
        "165D0F87EAC5F7DE4F3C13D14B643B608A32D980D125567E9CAD1EB095C4C4BB05D5A9B1EECC3E9AAD4174182841F1E8",
        "C62204116E719FF3474E4663ADA986DCA08C350162298B488BAADDB3761D25CE5114FAB64C979E5FCDAE6A024EF7A806",
        "79A2415AAC324408232363D12285DD33A690B3205175E6C75A85B368F8B1FE5BBB02EAFA624C61938BC2F805E94D001A",
        "AA90E6A2EE8852F82B573D09524DAED64933A03918C87E03BBC5F9A4349308666E83318C968A8486C8A722B1398C8429",
        "A9819A7BF5095739969C03BEADF7937A5DFA16DC7C44A8E3D355900A7D4089A5D300BB690CD8633B4DE36670D9374997",
        "A0309E117630131CB269F4B1EF9EF12980C0F3F40E6423C547B8C142A04D4D54A0054262776887358861228D1052D9F9",
        "60A877F89E0B8768C307C687A683941FA9A473110F87966CB56A81AF94C98C614740C9453999A6D0D3B12DE361AD7375",
        "EBD3022DC2B7626A286A63B8448947CACC",
    ))
}

fn f1024_msg() -> alloc::vec::Vec<u8> {
    from_hex_vec("D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8")
}

fn f1024_sig() -> alloc::vec::Vec<u8> {
    from_hex_vec(concat!(
        "2A33B3C07507E4201748494D832B6EE2A6C93BFF9B0EE343B550D1F85A3D0DE0D704C6D17842951309B49A5B21696C89",
        "5463EADC68BE13293EF2BB36368D1F916EDD6DEDDD17ED7F27061E61E54A91928D34D8FDDB65AF422CD36C2C912C5191",
        "9D278D39C3596DC61947403210A9EB974569B35ABED194889844A36705E7E73F979F9E6FFBB2E211BF5242A9A31E26D5",
        "011BC2D6C919EE34AE048CAC9AED4D2661688F426D167F1B6C608876158C96A5538BCE7E7A46AAA90A28C1CDA418CE8F",
        "D25E6A2C348FDE2584199F77355C4DEFDBA4A1BDF4ECB9DAF632527E629718DDCB7173480A0543359CEEE8E40F991912",
        "2859B889A60A3EBE912761490B8A5EF952EA093252ACF2A90282E96186DDCD283C8B6639CA665902598126720E38D1D9",
        "A9E22026D02E6422169740B57574691D2F349F46E5A062F2AF0D7B5F366F70B95E2B21527B25117E4486D79C20A508A0",
        "29594AE10643A8D7CD6C60CBC998836E8D4A850F358EFDA4C4E902EF7CA7D4C4BA9E44F6D5AFD78ADA910F51849A98F6",
        "CB4F02510CBAB3D1573656FD150984DC14E9B33FBFDAFE4C39A58BC3BFD9AF7E8FA6DDF47C5EB9EC5EFC99BAD9E5F208",
        "6B6C593B3E249D6D63A886816E33F6691E631CE253CBCAACCEADCAFE6FA73AD9E84D89C72199448EA2D092B4AE3186CF",
        "ED4AE763450851B14EB448C9103468BD50A42E56692274AADCD112495414713E77C9D3E510290DD13D8C6F39EBD6F12A",
        "C4B61CD8141D0467EE8D2ABE5B706CAB1AC7E598BC56FCE445B6DE7A4CF329A4AD2E6AA67FD1C9F4BBCFFC6F898FE56D",
        "CCFC43E2D0279AC7CC872F1961FE86B76A4A8297B4F296DD0A4258B79B47B35FCEDAF2E2411B6C0120A2A47916B24121",
        "E3D321C4FD212E54CAAF2DAA4E743D13BEC4769EB489AD82FCA56CDE2449C91DBBD4D8CD27689D2F775B26291429E79E",
        "1DF4F385A94FAFD834C8B523850BF7B770542D6E21AF3BC288645C39DFDBCB85679B2E3360816D5EC246E6D00CA3965F",
        "4AFCEE8A93CDD83353127DE19376F86490542A325954C9218CFCDC3E3F9CE3443BDFB3CAC8AA2CDBFE976638478D284C",
        "5AD67ABB3B857F994B7648CFA9ADFB6305D94A51665A989A69F2DF6A4604FFD5A49646C22DA9E46AC880FFD1B7587CD9",
        "A896BAE2CAA66AA9FB24665631AE7B48C6B1CD02CFC4B1F274F00745219B77589B165C8518135BEDA3ED7931DE7A358C",
        "FB3230762B827FE5258715488238338B4A3F1870CCE759549CC54A743650936FB0F458E20DFBE89A2A5D67C520699D3E",
        "4AD6E2CE1708C49109D671D999A5337798AE5DE53033956B982430589DCEF30FAD98618F572976EA4166CC2ADC0B16F6",
        "551C6A5C37830BE98215EA8A2E97253E2956711D4DE13FAFD141843BBC28A8D44BCBFD523D9AA6405588EC09CE435A68",
        "44DF0B8268B43907B578B61F4C4C6562A1B56E9A1B74D3D17529812B94F49D98B42DD34B9F0E9C7125137D3CBD326CA3",
        "5385313F5196EDC697B9BB204AE4298DDF9F2861B3F445FEC6A8FB6A8C2CFC711178B9864F320E4E108964ED1CB6EE94",
        "AEF722FAAE36A68BC4BDA30439515794F881A397BD782A5432218D2531262EC6B5610DE3D56B47DE5FCA82C1251A6662",
        "21CD747BF90D1E57FBAE4920DDEA69A84320BDB9CB325FE3AB12F97D903085070E9FC2A05489F336C433CF970D937235",
        "152ECA89548EE551AF8F421948C2561F07F3EDE6BCB9DB4AAC15148862BB6659F6D7A15438F39881248F2BC7AD397801",
        "B89446F6CDDD62FE56696C7CBC6473E95A8D03C573E0",
    ))
}

fn f512_c1_pk() -> alloc::vec::Vec<u8> {
    from_hex_vec(concat!(
        "09BACCC8D6C916C9AD12E3E49881F732B84870CE5976921D197A00D226AB8825430DA78F19B0E7A12129ECB739D4A05C",
        "5EBB0019F0C610E14556A0B4C7A48E2E4CC851D2E8A57417E48F918B56DC605D25113451C3B10520F81C016A63C6F2D8",
        "826B90B04D8B0A792272607E39829ADF4B09C0CAFB11CF2F893C56B26420F84901FF072F9100013536822D512792643D",
        "F4EDE4B64200AE0BF82B7D46792EEAE3571F501A9A814E69F21E84DC263457B913957886AF9DA2598003E853AC23B4D6",
        "82971507B85BFEB146010B4B0CDD3F00AF806CBD56A32987E38532AE3C7794058215C5DB042026AC7DFA58EA5B17B8AE",
        "91E06A07DB253E21EFF361EC063412B227FE2CF9592C6B4888589F0A3A7FB9A300B131FC4AE755CE16A1554BE6CE0F4E",
        "8301BB814E2D1903A209F0744687024949876AC94187FCE08655C2131F2A448864CD6C77783EA2DE6C1042C68E389F6D",
        "068EEC2199DC9B6E92EDD4469A923A683AB1C49557C19D9CC9A3822B628862A9E5DF2B152F898172F3C5FDA506C2B21E",
        "10ED39CC1CEBF50B889C493E1B6614A53C30EE7BE94ABE59D83C270350AD490E2F9205E5607AE9328322C60AACACEA9A",
        "F2A12114626964B68AF104AA3B34C1A9E0AE1885314891710B3ACE65F54F40451ABE425FD7AF4218FFD067A2F61E32D8",
        "51831AAB032C0FA95BCC5504FCF8C180A9EA6D14CB23E35DF931C40766468487612A172575D0BA6F20C225AB82A562F0",
        "EEF6D20ED239DA08287DDE67701D2C29368DBE52ACBBE0F219200535ADD286E6EB88E4F1643E922B2ACCBE8A3B52737A",
        "60A4344544966E66B7DA65657B5BDE6343B5987111C6863446C04415E0D985AB534E1D7EAC615DC08E8F3D2A73D60574",
        "18368AD1DFA7001E647876CD50D589765695CF9715739E5D42FA684C51C9077A95E7EB31B87BA1808882B0CD9FA0F5D4",
        "F26D596AF17F22DD09C18836106F5979203B01D10707840C80249F9B963080FD5221C250AE405F5A5D0C312B6EA8971A",
        "998324C542323808CC9A81A42AA9DF3C9080BCB4CF5BD73DFE5C080CEAAA66E0FAE05D88F23B76732BA4094C2D30FD16",
        "D26AC4247291FA2543B7751EFF202113588B76A1646ECC6AA17861DB54D5ADBBFD3AE11423F3A78E8342DEEE705E98BF",
        "8BDA82731A520374C69C6593C5D755C498F7B454C0185758C94B580D4257D66F71EAD38205E2CC717032F18656496424",
        "72C5F34E1854040C63369C8317C1FC37518B16637840A86627113E3809A700CC1B",
    ))
}

fn f512_c1_msg() -> alloc::vec::Vec<u8> {
    from_hex_vec(
        "225D5CE2CEAC61930A07503FB59F7C2F936A3E075481DA3CA299A80F8C5DF9223A073E7B90E02EBF98CA2227EBA38C1AB2568209E46DBA961869C6F83983B17DCD49",
    )
}

fn f512_c1_sig() -> alloc::vec::Vec<u8> {
    from_hex_vec(concat!(
        "2908E25538484CD7F1613248FE6C9F6B4EC14BE684C6DEFDD1E41333B6E9052AC4340E314EEA2C99F7E62B31023EB236",
        "B557957F7174885220923A7763217D9FE59B5BA53157CED51CD4D9AB93B38C666D2047C4FA21AEE43C95EA373F6D62F0",
        "E044BDB0BE988685154EF7682617C7367B30D934B1D9C89229D281734A3005124B8D7C70B78E1634A3A20CCF9AB952C8",
        "16DFAD3D173567C139BDC624512F23F2A0C2F78C2BE16D8F9B119D64BA6DEC5E50AD104D8BA25EDC9E53996F75D848CA",
        "A0E4421167DD4D42D07D39C3E35D10924C1A8A9E098AA4D6112C67DBBF08C7A0888AEB657456C19E2259621EDC3AF897",
        "8DE9C429B8167E679687A86CBB66403FBC6EE69F3F1344D07E845A865F22E5E94D9748CC12065FE1926D83CB288918C8",
        "2D19FD5416DE27576DF8E45DE1BD74351D996514748AE9018D27F57EDB1DE46975FEBA5E6D9BB1491C2A327BF158D03D",
        "2FBE0882EE0ADC9B8121876DD9EF5C37F58D325AF59B94DF324CCE5BC1216C8F4ECD0B4BB5728F83BEEAB09BFE3966CE",
        "BDF4657EC6CFD773F0D5DBA5BF28481DCB21AA1984E9C6D2168E350B4D6491D81967BE0E354C869A8487F0F939F537A5",
        "8DF88ABF2E4FADB55250897A54A8475D160D697A77DA36BBB1438245B35DEE2AC791920C9FAD8025ADC8DFA88B168716",
        "C5A45075A3F9536BCE6238E1AD4D41995D675D3CB71AD4CE33D0326EC2A9F5B9C1DC6750ECAA6AEAAD4C0EDCC4A5015E",
        "B3F7503BA2210B16665F889E4D1CF3A9E298D61B23846593FD4D772C646DD024823371D531094CBB17902DB113796852",
        "161F5D2A12608B3C1BCECE960AAD07952671E4CD6186B7ECFBC7710258B8B26CFA3F1CECC61121A49DD276E4B124E357",
        "3AC8231B60C778E03B74926E2BFBECD42F352BC325CF2204B3C0B5730E6188CFC0",
    ))
}

fn f1024_c1_pk() -> alloc::vec::Vec<u8> {
    from_hex_vec(concat!(
        "0A3D148E18FC1C313AFEAD62E4DDAF6399F6BA5C46F18FED739552CC6145012B8347D5B74E5C1B1194D78CA6C981E782",
        "075AAB0A8A46C6863347A643BBD60B13A8D4E743A258EB9ACC3D1B5D514D9BE217634846266D363417BAE98C07114618",
        "D4CDB77834D28520C98C941CBF9A05ACD202FEFCC11C6729387171B22DC3DAAB6810919E575CB1DE6B0A39AD4A9776D4",
        "190A903BADE1FBC1FA44519B951CC62D6D567E6D7071B6C8A782455D86BCC09570262DB5EBC4E7B7716D4A0A9108542D",
        "628B16863F7CE1D143E2453B2E6C001BBF8F4778D263850C66EA4D75DFD6475CEC58149F48489D108329AE96C78A7F6D",
        "86BA641DA8C812719D5ACDA8E604C64C46D3ADF314E264C7B3E7F217D5237B55A465AF14E582E9C5DE479DC3D98E1447",
        "5AC67F96D18D973F4113ABF986110EB5F5B34141D1B82AD5AB28AEEA7C5E06C123042953B079F546265D9D2D3E84E8AA",
        "0D3C248AEBD5D355108011E193C0E870024EAA4617EF217516327AA68C0312BAAAF0C1FD2E9AA75BE34FBA6E958194DE",
        "CC6A677ABB7793A5CBAED9A0A8FD01D012CAC0A5B22AB4B3383E4B20D27A902228531FEBB482A24A5B090C020BF5EBF9",
        "3CE36A1BEE44EB7BC0119CBC2B43B25ADB6DC02E6AA7E7653E247DC9CFEEED265C07015392FF40324A947F2305926E99",
        "C8F7A45D18481655DDE7E0B002D8D2702EEB3D567E596089A16A2DF352E543BB260C77E1EEA285135A11D101A49E1B86",
        "770A34ABF08E25B7A7E4C9238C841690E3D8E195B560B3D65B9027FE74C632001C0F35F124ED419443F145B95D1BF27B",
        "F276378A69DC1C98BA25E8EC6E4CA25B584A8708B35266171EA58B55099626AB02FF03499C578BA2A85BE127BBF9533B",
        "1478C3281C9C27A56DD6FA50C0973E0C3E43892BB98002E7147201C02D944147F0E7A463297E77FEA89C1D3949348143",
        "E40BB1DA8AFC94F7B1F13277019800908D3B8150D3146AC0E5771C26E8300C03B67D51DBB4B65626A352AE19625FF560",
        "2DC2A8DC8AE67DAB730FDA2813202BDFA42CF4A48B8F6218BCAB760BD96145F479AA4EDAF69B2073014E1A737F994201",
        "0F9A5581F112D44D5F089A1CBE0A755A3AB08E66E9111591101DDB5636914BAD223B383C02DB81BD07F4C7D553466D20",
        "C4F55FB0AE090613186D332744E9B905ED808EACBFF220909FA809B83976E6137ED99AF7CBDAA8BB16274463D7087A2C",
        "84F4706B89354DB8A29CE7275D6AFA50A4CE632476EC36A1CE90B61A32278956A1B16C28C94CEB02413412533FE33A39",
        "7087635B584039E86819E487482F1A6B6BDF003367BD1AB5765109701D8569EFC5257FA91AA37ADE1E19F449616923BB",
        "4BED20C236145A94589AAA999A37AC36F7B0822ECF439D5C99A3A5F1A4F12B090546BEA1C8C192EB66AF25E2D4C5C2C6",
        "3D510003FA836E7E2939B513B9278AA5AEAA5341E973BC01AC5BBDA1567F82C3F44F8FA984798C817BD0BC0E202759C4",
        "AACA058AF8867A8BC2B076724970663789D9D1FA6E55D0AA700884AE54929A155FF07CD293AAF595765B66127DB2E5C6",
        "5129B48AAD3805FD8C8D7C70EA0714D6EDA049A669BBC1A407E97B94FD074B0DEAA823E4908AAE9C23B36A85049FBA98",
        "FA3AC65388E53F386B28A864B9D68A324B9E85FDF4C8EE9D1BB93436BB5D17A12C7D176A52140E4D9618D851D178B4A6",
        "ED317721643CF9844B261274B4FD6EF2911FB30F7286357D14811A2AFAA241847C2E888EF8259883AFE58726B36E6974",
        "C2FA022580245C859E8B36EF295ACAB45AD6CB05AB220081340FDF4BE2FB2826E323B85DFB587FE81F756E7CE00EA5EA",
        "4F8A8804E518F30BC46E321799CAB9A46C69BE594A95E69C664C22AB4E7441C240DD6DBB58DE55279DB182007823746E",
        "FF95BD0BB81F527199D81881036DCB5F8680A8648ADD66CC9C7371855845AA8514C2A1358BCCB97B1C501A9585C248F2",
        "5D9D58B4DD817A611541D51CFADDE7F515C42B792CA1A931947AD5244F1422983758E66255378E9965B5EA87A980A198",
        "60AFF925F5CD19898EADB0F6BF215F20EA1862C2CA5C54AF54395903F2D5373874A0B4BE86DD8224749B341D55019C02",
        "7797D61E18C5305A235620523A51136181F437A4A68B509107AA96571347592B9D6E1DB35FC0DB9334A1831269D9556C",
        "EC52F6D7383238DC0524C2E451F495796E2541743C011B0AEB7D4364D5689646EC4A1650B408107D47EEC153900A9B92",
        "40D3A12C17F36EB88A123B5BBD0451E9F0072676A6CA10028F881752760AB496E3C26E66C478A6134B1CE80FF1E429A1",
        "7A56C7FB171D7C92719F90281760875DC6D81AE6D191C02DF9AB27987D168692D243D7BAD59C28A51A465541744B26C0",
        "511062459A9D42756EA1C7733720E394245D82FCA28545D6DA64482ABBB061BDE5B48954B33C22CA551361459E454875",
        "A43C03A2F89962E97FADE6D4A929E2C807CA2631C6C0C5A87938E38D9056B10E9C51A560D14899F5BA0C50FAB3B28BE1",
        "CD5DD4305CB895224899AA09E6A54E58DC",
    ))
}

fn f1024_c1_msg() -> alloc::vec::Vec<u8> {
    from_hex_vec(
        "225D5CE2CEAC61930A07503FB59F7C2F936A3E075481DA3CA299A80F8C5DF9223A073E7B90E02EBF98CA2227EBA38C1AB2568209E46DBA961869C6F83983B17DCD49",
    )
}

fn f1024_c1_sig() -> alloc::vec::Vec<u8> {
    from_hex_vec(concat!(
        "2A08E25538484CD7F1613248FE6C9F6B4EC14BE684C6DEFDD1E41333B6E9052AC4340E314EEA2C99F7BB38DC6185AFF2",
        "E37B8BDAC450D5A6B92EB3EE618D4601A0CF9E78AC0F31D23EDC6B7EB202BBA65FAD462F2F1A692E7DCAAE7937A9C271",
        "B83316A63E15F485D48217B8FA98905D553E8CDE2F8472585F8A713A272C1C99FF5CAC93D85ABDDC7CB1F0AFBE1EB8C3",
        "9A733685335105EBE7A4E136D866CBBC923C52AC22CD52B6BE9883D3B0C599964DA3DE30E9398E9E41CFAA6D62A333E4",
        "BACCB0DAA45A8F8D1E5974C43BB28CE5A8AE515FC43AEB8B2125E1F46DAD35FAD8C92DFF1A868A709CF3EF971E1FCDA0",
        "EB5CD2844380A3F4A4CDB9146DDB3EDC1AFB403718B4B1E2CE9735D36734F6D4A0655D064CA90A8330C2A1085AC50B9A",
        "0895D34B817D62E5353BDE1C7714477EF1D55F890DB351BADA3B3D4D7682CC3BA933895ACF4DC34AB335AE74BA8B1681",
        "5315ACB3F0C424886ED386B111F8C52D0FC8635774A53341497230AB5F30694AA3784A39325967538694F927CA146722",
        "85B0E9229BB759E219530C24504487B5E1DB9C3CF09D3AED3CFE729A8EA48B3F55AB23452F233C89A1C8FD1A670E7A59",
        "3AC4CB6658B4D47AA20FA87BF7BD9DDE43E546ED3A7897C61B6C0CDF69B430D92DD5DAFFC2C210CBB2B76FE641E2EAB6",
        "7FD38CBDC0E3DCE4052D742B4EAE565DAA76EAB63E0BC925C546581CD2F8DBDAB9938A1DF6718D984E7C9C072BA1E6FA",
        "CB14681BC16B5FB6B1E8009169709CFC3C0996A8E53A08836EF9E1D7196A3AE84CBCDBEAD2653C45AF360B32BB3DFE66",
        "5BCC7238615D54AAEACE222F56EB42B4C9CB3262A89DD308E5630EBA7F05F1C2D34681B2F6686D994B6DB1CDDA8BC3CD",
        "A3313B7C18C7C1D44408EDF57FAC6237E546B7ABAEBA4A60E56B3F63B51FDF29CE712C2626C1C7C20CA36BB35736CEDE",
        "41544EF13C47FC814CB8DB961390808A7C292477222B19E54C56876B7A9877E46C4A0048D4BF64C113244C6205C983B9",
        "65E1F797FE2D4DEB9D944932D81DE325D4B5A80CD4992A4F3C47E1C54821DB7B42990B1B25850C462C5263496642C699",
        "7F728D104313F8AB67817BAC7B0F57536C5E5AA94EFA9EDBEBB17C3704B160C9C9ED960A529541B9D3283D1F9CD56B88",
        "4752A66D93BD22F45E0073E9A8A49AAE485B4C9B69AE30B9329BEFB020D3FD38D4298769B0A020394417CB2058652F89",
        "45F4CBF0638F21719B2CBD7D8B575C9F9A299C8D39CDDCE644BD4BA0ADB254458C9B8D12EC2431D86B51CD9CFE15F92B",
        "295C635ABBE50B9534DBC8E2F6E36F4B94AEEEC4DDC1AEF49C498575DC3EC465A1E73752F41E008DDDB39457654E6A77",
        "C873EBCD4FE08401BB8191EDAC5264232EAB26661C69A74FF702971385DF0E84D818CAA6CC86B984058E81926FDC5510",
        "4E5BC85CE379B583E5B7E5D9CCCDB5DD1531B5688F82B2AEF60A62473A65DA9BF73B02DEA70F0FE9EEABD10FE46368E9",
        "25232DDC8BB1CEBCEADDC020E4964C5ECC9980425BAE656E94E41FE2F19223D8B80AA395F263CEA33C8D2A3DE5D1DA71",
        "CC1766A243478A11D76C3577F4DDD193D839748F4DA9D06A372ACF5C68939FFE93C1B01BAC82409EE21BAC24329A968D",
        "B2E9844C33CD09DEE38EDB1DBF8AF8D71A0DEFBC8D4C5C1362C5B50D492D4AADB2366AC331AF477151CC870B682C18F4",
        "F7B499F6E9D8CF4A230069E06D9C512BD64BB9EED28DAFB6100C08443710E489AA32CF0B09AFC32F6F7F418042367C25",
        "1287CC5192B94D3CD0DA4CDCDEF4B5F7D1C53509EFE4DD74",
    ))
}

#[test]
fn falcon512_kat_count1_accepts() {
    assert!(verify(&f512_c1_pk(), &f512_c1_msg(), &f512_c1_sig()));
}

#[test]
fn falcon1024_kat_count1_accepts() {
    assert!(verify(&f1024_c1_pk(), &f1024_c1_msg(), &f1024_c1_sig()));
}

#[test]
fn falcon512_count1_sig_does_not_verify_under_count0_key() {
    // Different keypair: count=1 signature must fail under count=0's pk.
    assert!(!verify(&f512_pk(), &f512_c1_msg(), &f512_c1_sig()));
}

#[test]
fn falcon512_kat_accepts_known_good() {
    let pk = f512_pk();
    let msg = f512_msg();
    let sig = f512_sig();
    // Sanity on the parameter set detection.
    let key = FalconPublicKey::from_bytes(&pk).expect("pk parses");
    assert_eq!(key.degree(), super::Degree::Falcon512);
    assert!(
        verify(&pk, &msg, &sig),
        "Falcon-512 KAT signature must verify"
    );
}

#[test]
fn falcon1024_kat_accepts_known_good() {
    let pk = f1024_pk();
    let msg = f1024_msg();
    let sig = f1024_sig();
    let key = FalconPublicKey::from_bytes(&pk).expect("pk parses");
    assert_eq!(key.degree(), super::Degree::Falcon1024);
    assert!(
        verify(&pk, &msg, &sig),
        "Falcon-1024 KAT signature must verify"
    );
}

#[test]
fn falcon512_rejects_flipped_signature_bit() {
    let pk = f512_pk();
    let msg = f512_msg();
    // Flip a bit deep in the compressed-s region (past header+nonce).
    let mut sig = f512_sig();
    let idx = 200;
    sig[idx] ^= 0x01;
    assert!(
        !verify(&pk, &msg, &sig),
        "tampered signature must be rejected"
    );
}

#[test]
fn falcon512_rejects_wrong_message() {
    let pk = f512_pk();
    let mut msg = f512_msg();
    msg[0] ^= 0x01;
    let sig = f512_sig();
    assert!(!verify(&pk, &msg, &sig), "wrong message must be rejected");
}

#[test]
fn falcon1024_rejects_flipped_signature_bit() {
    let pk = f1024_pk();
    let msg = f1024_msg();
    let mut sig = f1024_sig();
    sig[300] ^= 0x02;
    assert!(
        !verify(&pk, &msg, &sig),
        "tampered signature must be rejected"
    );
}

#[test]
fn rejects_wrong_parameter_set_pk() {
    // A Falcon-512 signature must not verify under a Falcon-1024 key.
    let pk = f1024_pk();
    let msg = f512_msg();
    let sig = f512_sig();
    assert!(!verify(&pk, &msg, &sig));
}

#[test]
fn rejects_truncated_inputs_without_panic() {
    let pk = f512_pk();
    let msg = f512_msg();
    let sig = f512_sig();
    for cut in [0usize, 1, 40, 41, sig.len() - 1] {
        assert!(!verify(&pk, &msg, &sig[..cut]));
    }
    for cut in [0usize, 1, pk.len() - 1] {
        assert!(!verify(&pk[..cut], &msg, &sig));
    }
    // Empty / garbage never panics.
    assert!(!verify(&[], &msg, &sig));
    assert!(!verify(&[0u8; 4], &msg, &sig));
    assert!(!verify(&pk, &msg, &[]));
}

#[test]
fn rejects_malformed_pk_header() {
    let mut pk = f512_pk();
    pk[0] = 0xFF; // top nibble nonzero + bad logn
    assert!(FalconPublicKey::from_bytes(&pk).is_err());
}

/// A deterministic CSPRNG-shaped source for the public-API tests.
struct TestRng(u64);
impl crate::rng::RngCore for TestRng {
    fn fill_bytes(&mut self, dest: &mut [u8]) {
        for b in dest.iter_mut() {
            self.0 = self
                .0
                .wrapping_mul(0x5851_F42D_4C95_7F2D)
                .wrapping_add(0x1405_7B7E_F767_814F);
            *b = (self.0 >> 56) as u8;
        }
    }
}
impl crate::rng::CryptoRng for TestRng {}

#[test]
fn keypair_generate_sign_verify_and_sk_roundtrip() {
    use super::{Degree, FalconPrivateKey};
    let mut rng = TestRng(0x0FA1_C09A_1C00_DE17);

    let sk = FalconPrivateKey::generate(Degree::Falcon512, &mut rng);
    assert_eq!(sk.degree(), Degree::Falcon512);
    let pk = sk.public_key_bytes();
    let msg = b"the quick brown fox jumps over the lazy dog";

    let sig = sk.sign(msg, &mut rng);
    assert_eq!(sig.len(), Degree::Falcon512.sig_len());
    assert!(verify(&pk, msg, &sig), "generated key must sign-verify");
    assert!(!verify(&pk, b"different message", &sig));

    // The typed public key agrees with the encoded bytes.
    assert_eq!(
        FalconPublicKey::from_bytes(&pk).unwrap().degree(),
        Degree::Falcon512
    );

    // Secret-key serialization round-trip: G and h are recomputed on import,
    // and the reimported key produces verifying signatures.
    let skb = sk.to_bytes();
    let sk2 = FalconPrivateKey::from_bytes(&skb).expect("sk round-trip");
    assert_eq!(
        sk2.public_key_bytes(),
        pk,
        "h must match after sk round-trip"
    );
    let sig2 = sk2.sign(msg, &mut rng);
    assert!(verify(&pk, msg, &sig2), "reimported key must sign-verify");
}