@@ -16,17 +16,17 @@ impl PermutationParameters for PoseidonCairoStark252 {
16
16
const N_MDS_MATRIX_COLS : usize = 3 ;
17
17
18
18
const ROUND_CONSTANTS : & ' static [ FE < Stark252PrimeField > ] =
19
- & PoseidonCairoStark252 :: ROUND_CONSTANTS ;
19
+ & PoseidonCairoStark252 :: OPTIMIZED_ROUND_CONSTANTS ;
20
+
20
21
const N_ROUND_CONSTANTS_ROWS : usize = 91 ;
21
22
const N_ROUND_CONSTANTS_COLS : usize = 3 ;
22
-
23
23
/// Redefined mix function for optimization purposes
24
+ #[ inline( always) ]
24
25
fn mix ( state : & mut [ FE < Self :: F > ] ) {
25
26
let t = & state[ 0 ] + & state[ 1 ] + & state[ 2 ] ;
26
27
state[ 0 ] = & t + & state[ 0 ] . double ( ) ;
27
28
state[ 1 ] = & t - & state[ 1 ] . double ( ) ;
28
- let minus_state_2 = -& state[ 2 ] ;
29
- state[ 2 ] = & t + & minus_state_2 + & minus_state_2 + & minus_state_2;
29
+ state[ 2 ] = & t - ( & state[ 2 ] + & state[ 2 ] + & state[ 2 ] ) ;
30
30
}
31
31
}
32
32
@@ -51,7 +51,10 @@ impl PoseidonCairoStark252 {
51
51
// And the round 0 ones matches the one used
52
52
// in Cairo Lang
53
53
// https://github.com/starkware-libs/cairo-lang/blob/c98fc0b50529185b7018208cb3460191eeb53e0d/src/starkware/cairo/stark_verifier/air/layouts/starknet/autogenerated.cairo#L1574-L1596
54
- pub const ROUND_CONSTANTS : [ FE < Stark252PrimeField > ; 3 * 91 ] = [
54
+ // These constants can be used for an unoptimized implementation of Poseidon, in which three additions need to be performed
55
+ // in each round, regardless if it is a full round or partial round.
56
+ #[ allow( unused) ]
57
+ const UNOPTIMIZED_ROUND_CONSTANTS : [ FE < Stark252PrimeField > ; 3 * 91 ] = [
55
58
FE :: from_hex_unchecked ( "6861759ea556a2339dd92f9562a30b9e58e2ad98109ae4780b7fd8eac77fe6f" ) ,
56
59
FE :: from_hex_unchecked ( "3827681995d5af9ffc8397a3d00425a3da43f76abf28a64e4ab1a22f27508c4" ) ,
57
60
FE :: from_hex_unchecked ( "3a3956d2fad44d0e7f760a2277dc7cb2cac75dc279b2d687a0dbe17704a8309" ) ,
@@ -326,4 +329,166 @@ impl PoseidonCairoStark252 {
326
329
FE :: from_hex_unchecked ( "51274d092db5099f180b1a8a13b7f2c7606836eabd8af54bf1d9ac2dc5717a5" ) ,
327
330
FE :: from_hex_unchecked ( "61fc552b8eb75e17ad0fb7aaa4ca528f415e14f0d9cdbed861a8db0bfff0c5b" ) ,
328
331
] ;
332
+
333
+ // The following constants are used for an optimized version of Poseidon hash, as suggested in Appendix B from
334
+ // the Poseidon paper (available at https://eprint.iacr.org/2019/458.pdf).
335
+ // In partial rounds, instead of adding constants to all the state, we add a constant just to the state
336
+ // to which the S box is applied (non-linear). The constants for the other positions are "moved forward" and
337
+ // added at the end.
338
+ // To get this constants you can use the rust code written at the end of the file
339
+ pub const OPTIMIZED_ROUND_CONSTANTS : [ FE < Stark252PrimeField > ; 107 ] = [
340
+ FE :: from_hex_unchecked ( "6861759ea556a2339dd92f9562a30b9e58e2ad98109ae4780b7fd8eac77fe6f" ) ,
341
+ FE :: from_hex_unchecked ( "3827681995d5af9ffc8397a3d00425a3da43f76abf28a64e4ab1a22f27508c4" ) ,
342
+ FE :: from_hex_unchecked ( "3a3956d2fad44d0e7f760a2277dc7cb2cac75dc279b2d687a0dbe17704a8309" ) ,
343
+ FE :: from_hex_unchecked ( "626c47a7d421fe1f13c4282214aa759291c78f926a2d1c6882031afe67ef4cd" ) ,
344
+ FE :: from_hex_unchecked ( "78985f8e16505035bd6df5518cfd41f2d327fcc948d772cadfe17baca05d6a6" ) ,
345
+ FE :: from_hex_unchecked ( "5427f10867514a3204c659875341243c6e26a68b456dc1d142dcf34341696ff" ) ,
346
+ FE :: from_hex_unchecked ( "5af083f36e4c729454361733f0883c5847cd2c5d9d4cb8b0465e60edce699d7" ) ,
347
+ FE :: from_hex_unchecked ( "7d71701bde3d06d54fa3f74f7b352a52d3975f92ff84b1ac77e709bfd388882" ) ,
348
+ FE :: from_hex_unchecked ( "603da06882019009c26f8a6320a1c5eac1b64f699ffea44e39584467a6b1d3e" ) ,
349
+ FE :: from_hex_unchecked ( "4332a6f6bde2f288e79ce13f47ad1cdeebd8870fd13a36b613b9721f6453a5d" ) ,
350
+ FE :: from_hex_unchecked ( "53d0ebf61664c685310a04c4dec2e7e4b9a813aaeff60d6c9e8caeb5cba78e7" ) ,
351
+ FE :: from_hex_unchecked ( "5346a68894845835ae5ebcb88028d2a6c82f99f928494ee1bfc2d15eaabfebc" ) ,
352
+ FE :: from_hex_unchecked ( "4B085EB1DF4258C3453CC97445954BF3433B6AB9DD5A99592864C00F54A3F9A" ) ,
353
+ FE :: from_hex_unchecked ( "731CFD19D508285965F12A079B2A169FDFE0A8E610E6F2D5CA5D7B0961F6D96" ) ,
354
+ FE :: from_hex_unchecked ( "217D08B5339852BCC6F7A774936B3E72ECD9E1F9A73D743F8079C1E3587EEAA" ) ,
355
+ FE :: from_hex_unchecked ( "C935DD633B0FD63599B13C850DAB3CB966BA510C81B20959E267008518C6E" ) ,
356
+ FE :: from_hex_unchecked ( "52AF8D378DD6772EE187ED23F79A7D98CF5A0A387103971467FE940E7B8B2BE" ) ,
357
+ FE :: from_hex_unchecked ( "294851C98B2682F1EC9918B9F12FCCEAA6E28A7B79B2E506362CDA595F8AB75" ) ,
358
+ FE :: from_hex_unchecked ( "11B59990BACC280824D1021418D4F589DA8C30063471494C204B169AB086064" ) ,
359
+ FE :: from_hex_unchecked ( "4B4DF56E3D7753F91960D59AE099B9BEB2CE690E6BBDCD0B599D49CEB2ACD6A" ) ,
360
+ FE :: from_hex_unchecked ( "5EECFA15A757DC3ECAE9FBD8FF06E466243534F30629FC5F1CF09EB5161AC4" ) ,
361
+ FE :: from_hex_unchecked ( "680BFDD8B9680E04659227634A1EC5282E5A7CEF81B15677F8448BDA4279059" ) ,
362
+ FE :: from_hex_unchecked ( "1D0BF8FAB0A1A7A14E2930794F7A3065C17E10B1CEDD791B8877D97ACD85053" ) ,
363
+ FE :: from_hex_unchecked ( "2C2C8C79F808ACE54BA207053C0D412C0FC11A610F14C48876701A37E32F464" ) ,
364
+ FE :: from_hex_unchecked ( "354EC9ED01D20EC52AAE19A9B858D3474D8234C11AD7BCE630AD56C54AFA562" ) ,
365
+ FE :: from_hex_unchecked ( "30DF20FCF6427BAC38BB5D1A42287F4E4136AC5892340E994E6EA28DEEC1E55" ) ,
366
+ FE :: from_hex_unchecked ( "528CF329C64E7EE3040BAFBDEFF61E241D99B424091E31472EDA296FC9C6778" ) ,
367
+ FE :: from_hex_unchecked ( "40416F24F623534634789660DF5435EBF0C3E0C69E6C5B5FF6E757930BD1960" ) ,
368
+ FE :: from_hex_unchecked ( "380C8F936E2ED9FD488AE3BAC7DCE315BA21B11E88339CD5444435CCC9EA38" ) ,
369
+ FE :: from_hex_unchecked ( "1CC4F5D5603D176F1A8E344392EFD2D03AD0541832829D245E0E2291F255B75" ) ,
370
+ FE :: from_hex_unchecked ( "5728917AF5DA91F9539310D99F5D142E011D6C8E015EA5423C502AA99C09752" ) ,
371
+ FE :: from_hex_unchecked ( "EFB450A9E86E1A46E295A348F0F23590925107D17C56D7C788FECC17219AA1" ) ,
372
+ FE :: from_hex_unchecked ( "2020D74D36C421AE1A025616B342D0784B8FCD977DE6C53A6C26693774DCA99" ) ,
373
+ FE :: from_hex_unchecked ( "7CFB309B75FD3BF2705558AE511DC82335050969F4BF84FA2B7B4F583989287" ) ,
374
+ FE :: from_hex_unchecked ( "4651E48B2E9349A5365E009ECE626809D7B7D02A617EB98C785A784812D75E9" ) ,
375
+ FE :: from_hex_unchecked ( "D77627B270F65122D0269719DA923CCAE822D9AAD0F0947A3B5C8F71C0DCC7" ) ,
376
+ FE :: from_hex_unchecked ( "199AD3D641B54C4D571B3FE37773A8B82B003377F0DD8B7D3B7758C32908EA8" ) ,
377
+ FE :: from_hex_unchecked ( "44F33640A8ECFD3973E2E9172A7333482B2D297BE2DA289319E72D137CDFE6E" ) ,
378
+ FE :: from_hex_unchecked ( "7E4ADF9894D964189D00A02DCF1E6BE7F801234F5216EAB6B6F366B6701ABF7" ) ,
379
+ FE :: from_hex_unchecked ( "3641FA5B3C90452F5FF808F8A9817EDA7C6AECFB5471DFDCA559FB4E711EE90" ) ,
380
+ FE :: from_hex_unchecked ( "3DE5729EFD2FCBD897A49A78FA923FC306DF32E6E2F0E02D0EEE2C2CC3F3533" ) ,
381
+ FE :: from_hex_unchecked ( "62691891A3FC1E27F622966CA0BE20C06563500C8F06C9BDB77BD2882D6C994" ) ,
382
+ FE :: from_hex_unchecked ( "6608D3BF11C18E4688739F72205763D1590CC4F9885AE1D86E96E0604BAA0BE" ) ,
383
+ FE :: from_hex_unchecked ( "11C9C9B39CAC71E3419726CE779116D07249F51CBDDA4FD98C25CBBF593A316" ) ,
384
+ FE :: from_hex_unchecked ( "61E23B58203269CAEF0850F74DA27B9748E3312EA40C6844DD68C557C462AD7" ) ,
385
+ FE :: from_hex_unchecked ( "4182CD9AB1D9488F870A572010BC2A3D9878440B25951E4CE010855CF83BDC8" ) ,
386
+ FE :: from_hex_unchecked ( "520FE6C4A096793F9055E6823116D15F1DF2FE89D306F9965F6A59F4F3ECB71" ) ,
387
+ FE :: from_hex_unchecked ( "346B2B2D6E5810129E093093DCD3DFA99ED6D71F47723EA3FBE4D4E2FD4AFA1" ) ,
388
+ FE :: from_hex_unchecked ( "1359CA923E7F1448EC1DD2A3684BEE4E8B682C8E8E973ACEA72877CE9F7E6CF" ) ,
389
+ FE :: from_hex_unchecked ( "47C655F55CF307800DFEFDAD24DE86FDE9DEADAB145A1B392420F37B95D9675" ) ,
390
+ FE :: from_hex_unchecked ( "4AB291F16555FA8A968CD7C9C285A9598EFD925F2D58B7AA38AD87DCA8441A8" ) ,
391
+ FE :: from_hex_unchecked ( "39F409C7C782101223D1F6F7D86C21A22C44EF959510E392C9C7C5D17C629C5" ) ,
392
+ FE :: from_hex_unchecked ( "44BE36B782F882AD86EECB0CD6BEB02E1A2F9FB5587A3BABFACEAD0CAFB6052" ) ,
393
+ FE :: from_hex_unchecked ( "50A1DFDE9B504AD2906DB6EB5B507203CD1CEB394C52CE7107679A53A0D538B" ) ,
394
+ FE :: from_hex_unchecked ( "5C753C14DA89E287B181C0DD11AC6C3680BDD7F1017DAE083E7AEBBEAB183AB" ) ,
395
+ FE :: from_hex_unchecked ( "2CF6306ED32232106C8015A3B180F386EEE93E15F7B4F4FA57746525FC0520C" ) ,
396
+ FE :: from_hex_unchecked ( "2C2014634D52E27420873CF347429091DFC6380689BD4F54D7D8E502C1C3A09" ) ,
397
+ FE :: from_hex_unchecked ( "3CFB9C5BD93E02B2FDACDE2058E33E5975C446345F010D850FC09CDF86ED8A1" ) ,
398
+ FE :: from_hex_unchecked ( "363FA71A383CF3897933F1411FC5F806E311E84F72CB50A9EA4E1281F6B0299" ) ,
399
+ FE :: from_hex_unchecked ( "728199657067EE16947B3FC76271676B4901B2A3686CFFEBCB960DA91B05DF8" ) ,
400
+ FE :: from_hex_unchecked ( "3FDFBD47D27F3D34F0723B728E8921DC9BDE34A9872DF5A652A078D7E4EE021" ) ,
401
+ FE :: from_hex_unchecked ( "7F241379440CACD7DC0EFBE7858EB7DE53CC02CA7D24197945C453398EFF449" ) ,
402
+ FE :: from_hex_unchecked ( "5B2E8771EA9A0004E3BF056F3727797CBB457A27574D5F104354E52A5C25F0B" ) ,
403
+ FE :: from_hex_unchecked ( "A8DDBCE708DE44A7E0B3B0333146E1E910245BE6BF822EA057A081BDA2E23E" ) ,
404
+ FE :: from_hex_unchecked ( "2D521E0DACA24E431AA47CD90A0F551C12270E533835613EDCE2E19AA9B0F61" ) ,
405
+ FE :: from_hex_unchecked ( "6CDBC0F2AA54D2CF7D5AC3B93F855AF03EEF7B07AAEE00341A6266C30E08AE6" ) ,
406
+ FE :: from_hex_unchecked ( "3DD96A17111EC8F4C5DA3AD6794C0961CEEE452CBE92C7A0941112B36ED9BF3" ) ,
407
+ FE :: from_hex_unchecked ( "5EAFB1EDEEDC5C07AC07FDD06159344A2CFB92196A65D9EC0C5E732C36687DC" ) ,
408
+ FE :: from_hex_unchecked ( "4AB038D7B09EDA9324577B260FEAEBDBCEC5A7B7C7F449B312CFCD065C207E6" ) ,
409
+ FE :: from_hex_unchecked ( "4CA71981E4DF6B505D2B0D94E235608463C58052570F68E495FC80C7FDEF220" ) ,
410
+ FE :: from_hex_unchecked ( "6DEE9C6DA4617E32AA419899C8EA8137E9B59D7E2759FFE573C15B77E413D2F" ) ,
411
+ FE :: from_hex_unchecked ( "58F9E60B34DDAB84DCBE2396065A4305B4A795A4770E4541E625D0460C6F186" ) ,
412
+ FE :: from_hex_unchecked ( "47B7B4A802A10C1E6C9C735DB6C34042D290906F274BEA8FCECEF17FC9AF632" ) ,
413
+ FE :: from_hex_unchecked ( "1849BCDB9AD7171096ECC936A186774084A074BE0BFC0FBB9463A06A2BD430C" ) ,
414
+ FE :: from_hex_unchecked ( "41870FBE04438348AF5767BDDAECD8AEA3B49B4217547DEC4D699B1466736CC" ) ,
415
+ FE :: from_hex_unchecked ( "226C04E598076A9FA02AA64557DAF28C0EC42E3D4DA68D1965029D284738B07" ) ,
416
+ FE :: from_hex_unchecked ( "1F0E971F0485A5B42EB92D6655C3DDB475CEC4371F269A95335B2A7D6DAC0FB" ) ,
417
+ FE :: from_hex_unchecked ( "9F31CC2907DCCBF994D35AA47EE3F4EBDF3703F795047A7B40DD3926431563" ) ,
418
+ FE :: from_hex_unchecked ( "4B40CCE78F3B641E31CE4DF58CE5A42C22CFBC198C84451FFE8CCA4C64BD7D2" ) ,
419
+ FE :: from_hex_unchecked ( "191660489E4BD8A3E4563173DE4A226F3AC736962FDFB70F72CB93CE50F8B9F" ) ,
420
+ FE :: from_hex_unchecked ( "18C0919618DB971F74EB01F293F2DAEA814B475103373DC7ED8DD4C7B467410" ) ,
421
+ FE :: from_hex_unchecked ( "35B60253848530E845C8753121577D0EF37002E941C3DC1FB240BD57EADC803" ) ,
422
+ FE :: from_hex_unchecked ( "1AE99DB1575AE91C8B43A9F71A5F362581AD9B413D97FA6FD029134957451D5" ) ,
423
+ FE :: from_hex_unchecked ( "3E6E1D0F3F8A0F728148EBCBD5D7D337D7CB8FEB58A37D2D1DFB357E172647B" ) ,
424
+ FE :: from_hex_unchecked ( "18BC36DFFA8F96A659E1A171B55D2706EE3E9AD619E16F5C38DD1F4A209B8F3" ) ,
425
+ FE :: from_hex_unchecked ( "2C7A3EF1AFB6A302B54AFC3A107FF9199A16EFE9A1CC3AB83FA5B64893DE4ED" ) ,
426
+ FE :: from_hex_unchecked ( "53A7BD889BED07BF5E27DD8E92F6AE85E4FE4E84B0C6DDE9856E94469DE4BD7" ) ,
427
+ FE :: from_hex_unchecked ( "4D383FF7FFC6318FDA704ACA35995F86BEC5A02CE9A0BF9D3CC0CC2F03CCEA9" ) ,
428
+ FE :: from_hex_unchecked ( "4667B6762FB8AD53D07EF7E8A65B21CA96E0B3503037710D1292519C326F5CD" ) ,
429
+ FE :: from_hex_unchecked ( "2CC8B43E75CF0B42A93C39EA98BCD46055DCCC9589F02EB7FB536422E5921F" ) ,
430
+ FE :: from_hex_unchecked ( "6B32EE98680871D38751447BFD76086BA4DF0E7BE59C55F4B2CE25582BF9C60" ) ,
431
+ FE :: from_hex_unchecked ( "3E907927C7182FAAA3B3C81358B82E734EFAC1F0609F0862D635CB1387102A3" ) ,
432
+ FE :: from_hex_unchecked ( "3F3A5057B3A08975F0253728E512AF78D2F437973F6A93793EA5E8424FBC6EA" ) ,
433
+ FE :: from_hex_unchecked ( "14B491D73724779F8AA74B3FD8AA5821C21E1017224726A7A946BB6CA68D8F5" ) ,
434
+ FE :: from_hex_unchecked ( "5C8278C7BBFC30AE7F60E514FE3B9367ACA84C54AD1373861695EA4ABB814EF" ) ,
435
+ FE :: from_hex_unchecked ( "64851937F9836EE5A08A7DDE65E44B467018A82BA3BF99BBA0B4502755C8074" ) ,
436
+ FE :: from_hex_unchecked ( "6A9AC84251294769ECA450FFB52B441882BE77CB85F422FF9EA5E73F1D971DC" ) ,
437
+ FE :: from_hex_unchecked ( "37EC35B710B0D04C9A2B71F2F7BD098C6A81D991D27F0FC1884F5CA545064DE" ) ,
438
+ FE :: from_hex_unchecked ( "5334f75b052c0235119816883040da72c6d0a61538bdfff46d6a242bfeb7a1" ) ,
439
+ FE :: from_hex_unchecked ( "5d0af4fcbd9e056c1020cca9d871ae68f80ee4af2ec6547cd49d6dca50aa431" ) ,
440
+ FE :: from_hex_unchecked ( "30131bce2fba5694114a19c46d24e00b4699dc00f1d53ba5ab99537901b1e65" ) ,
441
+ FE :: from_hex_unchecked ( "5646a95a7c1ae86b34c0750ed2e641c538f93f13161be3c4957660f2e788965" ) ,
442
+ FE :: from_hex_unchecked ( "4b9f291d7b430c79fac36230a11f43e78581f5259692b52c90df47b7d4ec01a" ) ,
443
+ FE :: from_hex_unchecked ( "5006d393d3480f41a98f19127072dc83e00becf6ceb4d73d890e74abae01a13" ) ,
444
+ FE :: from_hex_unchecked ( "62c9d42199f3b260e7cb8a115143106acf4f702e6b346fd202dc3b26a679d80" ) ,
445
+ FE :: from_hex_unchecked ( "51274d092db5099f180b1a8a13b7f2c7606836eabd8af54bf1d9ac2dc5717a5" ) ,
446
+ FE :: from_hex_unchecked ( "61fc552b8eb75e17ad0fb7aaa4ca528f415e14f0d9cdbed861a8db0bfff0c5b" ) ,
447
+ ] ;
448
+
449
+ // The following function allows to compute the optimized partial round constants.
450
+ // How to move forward the constants:
451
+ // M*S(s+c) where s is the state, c the first partial-round constant. We decompose c = c'+c'' where c' has all zeros
452
+ // except for the non-linear position, c'' has a zero in the non-linear position.
453
+ // M*S(s+c) = M*S(s+c')+M*c''
454
+ // We repeat this process as many times as partial rounds we have.
455
+ // Notice that the first constant for the next full round will change
456
+
457
+ /* pub fn compute_new_constants() -> String {
458
+ let mut res = String::from("");
459
+ let three: FE<Stark252PrimeField> = FE::from_hex_unchecked("3");
460
+
461
+ let mut i = 4;
462
+ let mut c_next: [FE<Stark252PrimeField>; 3] = [FE::zero(), FE::zero(), FE::zero()];
463
+ let mut c_current: [FE<Stark252PrimeField>; 3];
464
+
465
+ while i <= 86 {
466
+ let index = 3 * i;
467
+ c_current = [
468
+ Self::UNOPTIMIZED_ROUND_CONSTANTS[index] + c_next[0],
469
+ Self::UNOPTIMIZED_ROUND_CONSTANTS[index + 1] + c_next[1],
470
+ Self::UNOPTIMIZED_ROUND_CONSTANTS[index + 2] + c_next[2],
471
+ ];
472
+
473
+ c_next = [
474
+ three * c_current[0] + c_current[1],
475
+ c_current[0] - c_current[1],
476
+ c_current[0] + c_current[1],
477
+ ];
478
+ res = format!(
479
+ "{}, \n FE::from_hex_unchecked(\"{}\")",
480
+ res,
481
+ c_current[2].representative().to_hex()
482
+ );
483
+ if i == 86 {
484
+ c_next[0] += Self::UNOPTIMIZED_ROUND_CONSTANTS[3 * 87];
485
+ c_next[1] += Self::UNOPTIMIZED_ROUND_CONSTANTS[3 * 87 + 1];
486
+ c_next[2] += Self::UNOPTIMIZED_ROUND_CONSTANTS[3 * 87 + 2];
487
+ res = format!("{}, Last constant: \n FE::from_hex_unchecked(\"{}\"), \n FE::from_hex_unchecked(\"{}\"), \n FE::from_hex_unchecked(\"{}\")", res, c_next[0].representative().to_hex(), c_next[1].representative().to_hex(),c_next[2].representative().to_hex());
488
+ }
489
+ i += 1;
490
+ }
491
+ res
492
+ }
493
+ */
329
494
}
0 commit comments