diff --git a/barretenberg/cpp/pil/vm2/execution.pil b/barretenberg/cpp/pil/vm2/execution.pil index 5aa3f8d1791..0ec6d222722 100644 --- a/barretenberg/cpp/pil/vm2/execution.pil +++ b/barretenberg/cpp/pil/vm2/execution.pil @@ -9,6 +9,8 @@ include "bitwise.pil"; include "precomputed.pil"; include "sha256.pil"; include "ecc.pil"; +include "poseidon2_hash.pil"; +include "poseidon2_perm.pil"; namespace execution; diff --git a/barretenberg/cpp/pil/vm2/poseidon2_hash.pil b/barretenberg/cpp/pil/vm2/poseidon2_hash.pil new file mode 100644 index 00000000000..3e41adbcf56 --- /dev/null +++ b/barretenberg/cpp/pil/vm2/poseidon2_hash.pil @@ -0,0 +1,92 @@ +include "poseidon2_perm.pil"; + +// Performs the poseidon2 full hash +// It is **mostly** well-constrained +namespace poseidon2_hash; + + #[skippable_if] + sel = 0; + + // These are the inputs to be hashed this round, we hash chunks of 3 field elements + pol commit input_0; + pol commit input_1; + pol commit input_2; + + // Output of the hash it is matched with the result of the last permutation round + pol commit output; + + pol commit sel; + sel * (1 - sel) = 0; + sel = execute_perm + end; + pol TWOPOW64 = 18446744073709551616; + + pol commit input_len; + // Only used at the start of a new poseidon2 hash + pol IV = TWOPOW64 * input_len; + + + // Start of a poseidon2 computation + pol commit start; + start * (1 - start) = 0; + // When we end a poseidon, the next row must naturally have a start + sel' * (1 - precomputed.first_row) * (start' - end) = 0; + + // We track the num of rounds remaining, excluding the first round that has to be performed by the start selector. + // We use the padded length to calculate the num of rounds to perform and the unpadded length is used in the IV. + pol commit num_perm_rounds_rem; + pol commit padding; + // Padding can either be 0, 1 or 2 + padding * (padding - 1) * (padding - 2) = 0; + pol PADDED_LEN = input_len + padding; + start * ((num_perm_rounds_rem + 1) * 3 - PADDED_LEN) = 0; + + + // The row with the final result of the poseidon computation + pol commit end; + end * (1 - end) = 0; + // The final result of the output of the hash should match the output from the last permutation (b_0) + end * (output - b_0) = 0; + pol commit num_perm_rounds_rem_inv; + // end == 1 when the num_perm_rounds_rem == 0 + sel * (num_perm_rounds_rem * (end * (1 - num_perm_rounds_rem_inv) + num_perm_rounds_rem_inv) - 1 + end) = 0; + + // We perform the "squeeze" / perm operation until end + pol commit execute_perm; + execute_perm * (1 - execute_perm) = 0; + // The squeeze and end selector must be mutually exclusive + sel * (1 - end - execute_perm) = 0; + // Need an additional helper that holds the inverse of the num_perm_rounds_rem; + // If we still have rounds to perform, the num_perm_rounds_rem is decremented + execute_perm * (num_perm_rounds_rem' - num_perm_rounds_rem + 1) = 0; + + + // The input values are represented by a_0, a_1, a_2, a_3 + // This most definitely could be simplified to a lower degree check + // the next perm input is constrained to be the previous perm output + the new values to be hashed. + // This occurs when we execute_perm = 1 and we are not the start or the end of the poseidon perm + pol NEXT_INPUT_IS_PREV_OUTPUT_SEL = execute_perm' * (1 - start) * execute_perm; + pol commit a_0; + start * (a_0 - input_0) = 0; + sel * NEXT_INPUT_IS_PREV_OUTPUT_SEL * (a_0' - b_0 - input_0') = 0; + pol commit a_1; + start * (a_1 - input_1) = 0; + sel * NEXT_INPUT_IS_PREV_OUTPUT_SEL * (a_1' - b_1 - input_1') = 0; + pol commit a_2; + start * (a_2 - input_2) = 0; + sel * NEXT_INPUT_IS_PREV_OUTPUT_SEL * (a_2' - b_2 - input_2') = 0; + pol commit a_3; + start * (a_3 - IV) = 0; // IV is placed in the last slot if this is the start + sel * NEXT_INPUT_IS_PREV_OUTPUT_SEL * (a_3' - b_3) = 0; + + // Output value represented by b_0 + pol commit b_0; + pol commit b_1; + pol commit b_2; + pol commit b_3; + + #[LOOKUP_POS2_PERM] + sel { a_0, a_1, a_2, a_3, b_0, b_1, b_2, b_3} + in + poseidon2_perm.sel + { poseidon2_perm.a_0, poseidon2_perm.a_1, poseidon2_perm.a_2, poseidon2_perm.a_3, + poseidon2_perm.b_0, poseidon2_perm.b_1, poseidon2_perm.b_2, poseidon2_perm.b_3 }; diff --git a/barretenberg/cpp/pil/vm2/poseidon2_params.pil b/barretenberg/cpp/pil/vm2/poseidon2_params.pil new file mode 100644 index 00000000000..1074146a0fd --- /dev/null +++ b/barretenberg/cpp/pil/vm2/poseidon2_params.pil @@ -0,0 +1,336 @@ +// Values taken from barretenberg/crypto/poseidon2/poseidon2_params.hpp + +// Parameters for Poseidon for bn254. +// 64 total rounds (8 full rounds and 56 partial rounds) +// Total rate (t) of 4; +// Alpha (exponentiation): 5 +namespace poseidon2_params; + // Internal Matrix Diagonal (for partial rounds) + pol MU_0 = 7626475329478847982857743246276194948757851985510858890691733676098590062311; + pol MU_1 = 5498568565063849786384470689962419967523752476452646391422913716315471115275; + pol MU_2 = 148936322117705719734052984176402258788283488576388928671173547788498414613; + pol MU_3 = 15456385653678559339152734484033356164266089951521103188900320352052358038155; + + // Round constants + // Naming scheme is c_{round_count}_{input_count} where the counts are zero-indexed + // So the round constant applied in the 5th round to the 3rd input is c_4_2 + // Round 1 constants + pol C_0_0 = 11633431549750490989983886834189948010834808234699737327785600195936805266405; + pol C_0_1 = 17353750182810071758476407404624088842693631054828301270920107619055744005334; + pol C_0_2 = 11575173631114898451293296430061690731976535592475236587664058405912382527658; + pol C_0_3 = 9724643380371653925020965751082872123058642683375812487991079305063678725624; + // Round 2 constants + pol C_1_0 = 20936725237749945635418633443468987188819556232926135747685274666391889856770; + pol C_1_1 = 6427758822462294912934022562310355233516927282963039741999349770315205779230; + pol C_1_2 = 16782979953202249973699352594809882974187694538612412531558950864304931387798; + pol C_1_3 = 8979171037234948998646722737761679613767384188475887657669871981433930833742; + // Round 3 constants + pol C_2_0 = 5428827536651017352121626533783677797977876323745420084354839999137145767736; + pol C_2_1 = 507241738797493565802569310165979445570507129759637903167193063764556368390; + pol C_2_2 = 6711578168107599474498163409443059675558516582274824463959700553865920673097; + pol C_2_3 = 2197359304646916921018958991647650011119043556688567376178243393652789311643; + // Round 4 constants + pol C_3_0 = 4634703622846121403803831560584049007806112989824652272428991253572845447400; + pol C_3_1 = 17008376818199175111793852447685303011746023680921106348278379453039148937791; + pol C_3_2 = 18430784755956196942937899353653692286521408688385681805132578732731487278753; + pol C_3_3 = 4573768376486344895797915946239137669624900197544620153250805961657870918727; + // Round 5 constants + pol C_4_0 = 5624865188680173294191042415227598609140934495743721047183803859030618890703; + pol C_4_1 = 0; + pol C_4_2 = 0; + pol C_4_3 = 0; + // Round 6 constants + pol C_5_0 = 8228252753786907198149068514193371173033070694924002912950645971088002709521; + pol C_5_1 = 0; + pol C_5_2 = 0; + pol C_5_3 = 0; + // Round 7 constants + pol C_6_0 = 17586714789554691446538331362711502394998837215506284064347036653995353304693; + pol C_6_1 = 0; + pol C_6_2 = 0; + pol C_6_3 = 0; + // Round 8 constants + pol C_7_0 = 12985198716830497423350597750558817467658937953000235442251074063454897365701; + pol C_7_1 = 0; + pol C_7_2 = 0; + pol C_7_3 = 0; + // Round 9 constants + pol C_8_0 = 13480076116139680784838493959937969792577589073830107110893279354229821035984; + pol C_8_1 = 0; + pol C_8_2 = 0; + pol C_8_3 = 0; + // Round 10 constants + pol C_9_0 = 480609231761423388761863647137314056373740727639536352979673303078459561332; + pol C_9_1 = 0; + pol C_9_2 = 0; + pol C_9_3 = 0; + // Round 11 constants + pol C_10_0 = 19503345496799249258956440299354839375920540225688429628121751361906635419276; + pol C_10_1 = 0; + pol C_10_2 = 0; + pol C_10_3 = 0; + // Round 12 constants + pol C_11_0 = 16837818502122887883669221005435922946567532037624537243846974433811447595173; + pol C_11_1 = 0; + pol C_11_2 = 0; + pol C_11_3 = 0; + // Round 13 constants + pol C_12_0 = 5492108497278641078569490709794391352213168666744080628008171695469579703581; + pol C_12_1 = 0; + pol C_12_2 = 0; + pol C_12_3 = 0; + // Round 14 constants + pol C_13_0 = 11365311159988448419785032079155356000691294261495515880484003277443744617083; + pol C_13_1 = 0; + pol C_13_2 = 0; + pol C_13_3 = 0; + // Round 15 constants + pol C_14_0 = 13876891705632851072613751905778242936713392247975808888614530203269491723653; + pol C_14_1 = 0; + pol C_14_2 = 0; + pol C_14_3 = 0; + // Round 16 constants + pol C_15_0 = 10660388389107698747692475159023710744797290186015856503629656779989214850043; + pol C_15_1 = 0; + pol C_15_2 = 0; + pol C_15_3 = 0; + // Round 17 constants + pol C_16_0 = 18876318870401623474401728758498150977988613254023317877612912724282285739292; + pol C_16_1 = 0; + pol C_16_2 = 0; + pol C_16_3 = 0; + // Round 18 constants + pol C_17_0 = 15543349138237018307536452195922365893694804703361435879256942490123776892424; + pol C_17_1 = 0; + pol C_17_2 = 0; + pol C_17_3 = 0; + // Round 19 constants + pol C_18_0 = 2839988449157209999638903652853828318645773519300826410959678570041742458201; + pol C_18_1 = 0; + pol C_18_2 = 0; + pol C_18_3 = 0; + // Round 20 constants + pol C_19_0 = 7566039810305694135184226097163626060317478635973510706368412858136696413063; + pol C_19_1 = 0; + pol C_19_2 = 0; + pol C_19_3 = 0; + // Round 21 constants + pol C_20_0 = 6344830340705033582410486810600848473125256338903726340728639711688240744220; + pol C_20_1 = 0; + pol C_20_2 = 0; + pol C_20_3 = 0; + // Round 22 constants + pol C_21_0 = 12475357769019880256619207099578191648078162511547701737481203260317463892731; + pol C_21_1 = 0; + pol C_21_2 = 0; + pol C_21_3 = 0; + // Round 23 constants + pol C_22_0 = 13337401254840718303633782478677852514218549070508887338718446132574012311307; + pol C_22_1 = 0; + pol C_22_2 = 0; + pol C_22_3 = 0; + // Round 24 constants + pol C_23_0 = 21161869193849404954234950798647336336709035097706159414187214758702055364571; + pol C_23_1 = 0; + pol C_23_2 = 0; + pol C_23_3 = 0; + // Round 25 constants + pol C_24_0 = 20671052961616073313397254362345395594858011165315285344464242404604146448678; + pol C_24_1 = 0; + pol C_24_2 = 0; + pol C_24_3 = 0; + // Round 26 constants + pol C_25_0 = 2772189387845778213446441819361180378678387127454165972767013098872140927416; + pol C_25_1 = 0; + pol C_25_2 = 0; + pol C_25_3 = 0; + // Round 27 constants + pol C_26_0 = 3339032002224218054945450150550795352855387702520990006196627537441898997147; + pol C_26_1 = 0; + pol C_26_2 = 0; + pol C_26_3 = 0; + // Round 28 constants + pol C_27_0 = 14919705931281848425960108279746818433850049439186607267862213649460469542157; + pol C_27_1 = 0; + pol C_27_2 = 0; + pol C_27_3 = 0; + // Round 29 constants + pol C_28_0 = 17056699976793486403099510941807022658662936611123286147276760381688934087770; + pol C_28_1 = 0; + pol C_28_2 = 0; + pol C_28_3 = 0; + // Round 30 constants + pol C_29_0 = 16144580075268719403964467603213740327573316872987042261854346306108421013323; + pol C_29_1 = 0; + pol C_29_2 = 0; + pol C_29_3 = 0; + // Round 31 constants + pol C_30_0 = 15582343953927413680541644067712456296539774919658221087452235772880573393376; + pol C_30_1 = 0; + pol C_30_2 = 0; + pol C_30_3 = 0; + // Round 32 constants + pol C_31_0 = 17528510080741946423534916423363640132610906812668323263058626230135522155749; + pol C_31_1 = 0; + pol C_31_2 = 0; + pol C_31_3 = 0; + // Round 33 constants + pol C_32_0 = 3190600034239022251529646836642735752388641846393941612827022280601486805721; + pol C_32_1 = 0; + pol C_32_2 = 0; + pol C_32_3 = 0; + // Round 34 constants + pol C_33_0 = 8463814172152682468446984305780323150741498069701538916468821815030498611418; + pol C_33_1 = 0; + pol C_33_2 = 0; + pol C_33_3 = 0; + // Round 35 constants + pol C_34_0 = 16533435971270903741871235576178437313873873358463959658178441562520661055273; + pol C_34_1 = 0; + pol C_34_2 = 0; + pol C_34_3 = 0; + // Round 36 constants + pol C_35_0 = 11845696835505436397913764735273748291716405946246049903478361223369666046634; + pol C_35_1 = 0; + pol C_35_2 = 0; + pol C_35_3 = 0; + // Round 37 constants + pol C_36_0 = 18391057370973634202531308463652130631065370546571735004701144829951670507215; + pol C_36_1 = 0; + pol C_36_2 = 0; + pol C_36_3 = 0; + // Round 38 constants + pol C_37_0 = 262537877325812689820791215463881982531707709719292538608229687240243203710; + pol C_37_1 = 0; + pol C_37_2 = 0; + pol C_37_3 = 0; + // Round 39 constants + pol C_38_0 = 2187234489894387585309965540987639130975753519805550941279098789852422770021; + pol C_38_1 = 0; + pol C_38_2 = 0; + pol C_38_3 = 0; + // Round 40 constants + pol C_39_0 = 19189656350920455659006418422409390013967064310525314160026356916172976152967; + pol C_39_1 = 0; + pol C_39_2 = 0; + pol C_39_3 = 0; + // Round 41 constants + pol C_40_0 = 15839474183930359560478122372067744245080413846070743460407578046890458719219; + pol C_40_1 = 0; + pol C_40_2 = 0; + pol C_40_3 = 0; + // Round 42 constants + pol C_41_0 = 1805019124769763805045852541831585930225376844141668951787801647576910524592; + pol C_41_1 = 0; + pol C_41_2 = 0; + pol C_41_3 = 0; + // Round 43 constants + pol C_42_0 = 323592203814803486950280155834638828455175703393817797003361354810251742052; + pol C_42_1 = 0; + pol C_42_2 = 0; + pol C_42_3 = 0; + // Round 44 constants + pol C_43_0 = 9780393509796825017346015868945480913627956475147371732521398519483580624282; + pol C_43_1 = 0; + pol C_43_2 = 0; + pol C_43_3 = 0; + // Round 45 constants + pol C_44_0 = 14009429785059642386335012561867511048847749030947687313594053997432177705759; + pol C_44_1 = 0; + pol C_44_2 = 0; + pol C_44_3 = 0; + // Round 46 constants + pol C_45_0 = 13749550162460745037234826077137388777330401847577727796245150843898019635981; + pol C_45_1 = 0; + pol C_45_2 = 0; + pol C_45_3 = 0; + // Round 47 constants + pol C_46_0 = 19497187499283431845443758879472819384797584633472792651343926414232528405311; + pol C_46_1 = 0; + pol C_46_2 = 0; + pol C_46_3 = 0; + // Round 48 constants + pol C_47_0 = 3708428802547661961864524194762556064568867603968214870300574294082023305587; + pol C_47_1 = 0; + pol C_47_2 = 0; + pol C_47_3 = 0; + // Round 49 constants + pol C_48_0 = 1339414413482882567499652761996854155383863472782829777976929310155400981782; + pol C_48_1 = 0; + pol C_48_2 = 0; + pol C_48_3 = 0; + // Round 50 constants + pol C_49_0 = 6396261245879814100794661157306877072718690153118140891315137894471052482309; + pol C_49_1 = 0; + pol C_49_2 = 0; + pol C_49_3 = 0; + // Round 51 constants + pol C_50_0 = 2069661495404347929962833138824526893650803079024564477269192079629046031674; + pol C_50_1 = 0; + pol C_50_2 = 0; + pol C_50_3 = 0; + // Round 52 constants + pol C_51_0 = 15793521554502133342917616035884588152451122589545915605459159078589855944361; + pol C_51_1 = 0; + pol C_51_2 = 0; + pol C_51_3 = 0; + // Round 53 constants + pol C_52_0 = 17053424498357819626596285492499512504457128907932827007302385782133229252374; + pol C_52_1 = 0; + pol C_52_2 = 0; + pol C_52_3 = 0; + // Round 54 constants + pol C_53_0 = 13658536470391360399708067455536748955260723760813498481671323619545320978896; + pol C_53_1 = 0; + pol C_53_2 = 0; + pol C_53_3 = 0; + // Round 55 constants + pol C_54_0 = 21546095668130239633971575351786704948662094117932406102037724221634677838565; + pol C_54_1 = 0; + pol C_54_2 = 0; + pol C_54_3 = 0; + // Round 56 constants + pol C_55_0 = 21411726238386979516934941789127061362496195649331822900487557574597304399109; + pol C_55_1 = 0; + pol C_55_2 = 0; + pol C_55_3 = 0; + // Round 57 constants + pol C_56_0 = 1944776378988765673004063363506638781964264107780425928778257145151172817981; + pol C_56_1 = 0; + pol C_56_2 = 0; + pol C_56_3 = 0; + // Round 58 constants + pol C_57_0 = 15590719714223718537172639598316570285163081746016049278954513732528516468773; + pol C_57_1 = 0; + pol C_57_2 = 0; + pol C_57_3 = 0; + // Round 59 constants + pol C_58_0 = 1351266421179051765004709939353170430290500926943038391678843253157009556309; + pol C_58_1 = 0; + pol C_58_2 = 0; + pol C_58_3 = 0; + // Round 60 constants + pol C_59_0 = 6772476224477167317130064764757502335545080109882028900432703947986275397548; + pol C_59_1 = 0; + pol C_59_2 = 0; + pol C_59_3 = 0; + // Round 61 constants + pol C_60_0 = 10670120969725161535937685539136065944959698664551200616467222887025111751992; + pol C_60_1 = 4731853626374224678749618809759140702342195350742653173378450474772131006181; + pol C_60_2 = 14473527495914528513885847341981310373531349450901830749157165104135412062812; + pol C_60_3 = 16937191362061486658876740597821783333355021670608822932942683228741190786143; + // Round 62 constants + pol C_61_0 = 5656559696428674390125424316117443507583679061659043998559560535270557939546; + pol C_61_1 = 8897648276515725841133578021896617755369443750194849587616503841335248902806; + pol C_61_2 = 14938684446722672719637788054570691068799510611164812175626676768545923371470; + pol C_61_3 = 15284149043690546115252102390417391226617211133644099356880071475803043461465; + // Round 63 constants + pol C_62_0 = 2623479025068612775740107497276979457946709347831661908218182874823658838107; + pol C_62_1 = 6809791961761836061129379546794905411734858375517368211894790874813684813988; + pol C_62_2 = 2417620338751920563196799065781703780495622795713803712576790485412779971775; + pol C_62_3 = 4445143310792944321746901285176579692343442786777464604312772017806735512661; + // Round 64 constants + pol C_63_0 = 1429019233589939118995503267516676481141938536269008901607126781291273208629; + pol C_63_1 = 19874283200702583165110559932895904979843482162236139561356679724680604144459; + pol C_63_2 = 13426632171723830006915194799390005513190035492503509233177687891041405113055; + pol C_63_3 = 10582332261829184460912611488470654685922576576939233092337240630493625631748; diff --git a/barretenberg/cpp/pil/vm2/poseidon2_perm.pil b/barretenberg/cpp/pil/vm2/poseidon2_perm.pil new file mode 100644 index 00000000000..f261a3f01e0 --- /dev/null +++ b/barretenberg/cpp/pil/vm2/poseidon2_perm.pil @@ -0,0 +1,1753 @@ +// Implementation based on https://eprint.iacr.org/2023/323.pdf +include "poseidon2_params.pil"; + +namespace poseidon2_perm; + + // Selector for poseidon2 operation + pol commit sel; + // Selector is boolean + sel * (1 - sel) = 0; + #[skippable_if] + sel = 0; + + // The input values are represented by a_0, a_1, a_2, a_3 + pol commit a_0; + pol commit a_1; + pol commit a_2; + pol commit a_3; + + // Output values represented by b_0, b_1, b_2, b_3 + pol commit b_0; + pol commit b_1; + pol commit b_2; + pol commit b_3; + + // Intermediate helper values denoted by T_{id} - based on Appendix B of https://eprint.iacr.org/2023/323.pdf; + // T_0 = a_0 + a_1; + // T_1 = a_2 + a_3; + // T_2 = 2 * a_1 + T_0; + // T_3 = 2 * a_3 + T_0; + // T_4 = 4 * T_1 + T_3; + // T_5 = 4 * T_0 + T_2; + // T_6 = T_3 + T_5; + // T_7 = T_2 + T_4; + + // We additionally include the round identifier in the naming + // __ + // e.g. ARK_0_2 -> Add Round Constant, round 0, input 2 + + + // FIRST EXTERNAL MATRIX LAYER + pol commit EXT_LAYER_4; + pol commit EXT_LAYER_5; + pol commit EXT_LAYER_6; + pol commit EXT_LAYER_7; + pol EXT_LAYER_0 = a_0 + a_1; + pol EXT_LAYER_1 = a_2 + a_3; + pol EXT_LAYER_2 = 2 * a_1 + EXT_LAYER_1; + pol EXT_LAYER_3 = 2 * a_3 + EXT_LAYER_0; + sel * (EXT_LAYER_4 - (4 * EXT_LAYER_1 + EXT_LAYER_3)) = 0; + sel * (EXT_LAYER_5 - (4 * EXT_LAYER_0 + EXT_LAYER_2)) = 0; + sel * (EXT_LAYER_6 - (EXT_LAYER_3 + EXT_LAYER_5)) = 0; + sel * (EXT_LAYER_7 - (EXT_LAYER_2 + EXT_LAYER_4)) = 0; + + + ///////////////////////////////////////////////////// + // START FULL ROUNDS (4 ROUNDS) + ///////////////////////////////////////////////////// + // Round 1 (Full Round) + // ARK (Add Round Constant) + pol ARK_0_0 = EXT_LAYER_6 + poseidon2_params.C_0_0; + pol ARK_0_1 = EXT_LAYER_5 + poseidon2_params.C_0_1; + pol ARK_0_2 = EXT_LAYER_7 + poseidon2_params.C_0_2; + pol ARK_0_3 = EXT_LAYER_4 + poseidon2_params.C_0_3; + + // S-BOX (In full round all inputs are exponentiated) + pol A_0_0 = ARK_0_0 * ARK_0_0 * ARK_0_0 * ARK_0_0 * ARK_0_0; + pol A_0_1 = ARK_0_1 * ARK_0_1 * ARK_0_1 * ARK_0_1 * ARK_0_1; + pol A_0_2 = ARK_0_2 * ARK_0_2 * ARK_0_2 * ARK_0_2 * ARK_0_2; + pol A_0_3 = ARK_0_3 * ARK_0_3 * ARK_0_3 * ARK_0_3 * ARK_0_3; + + // MATRIX (Full round uses the external matrix) + pol commit T_0_4; + pol commit T_0_5; + pol commit T_0_6; + pol commit T_0_7; + + pol T_0_0 = A_0_0 + A_0_1; + pol T_0_1 = A_0_2 + A_0_3; + pol T_0_2 = 2 * A_0_1 + T_0_1; + pol T_0_3 = 2 * A_0_3 + T_0_0; + sel * (T_0_4 - (4 * T_0_1 + T_0_3)) = 0; + sel * (T_0_5 - (4 * T_0_0 + T_0_2)) = 0; + sel * (T_0_6 - (T_0_3 + T_0_5)) = 0; + sel * (T_0_7 - (T_0_2 + T_0_4)) = 0; + + // Round 2 (Full Round) + // ARK (Add Round Constant) + pol ARK_1_0 = T_0_6 + poseidon2_params.C_1_0; + pol ARK_1_1 = T_0_5 + poseidon2_params.C_1_1; + pol ARK_1_2 = T_0_7 + poseidon2_params.C_1_2; + pol ARK_1_3 = T_0_4 + poseidon2_params.C_1_3; + + // S-BOX (In full round all inputs are exponentiated) + pol A_1_0 = ARK_1_0 * ARK_1_0 * ARK_1_0 * ARK_1_0 * ARK_1_0; + pol A_1_1 = ARK_1_1 * ARK_1_1 * ARK_1_1 * ARK_1_1 * ARK_1_1; + pol A_1_2 = ARK_1_2 * ARK_1_2 * ARK_1_2 * ARK_1_2 * ARK_1_2; + pol A_1_3 = ARK_1_3 * ARK_1_3 * ARK_1_3 * ARK_1_3 * ARK_1_3; + + // MATRIX (Full round uses the external matrix) + pol commit T_1_4; + pol commit T_1_5; + pol commit T_1_6; + pol commit T_1_7; + + pol T_1_0 = A_1_0 + A_1_1; + pol T_1_1 = A_1_2 + A_1_3; + pol T_1_2 = 2 * A_1_1 + T_1_1; + pol T_1_3 = 2 * A_1_3 + T_1_0; + sel * (T_1_4 - (4 * T_1_1 + T_1_3)) = 0; + sel * (T_1_5 - (4 * T_1_0 + T_1_2)) = 0; + sel * (T_1_6 - (T_1_3 + T_1_5)) = 0; + sel * (T_1_7 - (T_1_2 + T_1_4)) = 0; + + // Round 3 (Full Round) + // ARK (Add Round Constant) + pol ARK_2_0 = T_1_6 + poseidon2_params.C_2_0; + pol ARK_2_1 = T_1_5 + poseidon2_params.C_2_1; + pol ARK_2_2 = T_1_7 + poseidon2_params.C_2_2; + pol ARK_2_3 = T_1_4 + poseidon2_params.C_2_3; + + // S-BOX (In full round all inputs are exponentiated) + pol A_2_0 = ARK_2_0 * ARK_2_0 * ARK_2_0 * ARK_2_0 * ARK_2_0; + pol A_2_1 = ARK_2_1 * ARK_2_1 * ARK_2_1 * ARK_2_1 * ARK_2_1; + pol A_2_2 = ARK_2_2 * ARK_2_2 * ARK_2_2 * ARK_2_2 * ARK_2_2; + pol A_2_3 = ARK_2_3 * ARK_2_3 * ARK_2_3 * ARK_2_3 * ARK_2_3; + + // MATRIX (Full round uses the external matrix) + pol commit T_2_4; + pol commit T_2_5; + pol commit T_2_6; + pol commit T_2_7; + + pol T_2_0 = A_2_0 + A_2_1; + pol T_2_1 = A_2_2 + A_2_3; + pol T_2_2 = 2 * A_2_1 + T_2_1; + pol T_2_3 = 2 * A_2_3 + T_2_0; + sel * (T_2_4 - (4 * T_2_1 + T_2_3)) = 0; + sel * (T_2_5 - (4 * T_2_0 + T_2_2)) = 0; + sel * (T_2_6 - (T_2_3 + T_2_5)) = 0; + sel * (T_2_7 - (T_2_2 + T_2_4)) = 0; + + // Round 4 (Full Round) + // ARK (Add Round Constant) + pol ARK_3_0 = T_2_6 + poseidon2_params.C_3_0; + pol ARK_3_1 = T_2_5 + poseidon2_params.C_3_1; + pol ARK_3_2 = T_2_7 + poseidon2_params.C_3_2; + pol ARK_3_3 = T_2_4 + poseidon2_params.C_3_3; + + // S-BOX (In full round all inputs are exponentiated) + pol A_3_0 = ARK_3_0 * ARK_3_0 * ARK_3_0 * ARK_3_0 * ARK_3_0; + pol A_3_1 = ARK_3_1 * ARK_3_1 * ARK_3_1 * ARK_3_1 * ARK_3_1; + pol A_3_2 = ARK_3_2 * ARK_3_2 * ARK_3_2 * ARK_3_2 * ARK_3_2; + pol A_3_3 = ARK_3_3 * ARK_3_3 * ARK_3_3 * ARK_3_3 * ARK_3_3; + + // MATRIX (Full round uses the external matrix) + pol commit T_3_4; + pol commit T_3_5; + pol commit T_3_6; + pol commit T_3_7; + + pol T_3_0 = A_3_0 + A_3_1; + pol T_3_1 = A_3_2 + A_3_3; + pol T_3_2 = 2 * A_3_1 + T_3_1; + pol T_3_3 = 2 * A_3_3 + T_3_0; + sel * (T_3_4 - (4 * T_3_1 + T_3_3)) = 0; + sel * (T_3_5 - (4 * T_3_0 + T_3_2)) = 0; + sel * (T_3_6 - (T_3_3 + T_3_5)) = 0; + sel * (T_3_7 - (T_3_2 + T_3_4)) = 0; + + ///////////////////////////////////////////////////// + // PARTIAL ROUNDS (56 ROUNDS) + ///////////////////////////////////////////////////// + + // Round 5 (Partial Round) + // ARK (Add Round Constant) + pol ARK_4_0 = T_3_6 + poseidon2_params.C_4_0; + pol ARK_4_1 = T_3_5 + poseidon2_params.C_4_1; + pol ARK_4_2 = T_3_7 + poseidon2_params.C_4_2; + pol ARK_4_3 = T_3_4 + poseidon2_params.C_4_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_4_0 = ARK_4_0 * ARK_4_0 * ARK_4_0 * ARK_4_0 * ARK_4_0; + pol A_4_1 = ARK_4_1; + pol A_4_2 = ARK_4_2; + pol A_4_3 = ARK_4_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_4_0; + pol commit B_4_1; + pol commit B_4_2; + pol commit B_4_3; + + pol SUM_4 = A_4_0 + A_4_1 + A_4_2 + A_4_3; + + sel * (B_4_0 - (poseidon2_params.MU_0 * A_4_0 + SUM_4)) = 0; + sel * (B_4_1 - (poseidon2_params.MU_1 * A_4_1 + SUM_4)) = 0; + sel * (B_4_2 - (poseidon2_params.MU_2 * A_4_2 + SUM_4)) = 0; + sel * (B_4_3 - (poseidon2_params.MU_3 * A_4_3 + SUM_4)) = 0; + + // Round 6 (Partial Round) + // ARK (Add Round Constant) + pol ARK_5_0 = B_4_0 + poseidon2_params.C_5_0; + pol ARK_5_1 = B_4_1 + poseidon2_params.C_5_1; + pol ARK_5_2 = B_4_2 + poseidon2_params.C_5_2; + pol ARK_5_3 = B_4_3 + poseidon2_params.C_5_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_5_0 = ARK_5_0 * ARK_5_0 * ARK_5_0 * ARK_5_0 * ARK_5_0; + pol A_5_1 = ARK_5_1; + pol A_5_2 = ARK_5_2; + pol A_5_3 = ARK_5_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_5_0; + pol commit B_5_1; + pol commit B_5_2; + pol commit B_5_3; + + pol SUM_5 = A_5_0 + A_5_1 + A_5_2 + A_5_3; + + sel * (B_5_0 - (poseidon2_params.MU_0 * A_5_0 + SUM_5)) = 0; + sel * (B_5_1 - (poseidon2_params.MU_1 * A_5_1 + SUM_5)) = 0; + sel * (B_5_2 - (poseidon2_params.MU_2 * A_5_2 + SUM_5)) = 0; + sel * (B_5_3 - (poseidon2_params.MU_3 * A_5_3 + SUM_5)) = 0; + + // Round 7 (Partial Round) + // ARK (Add Round Constant) + pol ARK_6_0 = B_5_0 + poseidon2_params.C_6_0; + pol ARK_6_1 = B_5_1 + poseidon2_params.C_6_1; + pol ARK_6_2 = B_5_2 + poseidon2_params.C_6_2; + pol ARK_6_3 = B_5_3 + poseidon2_params.C_6_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_6_0 = ARK_6_0 * ARK_6_0 * ARK_6_0 * ARK_6_0 * ARK_6_0; + pol A_6_1 = ARK_6_1; + pol A_6_2 = ARK_6_2; + pol A_6_3 = ARK_6_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_6_0; + pol commit B_6_1; + pol commit B_6_2; + pol commit B_6_3; + + pol SUM_6 = A_6_0 + A_6_1 + A_6_2 + A_6_3; + + sel * (B_6_0 - (poseidon2_params.MU_0 * A_6_0 + SUM_6)) = 0; + sel * (B_6_1 - (poseidon2_params.MU_1 * A_6_1 + SUM_6)) = 0; + sel * (B_6_2 - (poseidon2_params.MU_2 * A_6_2 + SUM_6)) = 0; + sel * (B_6_3 - (poseidon2_params.MU_3 * A_6_3 + SUM_6)) = 0; + + // Round 8 (Partial Round) + // ARK (Add Round Constant) + pol ARK_7_0 = B_6_0 + poseidon2_params.C_7_0; + pol ARK_7_1 = B_6_1 + poseidon2_params.C_7_1; + pol ARK_7_2 = B_6_2 + poseidon2_params.C_7_2; + pol ARK_7_3 = B_6_3 + poseidon2_params.C_7_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_7_0 = ARK_7_0 * ARK_7_0 * ARK_7_0 * ARK_7_0 * ARK_7_0; + pol A_7_1 = ARK_7_1; + pol A_7_2 = ARK_7_2; + pol A_7_3 = ARK_7_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_7_0; + pol commit B_7_1; + pol commit B_7_2; + pol commit B_7_3; + + pol SUM_7 = A_7_0 + A_7_1 + A_7_2 + A_7_3; + + sel * (B_7_0 - (poseidon2_params.MU_0 * A_7_0 + SUM_7)) = 0; + sel * (B_7_1 - (poseidon2_params.MU_1 * A_7_1 + SUM_7)) = 0; + sel * (B_7_2 - (poseidon2_params.MU_2 * A_7_2 + SUM_7)) = 0; + sel * (B_7_3 - (poseidon2_params.MU_3 * A_7_3 + SUM_7)) = 0; + + // Round 9 (Partial Round) + // ARK (Add Round Constant) + pol ARK_8_0 = B_7_0 + poseidon2_params.C_8_0; + pol ARK_8_1 = B_7_1 + poseidon2_params.C_8_1; + pol ARK_8_2 = B_7_2 + poseidon2_params.C_8_2; + pol ARK_8_3 = B_7_3 + poseidon2_params.C_8_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_8_0 = ARK_8_0 * ARK_8_0 * ARK_8_0 * ARK_8_0 * ARK_8_0; + pol A_8_1 = ARK_8_1; + pol A_8_2 = ARK_8_2; + pol A_8_3 = ARK_8_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_8_0; + pol commit B_8_1; + pol commit B_8_2; + pol commit B_8_3; + + pol SUM_8 = A_8_0 + A_8_1 + A_8_2 + A_8_3; + + sel * (B_8_0 - (poseidon2_params.MU_0 * A_8_0 + SUM_8)) = 0; + sel * (B_8_1 - (poseidon2_params.MU_1 * A_8_1 + SUM_8)) = 0; + sel * (B_8_2 - (poseidon2_params.MU_2 * A_8_2 + SUM_8)) = 0; + sel * (B_8_3 - (poseidon2_params.MU_3 * A_8_3 + SUM_8)) = 0; + + // Round 10 (Partial Round) + // ARK (Add Round Constant) + pol ARK_9_0 = B_8_0 + poseidon2_params.C_9_0; + pol ARK_9_1 = B_8_1 + poseidon2_params.C_9_1; + pol ARK_9_2 = B_8_2 + poseidon2_params.C_9_2; + pol ARK_9_3 = B_8_3 + poseidon2_params.C_9_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_9_0 = ARK_9_0 * ARK_9_0 * ARK_9_0 * ARK_9_0 * ARK_9_0; + pol A_9_1 = ARK_9_1; + pol A_9_2 = ARK_9_2; + pol A_9_3 = ARK_9_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_9_0; + pol commit B_9_1; + pol commit B_9_2; + pol commit B_9_3; + + pol SUM_9 = A_9_0 + A_9_1 + A_9_2 + A_9_3; + + sel * (B_9_0 - (poseidon2_params.MU_0 * A_9_0 + SUM_9)) = 0; + sel * (B_9_1 - (poseidon2_params.MU_1 * A_9_1 + SUM_9)) = 0; + sel * (B_9_2 - (poseidon2_params.MU_2 * A_9_2 + SUM_9)) = 0; + sel * (B_9_3 - (poseidon2_params.MU_3 * A_9_3 + SUM_9)) = 0; + + // Round 11 (Partial Round) + // ARK (Add Round Constant) + pol ARK_10_0 = B_9_0 + poseidon2_params.C_10_0; + pol ARK_10_1 = B_9_1 + poseidon2_params.C_10_1; + pol ARK_10_2 = B_9_2 + poseidon2_params.C_10_2; + pol ARK_10_3 = B_9_3 + poseidon2_params.C_10_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_10_0 = ARK_10_0 * ARK_10_0 * ARK_10_0 * ARK_10_0 * ARK_10_0; + pol A_10_1 = ARK_10_1; + pol A_10_2 = ARK_10_2; + pol A_10_3 = ARK_10_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_10_0; + pol commit B_10_1; + pol commit B_10_2; + pol commit B_10_3; + + pol SUM_10 = A_10_0 + A_10_1 + A_10_2 + A_10_3; + + sel * (B_10_0 - (poseidon2_params.MU_0 * A_10_0 + SUM_10)) = 0; + sel * (B_10_1 - (poseidon2_params.MU_1 * A_10_1 + SUM_10)) = 0; + sel * (B_10_2 - (poseidon2_params.MU_2 * A_10_2 + SUM_10)) = 0; + sel * (B_10_3 - (poseidon2_params.MU_3 * A_10_3 + SUM_10)) = 0; + + // Round 12 (Partial Round) + // ARK (Add Round Constant) + pol ARK_11_0 = B_10_0 + poseidon2_params.C_11_0; + pol ARK_11_1 = B_10_1 + poseidon2_params.C_11_1; + pol ARK_11_2 = B_10_2 + poseidon2_params.C_11_2; + pol ARK_11_3 = B_10_3 + poseidon2_params.C_11_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_11_0 = ARK_11_0 * ARK_11_0 * ARK_11_0 * ARK_11_0 * ARK_11_0; + pol A_11_1 = ARK_11_1; + pol A_11_2 = ARK_11_2; + pol A_11_3 = ARK_11_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_11_0; + pol commit B_11_1; + pol commit B_11_2; + pol commit B_11_3; + + pol SUM_11 = A_11_0 + A_11_1 + A_11_2 + A_11_3; + + sel * (B_11_0 - (poseidon2_params.MU_0 * A_11_0 + SUM_11)) = 0; + sel * (B_11_1 - (poseidon2_params.MU_1 * A_11_1 + SUM_11)) = 0; + sel * (B_11_2 - (poseidon2_params.MU_2 * A_11_2 + SUM_11)) = 0; + sel * (B_11_3 - (poseidon2_params.MU_3 * A_11_3 + SUM_11)) = 0; + + // Round 13 (Partial Round) + // ARK (Add Round Constant) + pol ARK_12_0 = B_11_0 + poseidon2_params.C_12_0; + pol ARK_12_1 = B_11_1 + poseidon2_params.C_12_1; + pol ARK_12_2 = B_11_2 + poseidon2_params.C_12_2; + pol ARK_12_3 = B_11_3 + poseidon2_params.C_12_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_12_0 = ARK_12_0 * ARK_12_0 * ARK_12_0 * ARK_12_0 * ARK_12_0; + pol A_12_1 = ARK_12_1; + pol A_12_2 = ARK_12_2; + pol A_12_3 = ARK_12_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_12_0; + pol commit B_12_1; + pol commit B_12_2; + pol commit B_12_3; + + pol SUM_12 = A_12_0 + A_12_1 + A_12_2 + A_12_3; + + sel * (B_12_0 - (poseidon2_params.MU_0 * A_12_0 + SUM_12)) = 0; + sel * (B_12_1 - (poseidon2_params.MU_1 * A_12_1 + SUM_12)) = 0; + sel * (B_12_2 - (poseidon2_params.MU_2 * A_12_2 + SUM_12)) = 0; + sel * (B_12_3 - (poseidon2_params.MU_3 * A_12_3 + SUM_12)) = 0; + + // Round 14 (Partial Round) + // ARK (Add Round Constant) + pol ARK_13_0 = B_12_0 + poseidon2_params.C_13_0; + pol ARK_13_1 = B_12_1 + poseidon2_params.C_13_1; + pol ARK_13_2 = B_12_2 + poseidon2_params.C_13_2; + pol ARK_13_3 = B_12_3 + poseidon2_params.C_13_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_13_0 = ARK_13_0 * ARK_13_0 * ARK_13_0 * ARK_13_0 * ARK_13_0; + pol A_13_1 = ARK_13_1; + pol A_13_2 = ARK_13_2; + pol A_13_3 = ARK_13_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_13_0; + pol commit B_13_1; + pol commit B_13_2; + pol commit B_13_3; + + pol SUM_13 = A_13_0 + A_13_1 + A_13_2 + A_13_3; + + sel * (B_13_0 - (poseidon2_params.MU_0 * A_13_0 + SUM_13)) = 0; + sel * (B_13_1 - (poseidon2_params.MU_1 * A_13_1 + SUM_13)) = 0; + sel * (B_13_2 - (poseidon2_params.MU_2 * A_13_2 + SUM_13)) = 0; + sel * (B_13_3 - (poseidon2_params.MU_3 * A_13_3 + SUM_13)) = 0; + + // Round 15 (Partial Round) + // ARK (Add Round Constant) + pol ARK_14_0 = B_13_0 + poseidon2_params.C_14_0; + pol ARK_14_1 = B_13_1 + poseidon2_params.C_14_1; + pol ARK_14_2 = B_13_2 + poseidon2_params.C_14_2; + pol ARK_14_3 = B_13_3 + poseidon2_params.C_14_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_14_0 = ARK_14_0 * ARK_14_0 * ARK_14_0 * ARK_14_0 * ARK_14_0; + pol A_14_1 = ARK_14_1; + pol A_14_2 = ARK_14_2; + pol A_14_3 = ARK_14_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_14_0; + pol commit B_14_1; + pol commit B_14_2; + pol commit B_14_3; + + pol SUM_14 = A_14_0 + A_14_1 + A_14_2 + A_14_3; + + sel * (B_14_0 - (poseidon2_params.MU_0 * A_14_0 + SUM_14)) = 0; + sel * (B_14_1 - (poseidon2_params.MU_1 * A_14_1 + SUM_14)) = 0; + sel * (B_14_2 - (poseidon2_params.MU_2 * A_14_2 + SUM_14)) = 0; + sel * (B_14_3 - (poseidon2_params.MU_3 * A_14_3 + SUM_14)) = 0; + + // Round 16 (Partial Round) + // ARK (Add Round Constant) + pol ARK_15_0 = B_14_0 + poseidon2_params.C_15_0; + pol ARK_15_1 = B_14_1 + poseidon2_params.C_15_1; + pol ARK_15_2 = B_14_2 + poseidon2_params.C_15_2; + pol ARK_15_3 = B_14_3 + poseidon2_params.C_15_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_15_0 = ARK_15_0 * ARK_15_0 * ARK_15_0 * ARK_15_0 * ARK_15_0; + pol A_15_1 = ARK_15_1; + pol A_15_2 = ARK_15_2; + pol A_15_3 = ARK_15_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_15_0; + pol commit B_15_1; + pol commit B_15_2; + pol commit B_15_3; + + pol SUM_15 = A_15_0 + A_15_1 + A_15_2 + A_15_3; + + sel * (B_15_0 - (poseidon2_params.MU_0 * A_15_0 + SUM_15)) = 0; + sel * (B_15_1 - (poseidon2_params.MU_1 * A_15_1 + SUM_15)) = 0; + sel * (B_15_2 - (poseidon2_params.MU_2 * A_15_2 + SUM_15)) = 0; + sel * (B_15_3 - (poseidon2_params.MU_3 * A_15_3 + SUM_15)) = 0; + + // Round 17 (Partial Round) + // ARK (Add Round Constant) + pol ARK_16_0 = B_15_0 + poseidon2_params.C_16_0; + pol ARK_16_1 = B_15_1 + poseidon2_params.C_16_1; + pol ARK_16_2 = B_15_2 + poseidon2_params.C_16_2; + pol ARK_16_3 = B_15_3 + poseidon2_params.C_16_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_16_0 = ARK_16_0 * ARK_16_0 * ARK_16_0 * ARK_16_0 * ARK_16_0; + pol A_16_1 = ARK_16_1; + pol A_16_2 = ARK_16_2; + pol A_16_3 = ARK_16_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_16_0; + pol commit B_16_1; + pol commit B_16_2; + pol commit B_16_3; + + pol SUM_16 = A_16_0 + A_16_1 + A_16_2 + A_16_3; + + sel * (B_16_0 - (poseidon2_params.MU_0 * A_16_0 + SUM_16)) = 0; + sel * (B_16_1 - (poseidon2_params.MU_1 * A_16_1 + SUM_16)) = 0; + sel * (B_16_2 - (poseidon2_params.MU_2 * A_16_2 + SUM_16)) = 0; + sel * (B_16_3 - (poseidon2_params.MU_3 * A_16_3 + SUM_16)) = 0; + + // Round 18 (Partial Round) + // ARK (Add Round Constant) + pol ARK_17_0 = B_16_0 + poseidon2_params.C_17_0; + pol ARK_17_1 = B_16_1 + poseidon2_params.C_17_1; + pol ARK_17_2 = B_16_2 + poseidon2_params.C_17_2; + pol ARK_17_3 = B_16_3 + poseidon2_params.C_17_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_17_0 = ARK_17_0 * ARK_17_0 * ARK_17_0 * ARK_17_0 * ARK_17_0; + pol A_17_1 = ARK_17_1; + pol A_17_2 = ARK_17_2; + pol A_17_3 = ARK_17_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_17_0; + pol commit B_17_1; + pol commit B_17_2; + pol commit B_17_3; + + pol SUM_17 = A_17_0 + A_17_1 + A_17_2 + A_17_3; + + sel * (B_17_0 - (poseidon2_params.MU_0 * A_17_0 + SUM_17)) = 0; + sel * (B_17_1 - (poseidon2_params.MU_1 * A_17_1 + SUM_17)) = 0; + sel * (B_17_2 - (poseidon2_params.MU_2 * A_17_2 + SUM_17)) = 0; + sel * (B_17_3 - (poseidon2_params.MU_3 * A_17_3 + SUM_17)) = 0; + + // Round 19 (Partial Round) + // ARK (Add Round Constant) + pol ARK_18_0 = B_17_0 + poseidon2_params.C_18_0; + pol ARK_18_1 = B_17_1 + poseidon2_params.C_18_1; + pol ARK_18_2 = B_17_2 + poseidon2_params.C_18_2; + pol ARK_18_3 = B_17_3 + poseidon2_params.C_18_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_18_0 = ARK_18_0 * ARK_18_0 * ARK_18_0 * ARK_18_0 * ARK_18_0; + pol A_18_1 = ARK_18_1; + pol A_18_2 = ARK_18_2; + pol A_18_3 = ARK_18_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_18_0; + pol commit B_18_1; + pol commit B_18_2; + pol commit B_18_3; + + pol SUM_18 = A_18_0 + A_18_1 + A_18_2 + A_18_3; + + sel * (B_18_0 - (poseidon2_params.MU_0 * A_18_0 + SUM_18)) = 0; + sel * (B_18_1 - (poseidon2_params.MU_1 * A_18_1 + SUM_18)) = 0; + sel * (B_18_2 - (poseidon2_params.MU_2 * A_18_2 + SUM_18)) = 0; + sel * (B_18_3 - (poseidon2_params.MU_3 * A_18_3 + SUM_18)) = 0; + + // Round 20 (Partial Round) + // ARK (Add Round Constant) + pol ARK_19_0 = B_18_0 + poseidon2_params.C_19_0; + pol ARK_19_1 = B_18_1 + poseidon2_params.C_19_1; + pol ARK_19_2 = B_18_2 + poseidon2_params.C_19_2; + pol ARK_19_3 = B_18_3 + poseidon2_params.C_19_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_19_0 = ARK_19_0 * ARK_19_0 * ARK_19_0 * ARK_19_0 * ARK_19_0; + pol A_19_1 = ARK_19_1; + pol A_19_2 = ARK_19_2; + pol A_19_3 = ARK_19_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_19_0; + pol commit B_19_1; + pol commit B_19_2; + pol commit B_19_3; + + pol SUM_19 = A_19_0 + A_19_1 + A_19_2 + A_19_3; + + sel * (B_19_0 - (poseidon2_params.MU_0 * A_19_0 + SUM_19)) = 0; + sel * (B_19_1 - (poseidon2_params.MU_1 * A_19_1 + SUM_19)) = 0; + sel * (B_19_2 - (poseidon2_params.MU_2 * A_19_2 + SUM_19)) = 0; + sel * (B_19_3 - (poseidon2_params.MU_3 * A_19_3 + SUM_19)) = 0; + + // Round 21 (Partial Round) + // ARK (Add Round Constant) + pol ARK_20_0 = B_19_0 + poseidon2_params.C_20_0; + pol ARK_20_1 = B_19_1 + poseidon2_params.C_20_1; + pol ARK_20_2 = B_19_2 + poseidon2_params.C_20_2; + pol ARK_20_3 = B_19_3 + poseidon2_params.C_20_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_20_0 = ARK_20_0 * ARK_20_0 * ARK_20_0 * ARK_20_0 * ARK_20_0; + pol A_20_1 = ARK_20_1; + pol A_20_2 = ARK_20_2; + pol A_20_3 = ARK_20_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_20_0; + pol commit B_20_1; + pol commit B_20_2; + pol commit B_20_3; + + pol SUM_20 = A_20_0 + A_20_1 + A_20_2 + A_20_3; + + sel * (B_20_0 - (poseidon2_params.MU_0 * A_20_0 + SUM_20)) = 0; + sel * (B_20_1 - (poseidon2_params.MU_1 * A_20_1 + SUM_20)) = 0; + sel * (B_20_2 - (poseidon2_params.MU_2 * A_20_2 + SUM_20)) = 0; + sel * (B_20_3 - (poseidon2_params.MU_3 * A_20_3 + SUM_20)) = 0; + + // Round 22 (Partial Round) + // ARK (Add Round Constant) + pol ARK_21_0 = B_20_0 + poseidon2_params.C_21_0; + pol ARK_21_1 = B_20_1 + poseidon2_params.C_21_1; + pol ARK_21_2 = B_20_2 + poseidon2_params.C_21_2; + pol ARK_21_3 = B_20_3 + poseidon2_params.C_21_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_21_0 = ARK_21_0 * ARK_21_0 * ARK_21_0 * ARK_21_0 * ARK_21_0; + pol A_21_1 = ARK_21_1; + pol A_21_2 = ARK_21_2; + pol A_21_3 = ARK_21_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_21_0; + pol commit B_21_1; + pol commit B_21_2; + pol commit B_21_3; + + pol SUM_21 = A_21_0 + A_21_1 + A_21_2 + A_21_3; + + sel * (B_21_0 - (poseidon2_params.MU_0 * A_21_0 + SUM_21)) = 0; + sel * (B_21_1 - (poseidon2_params.MU_1 * A_21_1 + SUM_21)) = 0; + sel * (B_21_2 - (poseidon2_params.MU_2 * A_21_2 + SUM_21)) = 0; + sel * (B_21_3 - (poseidon2_params.MU_3 * A_21_3 + SUM_21)) = 0; + + // Round 23 (Partial Round) + // ARK (Add Round Constant) + pol ARK_22_0 = B_21_0 + poseidon2_params.C_22_0; + pol ARK_22_1 = B_21_1 + poseidon2_params.C_22_1; + pol ARK_22_2 = B_21_2 + poseidon2_params.C_22_2; + pol ARK_22_3 = B_21_3 + poseidon2_params.C_22_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_22_0 = ARK_22_0 * ARK_22_0 * ARK_22_0 * ARK_22_0 * ARK_22_0; + pol A_22_1 = ARK_22_1; + pol A_22_2 = ARK_22_2; + pol A_22_3 = ARK_22_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_22_0; + pol commit B_22_1; + pol commit B_22_2; + pol commit B_22_3; + + pol SUM_22 = A_22_0 + A_22_1 + A_22_2 + A_22_3; + + sel * (B_22_0 - (poseidon2_params.MU_0 * A_22_0 + SUM_22)) = 0; + sel * (B_22_1 - (poseidon2_params.MU_1 * A_22_1 + SUM_22)) = 0; + sel * (B_22_2 - (poseidon2_params.MU_2 * A_22_2 + SUM_22)) = 0; + sel * (B_22_3 - (poseidon2_params.MU_3 * A_22_3 + SUM_22)) = 0; + + // Round 24 (Partial Round) + // ARK (Add Round Constant) + pol ARK_23_0 = B_22_0 + poseidon2_params.C_23_0; + pol ARK_23_1 = B_22_1 + poseidon2_params.C_23_1; + pol ARK_23_2 = B_22_2 + poseidon2_params.C_23_2; + pol ARK_23_3 = B_22_3 + poseidon2_params.C_23_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_23_0 = ARK_23_0 * ARK_23_0 * ARK_23_0 * ARK_23_0 * ARK_23_0; + pol A_23_1 = ARK_23_1; + pol A_23_2 = ARK_23_2; + pol A_23_3 = ARK_23_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_23_0; + pol commit B_23_1; + pol commit B_23_2; + pol commit B_23_3; + + pol SUM_23 = A_23_0 + A_23_1 + A_23_2 + A_23_3; + + sel * (B_23_0 - (poseidon2_params.MU_0 * A_23_0 + SUM_23)) = 0; + sel * (B_23_1 - (poseidon2_params.MU_1 * A_23_1 + SUM_23)) = 0; + sel * (B_23_2 - (poseidon2_params.MU_2 * A_23_2 + SUM_23)) = 0; + sel * (B_23_3 - (poseidon2_params.MU_3 * A_23_3 + SUM_23)) = 0; + + // Round 25 (Partial Round) + // ARK (Add Round Constant) + pol ARK_24_0 = B_23_0 + poseidon2_params.C_24_0; + pol ARK_24_1 = B_23_1 + poseidon2_params.C_24_1; + pol ARK_24_2 = B_23_2 + poseidon2_params.C_24_2; + pol ARK_24_3 = B_23_3 + poseidon2_params.C_24_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_24_0 = ARK_24_0 * ARK_24_0 * ARK_24_0 * ARK_24_0 * ARK_24_0; + pol A_24_1 = ARK_24_1; + pol A_24_2 = ARK_24_2; + pol A_24_3 = ARK_24_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_24_0; + pol commit B_24_1; + pol commit B_24_2; + pol commit B_24_3; + + pol SUM_24 = A_24_0 + A_24_1 + A_24_2 + A_24_3; + + sel * (B_24_0 - (poseidon2_params.MU_0 * A_24_0 + SUM_24)) = 0; + sel * (B_24_1 - (poseidon2_params.MU_1 * A_24_1 + SUM_24)) = 0; + sel * (B_24_2 - (poseidon2_params.MU_2 * A_24_2 + SUM_24)) = 0; + sel * (B_24_3 - (poseidon2_params.MU_3 * A_24_3 + SUM_24)) = 0; + + // Round 26 (Partial Round) + // ARK (Add Round Constant) + pol ARK_25_0 = B_24_0 + poseidon2_params.C_25_0; + pol ARK_25_1 = B_24_1 + poseidon2_params.C_25_1; + pol ARK_25_2 = B_24_2 + poseidon2_params.C_25_2; + pol ARK_25_3 = B_24_3 + poseidon2_params.C_25_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_25_0 = ARK_25_0 * ARK_25_0 * ARK_25_0 * ARK_25_0 * ARK_25_0; + pol A_25_1 = ARK_25_1; + pol A_25_2 = ARK_25_2; + pol A_25_3 = ARK_25_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_25_0; + pol commit B_25_1; + pol commit B_25_2; + pol commit B_25_3; + + pol SUM_25 = A_25_0 + A_25_1 + A_25_2 + A_25_3; + + sel * (B_25_0 - (poseidon2_params.MU_0 * A_25_0 + SUM_25)) = 0; + sel * (B_25_1 - (poseidon2_params.MU_1 * A_25_1 + SUM_25)) = 0; + sel * (B_25_2 - (poseidon2_params.MU_2 * A_25_2 + SUM_25)) = 0; + sel * (B_25_3 - (poseidon2_params.MU_3 * A_25_3 + SUM_25)) = 0; + + // Round 27 (Partial Round) + // ARK (Add Round Constant) + pol ARK_26_0 = B_25_0 + poseidon2_params.C_26_0; + pol ARK_26_1 = B_25_1 + poseidon2_params.C_26_1; + pol ARK_26_2 = B_25_2 + poseidon2_params.C_26_2; + pol ARK_26_3 = B_25_3 + poseidon2_params.C_26_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_26_0 = ARK_26_0 * ARK_26_0 * ARK_26_0 * ARK_26_0 * ARK_26_0; + pol A_26_1 = ARK_26_1; + pol A_26_2 = ARK_26_2; + pol A_26_3 = ARK_26_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_26_0; + pol commit B_26_1; + pol commit B_26_2; + pol commit B_26_3; + + pol SUM_26 = A_26_0 + A_26_1 + A_26_2 + A_26_3; + + sel * (B_26_0 - (poseidon2_params.MU_0 * A_26_0 + SUM_26)) = 0; + sel * (B_26_1 - (poseidon2_params.MU_1 * A_26_1 + SUM_26)) = 0; + sel * (B_26_2 - (poseidon2_params.MU_2 * A_26_2 + SUM_26)) = 0; + sel * (B_26_3 - (poseidon2_params.MU_3 * A_26_3 + SUM_26)) = 0; + + // Round 28 (Partial Round) + // ARK (Add Round Constant) + pol ARK_27_0 = B_26_0 + poseidon2_params.C_27_0; + pol ARK_27_1 = B_26_1 + poseidon2_params.C_27_1; + pol ARK_27_2 = B_26_2 + poseidon2_params.C_27_2; + pol ARK_27_3 = B_26_3 + poseidon2_params.C_27_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_27_0 = ARK_27_0 * ARK_27_0 * ARK_27_0 * ARK_27_0 * ARK_27_0; + pol A_27_1 = ARK_27_1; + pol A_27_2 = ARK_27_2; + pol A_27_3 = ARK_27_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_27_0; + pol commit B_27_1; + pol commit B_27_2; + pol commit B_27_3; + + pol SUM_27 = A_27_0 + A_27_1 + A_27_2 + A_27_3; + + sel * (B_27_0 - (poseidon2_params.MU_0 * A_27_0 + SUM_27)) = 0; + sel * (B_27_1 - (poseidon2_params.MU_1 * A_27_1 + SUM_27)) = 0; + sel * (B_27_2 - (poseidon2_params.MU_2 * A_27_2 + SUM_27)) = 0; + sel * (B_27_3 - (poseidon2_params.MU_3 * A_27_3 + SUM_27)) = 0; + + // Round 29 (Partial Round) + // ARK (Add Round Constant) + pol ARK_28_0 = B_27_0 + poseidon2_params.C_28_0; + pol ARK_28_1 = B_27_1 + poseidon2_params.C_28_1; + pol ARK_28_2 = B_27_2 + poseidon2_params.C_28_2; + pol ARK_28_3 = B_27_3 + poseidon2_params.C_28_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_28_0 = ARK_28_0 * ARK_28_0 * ARK_28_0 * ARK_28_0 * ARK_28_0; + pol A_28_1 = ARK_28_1; + pol A_28_2 = ARK_28_2; + pol A_28_3 = ARK_28_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_28_0; + pol commit B_28_1; + pol commit B_28_2; + pol commit B_28_3; + + pol SUM_28 = A_28_0 + A_28_1 + A_28_2 + A_28_3; + + sel * (B_28_0 - (poseidon2_params.MU_0 * A_28_0 + SUM_28)) = 0; + sel * (B_28_1 - (poseidon2_params.MU_1 * A_28_1 + SUM_28)) = 0; + sel * (B_28_2 - (poseidon2_params.MU_2 * A_28_2 + SUM_28)) = 0; + sel * (B_28_3 - (poseidon2_params.MU_3 * A_28_3 + SUM_28)) = 0; + + // Round 30 (Partial Round) + // ARK (Add Round Constant) + pol ARK_29_0 = B_28_0 + poseidon2_params.C_29_0; + pol ARK_29_1 = B_28_1 + poseidon2_params.C_29_1; + pol ARK_29_2 = B_28_2 + poseidon2_params.C_29_2; + pol ARK_29_3 = B_28_3 + poseidon2_params.C_29_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_29_0 = ARK_29_0 * ARK_29_0 * ARK_29_0 * ARK_29_0 * ARK_29_0; + pol A_29_1 = ARK_29_1; + pol A_29_2 = ARK_29_2; + pol A_29_3 = ARK_29_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_29_0; + pol commit B_29_1; + pol commit B_29_2; + pol commit B_29_3; + + pol SUM_29 = A_29_0 + A_29_1 + A_29_2 + A_29_3; + + sel * (B_29_0 - (poseidon2_params.MU_0 * A_29_0 + SUM_29)) = 0; + sel * (B_29_1 - (poseidon2_params.MU_1 * A_29_1 + SUM_29)) = 0; + sel * (B_29_2 - (poseidon2_params.MU_2 * A_29_2 + SUM_29)) = 0; + sel * (B_29_3 - (poseidon2_params.MU_3 * A_29_3 + SUM_29)) = 0; + + // Round 31 (Partial Round) + // ARK (Add Round Constant) + pol ARK_30_0 = B_29_0 + poseidon2_params.C_30_0; + pol ARK_30_1 = B_29_1 + poseidon2_params.C_30_1; + pol ARK_30_2 = B_29_2 + poseidon2_params.C_30_2; + pol ARK_30_3 = B_29_3 + poseidon2_params.C_30_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_30_0 = ARK_30_0 * ARK_30_0 * ARK_30_0 * ARK_30_0 * ARK_30_0; + pol A_30_1 = ARK_30_1; + pol A_30_2 = ARK_30_2; + pol A_30_3 = ARK_30_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_30_0; + pol commit B_30_1; + pol commit B_30_2; + pol commit B_30_3; + + pol SUM_30 = A_30_0 + A_30_1 + A_30_2 + A_30_3; + + sel * (B_30_0 - (poseidon2_params.MU_0 * A_30_0 + SUM_30)) = 0; + sel * (B_30_1 - (poseidon2_params.MU_1 * A_30_1 + SUM_30)) = 0; + sel * (B_30_2 - (poseidon2_params.MU_2 * A_30_2 + SUM_30)) = 0; + sel * (B_30_3 - (poseidon2_params.MU_3 * A_30_3 + SUM_30)) = 0; + + // Round 32 (Partial Round) + // ARK (Add Round Constant) + pol ARK_31_0 = B_30_0 + poseidon2_params.C_31_0; + pol ARK_31_1 = B_30_1 + poseidon2_params.C_31_1; + pol ARK_31_2 = B_30_2 + poseidon2_params.C_31_2; + pol ARK_31_3 = B_30_3 + poseidon2_params.C_31_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_31_0 = ARK_31_0 * ARK_31_0 * ARK_31_0 * ARK_31_0 * ARK_31_0; + pol A_31_1 = ARK_31_1; + pol A_31_2 = ARK_31_2; + pol A_31_3 = ARK_31_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_31_0; + pol commit B_31_1; + pol commit B_31_2; + pol commit B_31_3; + + pol SUM_31 = A_31_0 + A_31_1 + A_31_2 + A_31_3; + + sel * (B_31_0 - (poseidon2_params.MU_0 * A_31_0 + SUM_31)) = 0; + sel * (B_31_1 - (poseidon2_params.MU_1 * A_31_1 + SUM_31)) = 0; + sel * (B_31_2 - (poseidon2_params.MU_2 * A_31_2 + SUM_31)) = 0; + sel * (B_31_3 - (poseidon2_params.MU_3 * A_31_3 + SUM_31)) = 0; + + // Round 33 (Partial Round) + // ARK (Add Round Constant) + pol ARK_32_0 = B_31_0 + poseidon2_params.C_32_0; + pol ARK_32_1 = B_31_1 + poseidon2_params.C_32_1; + pol ARK_32_2 = B_31_2 + poseidon2_params.C_32_2; + pol ARK_32_3 = B_31_3 + poseidon2_params.C_32_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_32_0 = ARK_32_0 * ARK_32_0 * ARK_32_0 * ARK_32_0 * ARK_32_0; + pol A_32_1 = ARK_32_1; + pol A_32_2 = ARK_32_2; + pol A_32_3 = ARK_32_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_32_0; + pol commit B_32_1; + pol commit B_32_2; + pol commit B_32_3; + + pol SUM_32 = A_32_0 + A_32_1 + A_32_2 + A_32_3; + + sel * (B_32_0 - (poseidon2_params.MU_0 * A_32_0 + SUM_32)) = 0; + sel * (B_32_1 - (poseidon2_params.MU_1 * A_32_1 + SUM_32)) = 0; + sel * (B_32_2 - (poseidon2_params.MU_2 * A_32_2 + SUM_32)) = 0; + sel * (B_32_3 - (poseidon2_params.MU_3 * A_32_3 + SUM_32)) = 0; + + // Round 34 (Partial Round) + // ARK (Add Round Constant) + pol ARK_33_0 = B_32_0 + poseidon2_params.C_33_0; + pol ARK_33_1 = B_32_1 + poseidon2_params.C_33_1; + pol ARK_33_2 = B_32_2 + poseidon2_params.C_33_2; + pol ARK_33_3 = B_32_3 + poseidon2_params.C_33_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_33_0 = ARK_33_0 * ARK_33_0 * ARK_33_0 * ARK_33_0 * ARK_33_0; + pol A_33_1 = ARK_33_1; + pol A_33_2 = ARK_33_2; + pol A_33_3 = ARK_33_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_33_0; + pol commit B_33_1; + pol commit B_33_2; + pol commit B_33_3; + + pol SUM_33 = A_33_0 + A_33_1 + A_33_2 + A_33_3; + + sel * (B_33_0 - (poseidon2_params.MU_0 * A_33_0 + SUM_33)) = 0; + sel * (B_33_1 - (poseidon2_params.MU_1 * A_33_1 + SUM_33)) = 0; + sel * (B_33_2 - (poseidon2_params.MU_2 * A_33_2 + SUM_33)) = 0; + sel * (B_33_3 - (poseidon2_params.MU_3 * A_33_3 + SUM_33)) = 0; + + // Round 35 (Partial Round) + // ARK (Add Round Constant) + pol ARK_34_0 = B_33_0 + poseidon2_params.C_34_0; + pol ARK_34_1 = B_33_1 + poseidon2_params.C_34_1; + pol ARK_34_2 = B_33_2 + poseidon2_params.C_34_2; + pol ARK_34_3 = B_33_3 + poseidon2_params.C_34_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_34_0 = ARK_34_0 * ARK_34_0 * ARK_34_0 * ARK_34_0 * ARK_34_0; + pol A_34_1 = ARK_34_1; + pol A_34_2 = ARK_34_2; + pol A_34_3 = ARK_34_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_34_0; + pol commit B_34_1; + pol commit B_34_2; + pol commit B_34_3; + + pol SUM_34 = A_34_0 + A_34_1 + A_34_2 + A_34_3; + + sel * (B_34_0 - (poseidon2_params.MU_0 * A_34_0 + SUM_34)) = 0; + sel * (B_34_1 - (poseidon2_params.MU_1 * A_34_1 + SUM_34)) = 0; + sel * (B_34_2 - (poseidon2_params.MU_2 * A_34_2 + SUM_34)) = 0; + sel * (B_34_3 - (poseidon2_params.MU_3 * A_34_3 + SUM_34)) = 0; + + // Round 36 (Partial Round) + // ARK (Add Round Constant) + pol ARK_35_0 = B_34_0 + poseidon2_params.C_35_0; + pol ARK_35_1 = B_34_1 + poseidon2_params.C_35_1; + pol ARK_35_2 = B_34_2 + poseidon2_params.C_35_2; + pol ARK_35_3 = B_34_3 + poseidon2_params.C_35_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_35_0 = ARK_35_0 * ARK_35_0 * ARK_35_0 * ARK_35_0 * ARK_35_0; + pol A_35_1 = ARK_35_1; + pol A_35_2 = ARK_35_2; + pol A_35_3 = ARK_35_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_35_0; + pol commit B_35_1; + pol commit B_35_2; + pol commit B_35_3; + + pol SUM_35 = A_35_0 + A_35_1 + A_35_2 + A_35_3; + + sel * (B_35_0 - (poseidon2_params.MU_0 * A_35_0 + SUM_35)) = 0; + sel * (B_35_1 - (poseidon2_params.MU_1 * A_35_1 + SUM_35)) = 0; + sel * (B_35_2 - (poseidon2_params.MU_2 * A_35_2 + SUM_35)) = 0; + sel * (B_35_3 - (poseidon2_params.MU_3 * A_35_3 + SUM_35)) = 0; + + // Round 37 (Partial Round) + // ARK (Add Round Constant) + pol ARK_36_0 = B_35_0 + poseidon2_params.C_36_0; + pol ARK_36_1 = B_35_1 + poseidon2_params.C_36_1; + pol ARK_36_2 = B_35_2 + poseidon2_params.C_36_2; + pol ARK_36_3 = B_35_3 + poseidon2_params.C_36_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_36_0 = ARK_36_0 * ARK_36_0 * ARK_36_0 * ARK_36_0 * ARK_36_0; + pol A_36_1 = ARK_36_1; + pol A_36_2 = ARK_36_2; + pol A_36_3 = ARK_36_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_36_0; + pol commit B_36_1; + pol commit B_36_2; + pol commit B_36_3; + + pol SUM_36 = A_36_0 + A_36_1 + A_36_2 + A_36_3; + + sel * (B_36_0 - (poseidon2_params.MU_0 * A_36_0 + SUM_36)) = 0; + sel * (B_36_1 - (poseidon2_params.MU_1 * A_36_1 + SUM_36)) = 0; + sel * (B_36_2 - (poseidon2_params.MU_2 * A_36_2 + SUM_36)) = 0; + sel * (B_36_3 - (poseidon2_params.MU_3 * A_36_3 + SUM_36)) = 0; + + // Round 38 (Partial Round) + // ARK (Add Round Constant) + pol ARK_37_0 = B_36_0 + poseidon2_params.C_37_0; + pol ARK_37_1 = B_36_1 + poseidon2_params.C_37_1; + pol ARK_37_2 = B_36_2 + poseidon2_params.C_37_2; + pol ARK_37_3 = B_36_3 + poseidon2_params.C_37_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_37_0 = ARK_37_0 * ARK_37_0 * ARK_37_0 * ARK_37_0 * ARK_37_0; + pol A_37_1 = ARK_37_1; + pol A_37_2 = ARK_37_2; + pol A_37_3 = ARK_37_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_37_0; + pol commit B_37_1; + pol commit B_37_2; + pol commit B_37_3; + + pol SUM_37 = A_37_0 + A_37_1 + A_37_2 + A_37_3; + + sel * (B_37_0 - (poseidon2_params.MU_0 * A_37_0 + SUM_37)) = 0; + sel * (B_37_1 - (poseidon2_params.MU_1 * A_37_1 + SUM_37)) = 0; + sel * (B_37_2 - (poseidon2_params.MU_2 * A_37_2 + SUM_37)) = 0; + sel * (B_37_3 - (poseidon2_params.MU_3 * A_37_3 + SUM_37)) = 0; + + // Round 39 (Partial Round) + // ARK (Add Round Constant) + pol ARK_38_0 = B_37_0 + poseidon2_params.C_38_0; + pol ARK_38_1 = B_37_1 + poseidon2_params.C_38_1; + pol ARK_38_2 = B_37_2 + poseidon2_params.C_38_2; + pol ARK_38_3 = B_37_3 + poseidon2_params.C_38_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_38_0 = ARK_38_0 * ARK_38_0 * ARK_38_0 * ARK_38_0 * ARK_38_0; + pol A_38_1 = ARK_38_1; + pol A_38_2 = ARK_38_2; + pol A_38_3 = ARK_38_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_38_0; + pol commit B_38_1; + pol commit B_38_2; + pol commit B_38_3; + + pol SUM_38 = A_38_0 + A_38_1 + A_38_2 + A_38_3; + + sel * (B_38_0 - (poseidon2_params.MU_0 * A_38_0 + SUM_38)) = 0; + sel * (B_38_1 - (poseidon2_params.MU_1 * A_38_1 + SUM_38)) = 0; + sel * (B_38_2 - (poseidon2_params.MU_2 * A_38_2 + SUM_38)) = 0; + sel * (B_38_3 - (poseidon2_params.MU_3 * A_38_3 + SUM_38)) = 0; + + // Round 40 (Partial Round) + // ARK (Add Round Constant) + pol ARK_39_0 = B_38_0 + poseidon2_params.C_39_0; + pol ARK_39_1 = B_38_1 + poseidon2_params.C_39_1; + pol ARK_39_2 = B_38_2 + poseidon2_params.C_39_2; + pol ARK_39_3 = B_38_3 + poseidon2_params.C_39_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_39_0 = ARK_39_0 * ARK_39_0 * ARK_39_0 * ARK_39_0 * ARK_39_0; + pol A_39_1 = ARK_39_1; + pol A_39_2 = ARK_39_2; + pol A_39_3 = ARK_39_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_39_0; + pol commit B_39_1; + pol commit B_39_2; + pol commit B_39_3; + + pol SUM_39 = A_39_0 + A_39_1 + A_39_2 + A_39_3; + + sel * (B_39_0 - (poseidon2_params.MU_0 * A_39_0 + SUM_39)) = 0; + sel * (B_39_1 - (poseidon2_params.MU_1 * A_39_1 + SUM_39)) = 0; + sel * (B_39_2 - (poseidon2_params.MU_2 * A_39_2 + SUM_39)) = 0; + sel * (B_39_3 - (poseidon2_params.MU_3 * A_39_3 + SUM_39)) = 0; + + // Round 41 (Partial Round) + // ARK (Add Round Constant) + pol ARK_40_0 = B_39_0 + poseidon2_params.C_40_0; + pol ARK_40_1 = B_39_1 + poseidon2_params.C_40_1; + pol ARK_40_2 = B_39_2 + poseidon2_params.C_40_2; + pol ARK_40_3 = B_39_3 + poseidon2_params.C_40_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_40_0 = ARK_40_0 * ARK_40_0 * ARK_40_0 * ARK_40_0 * ARK_40_0; + pol A_40_1 = ARK_40_1; + pol A_40_2 = ARK_40_2; + pol A_40_3 = ARK_40_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_40_0; + pol commit B_40_1; + pol commit B_40_2; + pol commit B_40_3; + + pol SUM_40 = A_40_0 + A_40_1 + A_40_2 + A_40_3; + + sel * (B_40_0 - (poseidon2_params.MU_0 * A_40_0 + SUM_40)) = 0; + sel * (B_40_1 - (poseidon2_params.MU_1 * A_40_1 + SUM_40)) = 0; + sel * (B_40_2 - (poseidon2_params.MU_2 * A_40_2 + SUM_40)) = 0; + sel * (B_40_3 - (poseidon2_params.MU_3 * A_40_3 + SUM_40)) = 0; + + // Round 42 (Partial Round) + // ARK (Add Round Constant) + pol ARK_41_0 = B_40_0 + poseidon2_params.C_41_0; + pol ARK_41_1 = B_40_1 + poseidon2_params.C_41_1; + pol ARK_41_2 = B_40_2 + poseidon2_params.C_41_2; + pol ARK_41_3 = B_40_3 + poseidon2_params.C_41_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_41_0 = ARK_41_0 * ARK_41_0 * ARK_41_0 * ARK_41_0 * ARK_41_0; + pol A_41_1 = ARK_41_1; + pol A_41_2 = ARK_41_2; + pol A_41_3 = ARK_41_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_41_0; + pol commit B_41_1; + pol commit B_41_2; + pol commit B_41_3; + + pol SUM_41 = A_41_0 + A_41_1 + A_41_2 + A_41_3; + + sel * (B_41_0 - (poseidon2_params.MU_0 * A_41_0 + SUM_41)) = 0; + sel * (B_41_1 - (poseidon2_params.MU_1 * A_41_1 + SUM_41)) = 0; + sel * (B_41_2 - (poseidon2_params.MU_2 * A_41_2 + SUM_41)) = 0; + sel * (B_41_3 - (poseidon2_params.MU_3 * A_41_3 + SUM_41)) = 0; + + // Round 43 (Partial Round) + // ARK (Add Round Constant) + pol ARK_42_0 = B_41_0 + poseidon2_params.C_42_0; + pol ARK_42_1 = B_41_1 + poseidon2_params.C_42_1; + pol ARK_42_2 = B_41_2 + poseidon2_params.C_42_2; + pol ARK_42_3 = B_41_3 + poseidon2_params.C_42_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_42_0 = ARK_42_0 * ARK_42_0 * ARK_42_0 * ARK_42_0 * ARK_42_0; + pol A_42_1 = ARK_42_1; + pol A_42_2 = ARK_42_2; + pol A_42_3 = ARK_42_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_42_0; + pol commit B_42_1; + pol commit B_42_2; + pol commit B_42_3; + + pol SUM_42 = A_42_0 + A_42_1 + A_42_2 + A_42_3; + + sel * (B_42_0 - (poseidon2_params.MU_0 * A_42_0 + SUM_42)) = 0; + sel * (B_42_1 - (poseidon2_params.MU_1 * A_42_1 + SUM_42)) = 0; + sel * (B_42_2 - (poseidon2_params.MU_2 * A_42_2 + SUM_42)) = 0; + sel * (B_42_3 - (poseidon2_params.MU_3 * A_42_3 + SUM_42)) = 0; + + // Round 44 (Partial Round) + // ARK (Add Round Constant) + pol ARK_43_0 = B_42_0 + poseidon2_params.C_43_0; + pol ARK_43_1 = B_42_1 + poseidon2_params.C_43_1; + pol ARK_43_2 = B_42_2 + poseidon2_params.C_43_2; + pol ARK_43_3 = B_42_3 + poseidon2_params.C_43_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_43_0 = ARK_43_0 * ARK_43_0 * ARK_43_0 * ARK_43_0 * ARK_43_0; + pol A_43_1 = ARK_43_1; + pol A_43_2 = ARK_43_2; + pol A_43_3 = ARK_43_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_43_0; + pol commit B_43_1; + pol commit B_43_2; + pol commit B_43_3; + + pol SUM_43 = A_43_0 + A_43_1 + A_43_2 + A_43_3; + + sel * (B_43_0 - (poseidon2_params.MU_0 * A_43_0 + SUM_43)) = 0; + sel * (B_43_1 - (poseidon2_params.MU_1 * A_43_1 + SUM_43)) = 0; + sel * (B_43_2 - (poseidon2_params.MU_2 * A_43_2 + SUM_43)) = 0; + sel * (B_43_3 - (poseidon2_params.MU_3 * A_43_3 + SUM_43)) = 0; + + // Round 45 (Partial Round) + // ARK (Add Round Constant) + pol ARK_44_0 = B_43_0 + poseidon2_params.C_44_0; + pol ARK_44_1 = B_43_1 + poseidon2_params.C_44_1; + pol ARK_44_2 = B_43_2 + poseidon2_params.C_44_2; + pol ARK_44_3 = B_43_3 + poseidon2_params.C_44_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_44_0 = ARK_44_0 * ARK_44_0 * ARK_44_0 * ARK_44_0 * ARK_44_0; + pol A_44_1 = ARK_44_1; + pol A_44_2 = ARK_44_2; + pol A_44_3 = ARK_44_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_44_0; + pol commit B_44_1; + pol commit B_44_2; + pol commit B_44_3; + + pol SUM_44 = A_44_0 + A_44_1 + A_44_2 + A_44_3; + + sel * (B_44_0 - (poseidon2_params.MU_0 * A_44_0 + SUM_44)) = 0; + sel * (B_44_1 - (poseidon2_params.MU_1 * A_44_1 + SUM_44)) = 0; + sel * (B_44_2 - (poseidon2_params.MU_2 * A_44_2 + SUM_44)) = 0; + sel * (B_44_3 - (poseidon2_params.MU_3 * A_44_3 + SUM_44)) = 0; + + // Round 46 (Partial Round) + // ARK (Add Round Constant) + pol ARK_45_0 = B_44_0 + poseidon2_params.C_45_0; + pol ARK_45_1 = B_44_1 + poseidon2_params.C_45_1; + pol ARK_45_2 = B_44_2 + poseidon2_params.C_45_2; + pol ARK_45_3 = B_44_3 + poseidon2_params.C_45_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_45_0 = ARK_45_0 * ARK_45_0 * ARK_45_0 * ARK_45_0 * ARK_45_0; + pol A_45_1 = ARK_45_1; + pol A_45_2 = ARK_45_2; + pol A_45_3 = ARK_45_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_45_0; + pol commit B_45_1; + pol commit B_45_2; + pol commit B_45_3; + + pol SUM_45 = A_45_0 + A_45_1 + A_45_2 + A_45_3; + + sel * (B_45_0 - (poseidon2_params.MU_0 * A_45_0 + SUM_45)) = 0; + sel * (B_45_1 - (poseidon2_params.MU_1 * A_45_1 + SUM_45)) = 0; + sel * (B_45_2 - (poseidon2_params.MU_2 * A_45_2 + SUM_45)) = 0; + sel * (B_45_3 - (poseidon2_params.MU_3 * A_45_3 + SUM_45)) = 0; + + // Round 47 (Partial Round) + // ARK (Add Round Constant) + pol ARK_46_0 = B_45_0 + poseidon2_params.C_46_0; + pol ARK_46_1 = B_45_1 + poseidon2_params.C_46_1; + pol ARK_46_2 = B_45_2 + poseidon2_params.C_46_2; + pol ARK_46_3 = B_45_3 + poseidon2_params.C_46_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_46_0 = ARK_46_0 * ARK_46_0 * ARK_46_0 * ARK_46_0 * ARK_46_0; + pol A_46_1 = ARK_46_1; + pol A_46_2 = ARK_46_2; + pol A_46_3 = ARK_46_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_46_0; + pol commit B_46_1; + pol commit B_46_2; + pol commit B_46_3; + + pol SUM_46 = A_46_0 + A_46_1 + A_46_2 + A_46_3; + + sel * (B_46_0 - (poseidon2_params.MU_0 * A_46_0 + SUM_46)) = 0; + sel * (B_46_1 - (poseidon2_params.MU_1 * A_46_1 + SUM_46)) = 0; + sel * (B_46_2 - (poseidon2_params.MU_2 * A_46_2 + SUM_46)) = 0; + sel * (B_46_3 - (poseidon2_params.MU_3 * A_46_3 + SUM_46)) = 0; + + // Round 48 (Partial Round) + // ARK (Add Round Constant) + pol ARK_47_0 = B_46_0 + poseidon2_params.C_47_0; + pol ARK_47_1 = B_46_1 + poseidon2_params.C_47_1; + pol ARK_47_2 = B_46_2 + poseidon2_params.C_47_2; + pol ARK_47_3 = B_46_3 + poseidon2_params.C_47_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_47_0 = ARK_47_0 * ARK_47_0 * ARK_47_0 * ARK_47_0 * ARK_47_0; + pol A_47_1 = ARK_47_1; + pol A_47_2 = ARK_47_2; + pol A_47_3 = ARK_47_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_47_0; + pol commit B_47_1; + pol commit B_47_2; + pol commit B_47_3; + + pol SUM_47 = A_47_0 + A_47_1 + A_47_2 + A_47_3; + + sel * (B_47_0 - (poseidon2_params.MU_0 * A_47_0 + SUM_47)) = 0; + sel * (B_47_1 - (poseidon2_params.MU_1 * A_47_1 + SUM_47)) = 0; + sel * (B_47_2 - (poseidon2_params.MU_2 * A_47_2 + SUM_47)) = 0; + sel * (B_47_3 - (poseidon2_params.MU_3 * A_47_3 + SUM_47)) = 0; + + // Round 49 (Partial Round) + // ARK (Add Round Constant) + pol ARK_48_0 = B_47_0 + poseidon2_params.C_48_0; + pol ARK_48_1 = B_47_1 + poseidon2_params.C_48_1; + pol ARK_48_2 = B_47_2 + poseidon2_params.C_48_2; + pol ARK_48_3 = B_47_3 + poseidon2_params.C_48_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_48_0 = ARK_48_0 * ARK_48_0 * ARK_48_0 * ARK_48_0 * ARK_48_0; + pol A_48_1 = ARK_48_1; + pol A_48_2 = ARK_48_2; + pol A_48_3 = ARK_48_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_48_0; + pol commit B_48_1; + pol commit B_48_2; + pol commit B_48_3; + + pol SUM_48 = A_48_0 + A_48_1 + A_48_2 + A_48_3; + + sel * (B_48_0 - (poseidon2_params.MU_0 * A_48_0 + SUM_48)) = 0; + sel * (B_48_1 - (poseidon2_params.MU_1 * A_48_1 + SUM_48)) = 0; + sel * (B_48_2 - (poseidon2_params.MU_2 * A_48_2 + SUM_48)) = 0; + sel * (B_48_3 - (poseidon2_params.MU_3 * A_48_3 + SUM_48)) = 0; + + // Round 50 (Partial Round) + // ARK (Add Round Constant) + pol ARK_49_0 = B_48_0 + poseidon2_params.C_49_0; + pol ARK_49_1 = B_48_1 + poseidon2_params.C_49_1; + pol ARK_49_2 = B_48_2 + poseidon2_params.C_49_2; + pol ARK_49_3 = B_48_3 + poseidon2_params.C_49_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_49_0 = ARK_49_0 * ARK_49_0 * ARK_49_0 * ARK_49_0 * ARK_49_0; + pol A_49_1 = ARK_49_1; + pol A_49_2 = ARK_49_2; + pol A_49_3 = ARK_49_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_49_0; + pol commit B_49_1; + pol commit B_49_2; + pol commit B_49_3; + + pol SUM_49 = A_49_0 + A_49_1 + A_49_2 + A_49_3; + + sel * (B_49_0 - (poseidon2_params.MU_0 * A_49_0 + SUM_49)) = 0; + sel * (B_49_1 - (poseidon2_params.MU_1 * A_49_1 + SUM_49)) = 0; + sel * (B_49_2 - (poseidon2_params.MU_2 * A_49_2 + SUM_49)) = 0; + sel * (B_49_3 - (poseidon2_params.MU_3 * A_49_3 + SUM_49)) = 0; + + // Round 51 (Partial Round) + // ARK (Add Round Constant) + pol ARK_50_0 = B_49_0 + poseidon2_params.C_50_0; + pol ARK_50_1 = B_49_1 + poseidon2_params.C_50_1; + pol ARK_50_2 = B_49_2 + poseidon2_params.C_50_2; + pol ARK_50_3 = B_49_3 + poseidon2_params.C_50_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_50_0 = ARK_50_0 * ARK_50_0 * ARK_50_0 * ARK_50_0 * ARK_50_0; + pol A_50_1 = ARK_50_1; + pol A_50_2 = ARK_50_2; + pol A_50_3 = ARK_50_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_50_0; + pol commit B_50_1; + pol commit B_50_2; + pol commit B_50_3; + + pol SUM_50 = A_50_0 + A_50_1 + A_50_2 + A_50_3; + + sel * (B_50_0 - (poseidon2_params.MU_0 * A_50_0 + SUM_50)) = 0; + sel * (B_50_1 - (poseidon2_params.MU_1 * A_50_1 + SUM_50)) = 0; + sel * (B_50_2 - (poseidon2_params.MU_2 * A_50_2 + SUM_50)) = 0; + sel * (B_50_3 - (poseidon2_params.MU_3 * A_50_3 + SUM_50)) = 0; + + // Round 52 (Partial Round) + // ARK (Add Round Constant) + pol ARK_51_0 = B_50_0 + poseidon2_params.C_51_0; + pol ARK_51_1 = B_50_1 + poseidon2_params.C_51_1; + pol ARK_51_2 = B_50_2 + poseidon2_params.C_51_2; + pol ARK_51_3 = B_50_3 + poseidon2_params.C_51_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_51_0 = ARK_51_0 * ARK_51_0 * ARK_51_0 * ARK_51_0 * ARK_51_0; + pol A_51_1 = ARK_51_1; + pol A_51_2 = ARK_51_2; + pol A_51_3 = ARK_51_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_51_0; + pol commit B_51_1; + pol commit B_51_2; + pol commit B_51_3; + + pol SUM_51 = A_51_0 + A_51_1 + A_51_2 + A_51_3; + + sel * (B_51_0 - (poseidon2_params.MU_0 * A_51_0 + SUM_51)) = 0; + sel * (B_51_1 - (poseidon2_params.MU_1 * A_51_1 + SUM_51)) = 0; + sel * (B_51_2 - (poseidon2_params.MU_2 * A_51_2 + SUM_51)) = 0; + sel * (B_51_3 - (poseidon2_params.MU_3 * A_51_3 + SUM_51)) = 0; + + // Round 53 (Partial Round) + // ARK (Add Round Constant) + pol ARK_52_0 = B_51_0 + poseidon2_params.C_52_0; + pol ARK_52_1 = B_51_1 + poseidon2_params.C_52_1; + pol ARK_52_2 = B_51_2 + poseidon2_params.C_52_2; + pol ARK_52_3 = B_51_3 + poseidon2_params.C_52_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_52_0 = ARK_52_0 * ARK_52_0 * ARK_52_0 * ARK_52_0 * ARK_52_0; + pol A_52_1 = ARK_52_1; + pol A_52_2 = ARK_52_2; + pol A_52_3 = ARK_52_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_52_0; + pol commit B_52_1; + pol commit B_52_2; + pol commit B_52_3; + + pol SUM_52 = A_52_0 + A_52_1 + A_52_2 + A_52_3; + + sel * (B_52_0 - (poseidon2_params.MU_0 * A_52_0 + SUM_52)) = 0; + sel * (B_52_1 - (poseidon2_params.MU_1 * A_52_1 + SUM_52)) = 0; + sel * (B_52_2 - (poseidon2_params.MU_2 * A_52_2 + SUM_52)) = 0; + sel * (B_52_3 - (poseidon2_params.MU_3 * A_52_3 + SUM_52)) = 0; + + // Round 54 (Partial Round) + // ARK (Add Round Constant) + pol ARK_53_0 = B_52_0 + poseidon2_params.C_53_0; + pol ARK_53_1 = B_52_1 + poseidon2_params.C_53_1; + pol ARK_53_2 = B_52_2 + poseidon2_params.C_53_2; + pol ARK_53_3 = B_52_3 + poseidon2_params.C_53_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_53_0 = ARK_53_0 * ARK_53_0 * ARK_53_0 * ARK_53_0 * ARK_53_0; + pol A_53_1 = ARK_53_1; + pol A_53_2 = ARK_53_2; + pol A_53_3 = ARK_53_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_53_0; + pol commit B_53_1; + pol commit B_53_2; + pol commit B_53_3; + + pol SUM_53 = A_53_0 + A_53_1 + A_53_2 + A_53_3; + + sel * (B_53_0 - (poseidon2_params.MU_0 * A_53_0 + SUM_53)) = 0; + sel * (B_53_1 - (poseidon2_params.MU_1 * A_53_1 + SUM_53)) = 0; + sel * (B_53_2 - (poseidon2_params.MU_2 * A_53_2 + SUM_53)) = 0; + sel * (B_53_3 - (poseidon2_params.MU_3 * A_53_3 + SUM_53)) = 0; + + // Round 55 (Partial Round) + // ARK (Add Round Constant) + pol ARK_54_0 = B_53_0 + poseidon2_params.C_54_0; + pol ARK_54_1 = B_53_1 + poseidon2_params.C_54_1; + pol ARK_54_2 = B_53_2 + poseidon2_params.C_54_2; + pol ARK_54_3 = B_53_3 + poseidon2_params.C_54_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_54_0 = ARK_54_0 * ARK_54_0 * ARK_54_0 * ARK_54_0 * ARK_54_0; + pol A_54_1 = ARK_54_1; + pol A_54_2 = ARK_54_2; + pol A_54_3 = ARK_54_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_54_0; + pol commit B_54_1; + pol commit B_54_2; + pol commit B_54_3; + + pol SUM_54 = A_54_0 + A_54_1 + A_54_2 + A_54_3; + + sel * (B_54_0 - (poseidon2_params.MU_0 * A_54_0 + SUM_54)) = 0; + sel * (B_54_1 - (poseidon2_params.MU_1 * A_54_1 + SUM_54)) = 0; + sel * (B_54_2 - (poseidon2_params.MU_2 * A_54_2 + SUM_54)) = 0; + sel * (B_54_3 - (poseidon2_params.MU_3 * A_54_3 + SUM_54)) = 0; + + // Round 56 (Partial Round) + // ARK (Add Round Constant) + pol ARK_55_0 = B_54_0 + poseidon2_params.C_55_0; + pol ARK_55_1 = B_54_1 + poseidon2_params.C_55_1; + pol ARK_55_2 = B_54_2 + poseidon2_params.C_55_2; + pol ARK_55_3 = B_54_3 + poseidon2_params.C_55_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_55_0 = ARK_55_0 * ARK_55_0 * ARK_55_0 * ARK_55_0 * ARK_55_0; + pol A_55_1 = ARK_55_1; + pol A_55_2 = ARK_55_2; + pol A_55_3 = ARK_55_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_55_0; + pol commit B_55_1; + pol commit B_55_2; + pol commit B_55_3; + + pol SUM_55 = A_55_0 + A_55_1 + A_55_2 + A_55_3; + + sel * (B_55_0 - (poseidon2_params.MU_0 * A_55_0 + SUM_55)) = 0; + sel * (B_55_1 - (poseidon2_params.MU_1 * A_55_1 + SUM_55)) = 0; + sel * (B_55_2 - (poseidon2_params.MU_2 * A_55_2 + SUM_55)) = 0; + sel * (B_55_3 - (poseidon2_params.MU_3 * A_55_3 + SUM_55)) = 0; + + // Round 57 (Partial Round) + // ARK (Add Round Constant) + pol ARK_56_0 = B_55_0 + poseidon2_params.C_56_0; + pol ARK_56_1 = B_55_1 + poseidon2_params.C_56_1; + pol ARK_56_2 = B_55_2 + poseidon2_params.C_56_2; + pol ARK_56_3 = B_55_3 + poseidon2_params.C_56_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_56_0 = ARK_56_0 * ARK_56_0 * ARK_56_0 * ARK_56_0 * ARK_56_0; + pol A_56_1 = ARK_56_1; + pol A_56_2 = ARK_56_2; + pol A_56_3 = ARK_56_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_56_0; + pol commit B_56_1; + pol commit B_56_2; + pol commit B_56_3; + + pol SUM_56 = A_56_0 + A_56_1 + A_56_2 + A_56_3; + + sel * (B_56_0 - (poseidon2_params.MU_0 * A_56_0 + SUM_56)) = 0; + sel * (B_56_1 - (poseidon2_params.MU_1 * A_56_1 + SUM_56)) = 0; + sel * (B_56_2 - (poseidon2_params.MU_2 * A_56_2 + SUM_56)) = 0; + sel * (B_56_3 - (poseidon2_params.MU_3 * A_56_3 + SUM_56)) = 0; + + // Round 58 (Partial Round) + // ARK (Add Round Constant) + pol ARK_57_0 = B_56_0 + poseidon2_params.C_57_0; + pol ARK_57_1 = B_56_1 + poseidon2_params.C_57_1; + pol ARK_57_2 = B_56_2 + poseidon2_params.C_57_2; + pol ARK_57_3 = B_56_3 + poseidon2_params.C_57_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_57_0 = ARK_57_0 * ARK_57_0 * ARK_57_0 * ARK_57_0 * ARK_57_0; + pol A_57_1 = ARK_57_1; + pol A_57_2 = ARK_57_2; + pol A_57_3 = ARK_57_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_57_0; + pol commit B_57_1; + pol commit B_57_2; + pol commit B_57_3; + + pol SUM_57 = A_57_0 + A_57_1 + A_57_2 + A_57_3; + + sel * (B_57_0 - (poseidon2_params.MU_0 * A_57_0 + SUM_57)) = 0; + sel * (B_57_1 - (poseidon2_params.MU_1 * A_57_1 + SUM_57)) = 0; + sel * (B_57_2 - (poseidon2_params.MU_2 * A_57_2 + SUM_57)) = 0; + sel * (B_57_3 - (poseidon2_params.MU_3 * A_57_3 + SUM_57)) = 0; + + // Round 59 (Partial Round) + // ARK (Add Round Constant) + pol ARK_58_0 = B_57_0 + poseidon2_params.C_58_0; + pol ARK_58_1 = B_57_1 + poseidon2_params.C_58_1; + pol ARK_58_2 = B_57_2 + poseidon2_params.C_58_2; + pol ARK_58_3 = B_57_3 + poseidon2_params.C_58_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_58_0 = ARK_58_0 * ARK_58_0 * ARK_58_0 * ARK_58_0 * ARK_58_0; + pol A_58_1 = ARK_58_1; + pol A_58_2 = ARK_58_2; + pol A_58_3 = ARK_58_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_58_0; + pol commit B_58_1; + pol commit B_58_2; + pol commit B_58_3; + + pol SUM_58 = A_58_0 + A_58_1 + A_58_2 + A_58_3; + + sel * (B_58_0 - (poseidon2_params.MU_0 * A_58_0 + SUM_58)) = 0; + sel * (B_58_1 - (poseidon2_params.MU_1 * A_58_1 + SUM_58)) = 0; + sel * (B_58_2 - (poseidon2_params.MU_2 * A_58_2 + SUM_58)) = 0; + sel * (B_58_3 - (poseidon2_params.MU_3 * A_58_3 + SUM_58)) = 0; + + // Round 60 (Partial Round) + // ARK (Add Round Constant) + pol ARK_59_0 = B_58_0 + poseidon2_params.C_59_0; + pol ARK_59_1 = B_58_1 + poseidon2_params.C_59_1; + pol ARK_59_2 = B_58_2 + poseidon2_params.C_59_2; + pol ARK_59_3 = B_58_3 + poseidon2_params.C_59_3; + + // S-BOX (In partial round only first input is exponentiated) + pol A_59_0 = ARK_59_0 * ARK_59_0 * ARK_59_0 * ARK_59_0 * ARK_59_0; + pol A_59_1 = ARK_59_1; + pol A_59_2 = ARK_59_2; + pol A_59_3 = ARK_59_3; + + // MATRIX (Partial round uses the external matrix) + pol commit B_59_0; + pol commit B_59_1; + pol commit B_59_2; + pol commit B_59_3; + + pol SUM_59 = A_59_0 + A_59_1 + A_59_2 + A_59_3; + + sel * (B_59_0 - (poseidon2_params.MU_0 * A_59_0 + SUM_59)) = 0; + sel * (B_59_1 - (poseidon2_params.MU_1 * A_59_1 + SUM_59)) = 0; + sel * (B_59_2 - (poseidon2_params.MU_2 * A_59_2 + SUM_59)) = 0; + sel * (B_59_3 - (poseidon2_params.MU_3 * A_59_3 + SUM_59)) = 0; + + ///////////////////////////////////////////////////// + // FINAL FULL ROUNDS (4 ROUNDS) + ///////////////////////////////////////////////////// + // Round 61 (Full Round) + // ARK (Add Round Constant) + pol ARK_60_0 = B_59_0 + poseidon2_params.C_60_0; + pol ARK_60_1 = B_59_1 + poseidon2_params.C_60_1; + pol ARK_60_2 = B_59_2 + poseidon2_params.C_60_2; + pol ARK_60_3 = B_59_3 + poseidon2_params.C_60_3; + + // S-BOX (In full round all inputs are exponentiated) + pol A_60_0 = ARK_60_0 * ARK_60_0 * ARK_60_0 * ARK_60_0 * ARK_60_0; + pol A_60_1 = ARK_60_1 * ARK_60_1 * ARK_60_1 * ARK_60_1 * ARK_60_1; + pol A_60_2 = ARK_60_2 * ARK_60_2 * ARK_60_2 * ARK_60_2 * ARK_60_2; + pol A_60_3 = ARK_60_3 * ARK_60_3 * ARK_60_3 * ARK_60_3 * ARK_60_3; + + // MATRIX (Full round uses the external matrix) + pol commit T_60_4; + pol commit T_60_5; + pol commit T_60_6; + pol commit T_60_7; + + pol T_60_0 = A_60_0 + A_60_1; + pol T_60_1 = A_60_2 + A_60_3; + pol T_60_2 = 2 * A_60_1 + T_60_1; + pol T_60_3 = 2 * A_60_3 + T_60_0; + sel * (T_60_4 - (4 * T_60_1 + T_60_3)) = 0; + sel * (T_60_5 - (4 * T_60_0 + T_60_2)) = 0; + sel * (T_60_6 - (T_60_3 + T_60_5)) = 0; + sel * (T_60_7 - (T_60_2 + T_60_4)) = 0; + + // Round 62 (Full Round) + // ARK (Add Round Constant) + pol ARK_61_0 = T_60_6 + poseidon2_params.C_61_0; + pol ARK_61_1 = T_60_5 + poseidon2_params.C_61_1; + pol ARK_61_2 = T_60_7 + poseidon2_params.C_61_2; + pol ARK_61_3 = T_60_4 + poseidon2_params.C_61_3; + + // S-BOX (In full round all inputs are exponentiated) + pol A_61_0 = ARK_61_0 * ARK_61_0 * ARK_61_0 * ARK_61_0 * ARK_61_0; + pol A_61_1 = ARK_61_1 * ARK_61_1 * ARK_61_1 * ARK_61_1 * ARK_61_1; + pol A_61_2 = ARK_61_2 * ARK_61_2 * ARK_61_2 * ARK_61_2 * ARK_61_2; + pol A_61_3 = ARK_61_3 * ARK_61_3 * ARK_61_3 * ARK_61_3 * ARK_61_3; + + // MATRIX (Full round uses the external matrix) + pol commit T_61_4; + pol commit T_61_5; + pol commit T_61_6; + pol commit T_61_7; + + pol T_61_0 = A_61_0 + A_61_1; + pol T_61_1 = A_61_2 + A_61_3; + pol T_61_2 = 2 * A_61_1 + T_61_1; + pol T_61_3 = 2 * A_61_3 + T_61_0; + sel * (T_61_4 - (4 * T_61_1 + T_61_3)) = 0; + sel * (T_61_5 - (4 * T_61_0 + T_61_2)) = 0; + sel * (T_61_6 - (T_61_3 + T_61_5)) = 0; + sel * (T_61_7 - (T_61_2 + T_61_4)) = 0; + + // Round 63 (Full Round) + // ARK (Add Round Constant) + pol ARK_62_0 = T_61_6 + poseidon2_params.C_62_0; + pol ARK_62_1 = T_61_5 + poseidon2_params.C_62_1; + pol ARK_62_2 = T_61_7 + poseidon2_params.C_62_2; + pol ARK_62_3 = T_61_4 + poseidon2_params.C_62_3; + + // S-BOX (In full round all inputs are exponentiated) + pol A_62_0 = ARK_62_0 * ARK_62_0 * ARK_62_0 * ARK_62_0 * ARK_62_0; + pol A_62_1 = ARK_62_1 * ARK_62_1 * ARK_62_1 * ARK_62_1 * ARK_62_1; + pol A_62_2 = ARK_62_2 * ARK_62_2 * ARK_62_2 * ARK_62_2 * ARK_62_2; + pol A_62_3 = ARK_62_3 * ARK_62_3 * ARK_62_3 * ARK_62_3 * ARK_62_3; + + // MATRIX (Full round uses the external matrix) + pol commit T_62_4; + pol commit T_62_5; + pol commit T_62_6; + pol commit T_62_7; + + pol T_62_0 = A_62_0 + A_62_1; + pol T_62_1 = A_62_2 + A_62_3; + pol T_62_2 = 2 * A_62_1 + T_62_1; + pol T_62_3 = 2 * A_62_3 + T_62_0; + sel * (T_62_4 - (4 * T_62_1 + T_62_3)) = 0; + sel * (T_62_5 - (4 * T_62_0 + T_62_2)) = 0; + sel * (T_62_6 - (T_62_3 + T_62_5)) = 0; + sel * (T_62_7 - (T_62_2 + T_62_4)) = 0; + + // Round 64 (Full Round) + // ARK (Add Round Constant) + pol ARK_63_0 = T_62_6 + poseidon2_params.C_63_0; + pol ARK_63_1 = T_62_5 + poseidon2_params.C_63_1; + pol ARK_63_2 = T_62_7 + poseidon2_params.C_63_2; + pol ARK_63_3 = T_62_4 + poseidon2_params.C_63_3; + + // S-BOX (In full round all inputs are exponentiated) + pol A_63_0 = ARK_63_0 * ARK_63_0 * ARK_63_0 * ARK_63_0 * ARK_63_0; + pol A_63_1 = ARK_63_1 * ARK_63_1 * ARK_63_1 * ARK_63_1 * ARK_63_1; + pol A_63_2 = ARK_63_2 * ARK_63_2 * ARK_63_2 * ARK_63_2 * ARK_63_2; + pol A_63_3 = ARK_63_3 * ARK_63_3 * ARK_63_3 * ARK_63_3 * ARK_63_3; + + // MATRIX (Full round uses the external matrix) + pol commit T_63_4; + pol commit T_63_5; + pol commit T_63_6; + pol commit T_63_7; + + pol T_63_0 = A_63_0 + A_63_1; + pol T_63_1 = A_63_2 + A_63_3; + pol T_63_2 = 2 * A_63_1 + T_63_1; + pol T_63_3 = 2 * A_63_3 + T_63_0; + sel * (T_63_4 - (4 * T_63_1 + T_63_3)) = 0; + sel * (T_63_5 - (4 * T_63_0 + T_63_2)) = 0; + sel * (T_63_6 - (T_63_3 + T_63_5)) = 0; + sel * (T_63_7 - (T_63_2 + T_63_4)) = 0; + + ///////////////////////////////////////////////////// + // PERMUTATION END + ///////////////////////////////////////////////////// + // Check output against claimed output + sel * (b_0 - T_63_6) = 0; + sel * (b_1 - T_63_5) = 0; + sel * (b_2 - T_63_7) = 0; + sel * (b_3 - T_63_4) = 0; + diff --git a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/poseidon2.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/poseidon2.test.cpp new file mode 100644 index 00000000000..65648976ada --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/poseidon2.test.cpp @@ -0,0 +1,223 @@ +#include +#include + +#include + +#include "barretenberg/crypto/poseidon2/poseidon2.hpp" +#include "barretenberg/vm2/constraining/testing/check_relation.hpp" +#include "barretenberg/vm2/generated/flavor_settings.hpp" +#include "barretenberg/vm2/generated/relations/lookups_poseidon2_hash.hpp" +#include "barretenberg/vm2/generated/relations/poseidon2_hash.hpp" +#include "barretenberg/vm2/generated/relations/poseidon2_perm.hpp" +#include "barretenberg/vm2/simulation/events/event_emitter.hpp" +#include "barretenberg/vm2/testing/macros.hpp" +#include "barretenberg/vm2/tracegen/lib/lookup_builder.hpp" +#include "barretenberg/vm2/tracegen/poseidon2_trace.hpp" +// Temporary imports, see comment in test. +#include "barretenberg/vm2/simulation/poseidon2.hpp" +#include "barretenberg/vm2/tracegen/test_trace_container.hpp" + +namespace bb::avm2::constraining { + +using ::testing::ElementsAreArray; + +using tracegen::TestTraceContainer; +using FF = AvmFlavorSettings::FF; +using C = Column; +using poseidon2_hash = bb::avm2::poseidon2_hash; +using poseidon2_perm = bb::avm2::poseidon2_perm; + +using simulation::EventEmitter; +using simulation::NoopEventEmitter; +using simulation::Poseidon2; +using simulation::Poseidon2HashEvent; +using simulation::Poseidon2PermutationEvent; + +using tracegen::LookupIntoDynamicTableSequential; +using lookup_pos2_perm_relation = bb::avm2::lookup_pos2_perm_relation; + +TEST(Poseidon2, Poseidon2EmptyRow) +{ + auto trace = TestTraceContainer::from_rows({ + { .precomputed_first_row = 1 }, + }); + + check_relation(trace); + check_relation(trace); +} + +// These tests imports a bunch of external code since hand-generating the poseidon2 trace is a bit laborious atm. +// TODO: Test lookup relations +TEST(Poseidon2, BasicPermutation) +{ + // We are just testing the permutation event here so we can use a noop emitter for the hash events. + NoopEventEmitter poseidon2_hash_event_emitter; + EventEmitter poseidon2_perm_event_emitter; + Poseidon2 poseidon2(poseidon2_hash_event_emitter, poseidon2_perm_event_emitter); + + // Taken From barretenberg/crypto/poseidon2/poseidon2.test.cpp + FF a("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789"); + FF b("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789"); + FF c("0x9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789"); + FF d("0x9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789"); + + std::array input = { a, b, c, d }; + auto result = poseidon2.permutation(input); + + std::array expected = { + FF("0x2bf1eaf87f7d27e8dc4056e9af975985bccc89077a21891d6c7b6ccce0631f95"), + FF("0x0c01fa1b8d0748becafbe452c0cb0231c38224ea824554c9362518eebdd5701f"), + FF("0x018555a8eb50cf07f64b019ebaf3af3c925c93e631f3ecd455db07bbb52bbdd3"), + FF("0x0cbea457c91c22c6c31fd89afd2541efc2edf31736b9f721e823b2165c90fd41"), + }; + + EXPECT_THAT(result, ElementsAreArray(expected)); + + TestTraceContainer trace; + tracegen::Poseidon2TraceBuilder builder; + + builder.process_permutation(poseidon2_perm_event_emitter.dump_events(), trace); + EXPECT_EQ(trace.get_num_rows(), 1); + + check_relation(trace); +} + +TEST(Poseidon2, HashWithSinglePermutation) +{ + EventEmitter poseidon2_hash_event_emitter; + // We are just testing the hash event here so we can use a noop emitter for the permutation events. + NoopEventEmitter poseidon2_perm_event_emitter; + Poseidon2 poseidon2(poseidon2_hash_event_emitter, poseidon2_perm_event_emitter); + + FF a("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789"); + FF b("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789"); + FF c("0x9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789"); + + std::vector input = { a, b, c }; + poseidon2.hash(input); + + // This first row column is set becuase it is used in the relations for Poseidon2Hash. + // This could be replaced by having the precomputed tables in the trace, but currently that would + // mean the clk column of length 2^21 -1 will be include :O + TestTraceContainer trace = TestTraceContainer::from_rows({ + { .precomputed_first_row = 1 }, + }); + tracegen::Poseidon2TraceBuilder builder; + + builder.process_hash(poseidon2_hash_event_emitter.dump_events(), trace); + EXPECT_EQ(trace.get_num_rows(), /*start_row=*/1 + 1); + + check_relation(trace); +} + +TEST(Poseidon2, HashWithMultiplePermutation) +{ + EventEmitter poseidon2_hash_event_emitter; + NoopEventEmitter poseidon2_perm_event_emitter; + Poseidon2 poseidon2(poseidon2_hash_event_emitter, poseidon2_perm_event_emitter); + + // Taken From barretenberg/crypto/poseidon2/poseidon2.test.cpp + FF a("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789"); + FF b("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789"); + FF c("0x9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789"); + FF d("0x9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789"); + + std::vector input = { a, b, c, d }; + poseidon2.hash(input); + + TestTraceContainer trace = TestTraceContainer::from_rows({ + { .precomputed_first_row = 1 }, + }); + tracegen::Poseidon2TraceBuilder builder; + + builder.process_hash(poseidon2_hash_event_emitter.dump_events(), trace); + EXPECT_EQ(trace.get_num_rows(), /*start_row=*/1 + 2); + + check_relation(trace); +} + +TEST(Poseidon2, MultipleHashInvocations) +{ + EventEmitter poseidon2_hash_event_emitter; + NoopEventEmitter poseidon2_perm_event_emitter; + Poseidon2 poseidon2(poseidon2_hash_event_emitter, poseidon2_perm_event_emitter); + + std::vector input = { 1, 2, 3, 4 }; + + FF result = poseidon2.hash(input); + FF bb_result = crypto::Poseidon2::hash(input); + EXPECT_EQ(result, bb_result); + + result = poseidon2.hash({ result, 1, 2, 3, 4 }); + bb_result = crypto::Poseidon2::hash({ bb_result, 1, 2, 3, 4 }); + EXPECT_EQ(result, bb_result); + + TestTraceContainer trace = TestTraceContainer::from_rows({ + { .precomputed_first_row = 1 }, + }); + tracegen::Poseidon2TraceBuilder builder; + + builder.process_hash(poseidon2_hash_event_emitter.dump_events(), trace); + builder.process_permutation(poseidon2_perm_event_emitter.dump_events(), trace); + EXPECT_EQ(trace.get_num_rows(), /*start_row=*/1 + /*first_invocation=*/2 + /*second_invokcation=*/2); + + check_relation(trace); +} + +TEST(Poseidon2, HashPermInteractions) +{ + EventEmitter poseidon2_hash_event_emitter; + EventEmitter poseidon2_perm_event_emitter; + Poseidon2 poseidon2(poseidon2_hash_event_emitter, poseidon2_perm_event_emitter); + + std::vector input = { 1, 2, 3, 4 }; + + poseidon2.hash(input); + + TestTraceContainer trace = TestTraceContainer::from_rows({ + { .precomputed_first_row = 1 }, + }); + tracegen::Poseidon2TraceBuilder builder; + + builder.process_hash(poseidon2_hash_event_emitter.dump_events(), trace); + builder.process_permutation(poseidon2_perm_event_emitter.dump_events(), trace); + LookupIntoDynamicTableSequential().process(trace); + + EXPECT_EQ(trace.get_num_rows(), /*start_row=*/1 + /*first_invocation=*/2); + + check_relation(trace); + check_relation(trace); + check_interaction(trace); +} + +TEST(Poseidon2, NegativeHashPermInteractions) +{ + // We won't generate permutation events which will cause the lookup to fail + NoopEventEmitter poseidon2_perm_event_emitter; + EventEmitter poseidon2_hash_event_emitter; + Poseidon2 poseidon2(poseidon2_hash_event_emitter, poseidon2_perm_event_emitter); + + std::vector input = { 1, 2, 3, 4 }; + + poseidon2.hash(input); + + TestTraceContainer trace = TestTraceContainer::from_rows({ + { .precomputed_first_row = 1 }, + }); + tracegen::Poseidon2TraceBuilder builder; + + builder.process_hash(poseidon2_hash_event_emitter.dump_events(), trace); + + // This sets the length of the inverse polynomial via SetDummyInverses, so we still need to call this even though we + // know it will fail. + EXPECT_THROW_WITH_MESSAGE(LookupIntoDynamicTableSequential().process(trace), + "Failed.*LOOKUP_POS2_PERM. Could not find tuple in destination."); + + EXPECT_EQ(trace.get_num_rows(), /*start_row=*/1 + /*first_invocation=*/2); + + check_relation(trace); + EXPECT_THROW_WITH_MESSAGE(check_interaction(trace), + "Relation LOOKUP_POS2_PERM.* ACCUMULATION.* is non-zero"); +} + +} // namespace bb::avm2::constraining diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/columns.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/columns.hpp index e222f8f3db6..9439928bc80 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/columns.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/columns.hpp @@ -10,16 +10,16 @@ namespace bb::avm2 { // The entities that will be used in the flavor. // clang-format off #define AVM2_PRECOMPUTED_ENTITIES precomputed_as_unary, precomputed_bitwise_input_a, precomputed_bitwise_input_b, precomputed_bitwise_op_id, precomputed_bitwise_output, precomputed_clk, precomputed_first_row, precomputed_integral_tag_length, precomputed_power_of_2, precomputed_sel_bitwise, precomputed_sel_integral_tag, precomputed_sel_range_16, precomputed_sel_range_8, precomputed_sel_sha256_compression, precomputed_sel_unary, precomputed_sha256_compression_round_constant -#define AVM2_WIRE_ENTITIES execution_input, alu_dst_addr, alu_ia, alu_ia_addr, alu_ib, alu_ib_addr, alu_ic, alu_op, alu_sel_op_add, bc_decomposition_abs_diff, bc_decomposition_bytes, bc_decomposition_bytes_pc_plus_1, bc_decomposition_bytes_pc_plus_10, bc_decomposition_bytes_pc_plus_11, bc_decomposition_bytes_pc_plus_12, bc_decomposition_bytes_pc_plus_13, bc_decomposition_bytes_pc_plus_14, bc_decomposition_bytes_pc_plus_15, bc_decomposition_bytes_pc_plus_16, bc_decomposition_bytes_pc_plus_17, bc_decomposition_bytes_pc_plus_18, bc_decomposition_bytes_pc_plus_19, bc_decomposition_bytes_pc_plus_2, bc_decomposition_bytes_pc_plus_20, bc_decomposition_bytes_pc_plus_21, bc_decomposition_bytes_pc_plus_22, bc_decomposition_bytes_pc_plus_23, bc_decomposition_bytes_pc_plus_24, bc_decomposition_bytes_pc_plus_25, bc_decomposition_bytes_pc_plus_26, bc_decomposition_bytes_pc_plus_27, bc_decomposition_bytes_pc_plus_28, bc_decomposition_bytes_pc_plus_29, bc_decomposition_bytes_pc_plus_3, bc_decomposition_bytes_pc_plus_30, bc_decomposition_bytes_pc_plus_31, bc_decomposition_bytes_pc_plus_32, bc_decomposition_bytes_pc_plus_33, bc_decomposition_bytes_pc_plus_34, bc_decomposition_bytes_pc_plus_35, bc_decomposition_bytes_pc_plus_4, bc_decomposition_bytes_pc_plus_5, bc_decomposition_bytes_pc_plus_6, bc_decomposition_bytes_pc_plus_7, bc_decomposition_bytes_pc_plus_8, bc_decomposition_bytes_pc_plus_9, bc_decomposition_bytes_rem_inv, bc_decomposition_bytes_rem_min_one_inv, bc_decomposition_bytes_remaining, bc_decomposition_bytes_to_read, bc_decomposition_bytes_to_read_unary, bc_decomposition_id, bc_decomposition_last_of_contract, bc_decomposition_pc, bc_decomposition_sel, bc_decomposition_sel_overflow_correction_needed, bc_decomposition_sel_pc_plus_1, bc_decomposition_sel_pc_plus_10, bc_decomposition_sel_pc_plus_11, bc_decomposition_sel_pc_plus_12, bc_decomposition_sel_pc_plus_13, bc_decomposition_sel_pc_plus_14, bc_decomposition_sel_pc_plus_15, bc_decomposition_sel_pc_plus_16, bc_decomposition_sel_pc_plus_17, bc_decomposition_sel_pc_plus_18, bc_decomposition_sel_pc_plus_19, bc_decomposition_sel_pc_plus_2, bc_decomposition_sel_pc_plus_20, bc_decomposition_sel_pc_plus_21, bc_decomposition_sel_pc_plus_22, bc_decomposition_sel_pc_plus_23, bc_decomposition_sel_pc_plus_24, bc_decomposition_sel_pc_plus_25, bc_decomposition_sel_pc_plus_26, bc_decomposition_sel_pc_plus_27, bc_decomposition_sel_pc_plus_28, bc_decomposition_sel_pc_plus_29, bc_decomposition_sel_pc_plus_3, bc_decomposition_sel_pc_plus_30, bc_decomposition_sel_pc_plus_31, bc_decomposition_sel_pc_plus_32, bc_decomposition_sel_pc_plus_33, bc_decomposition_sel_pc_plus_34, bc_decomposition_sel_pc_plus_35, bc_decomposition_sel_pc_plus_4, bc_decomposition_sel_pc_plus_5, bc_decomposition_sel_pc_plus_6, bc_decomposition_sel_pc_plus_7, bc_decomposition_sel_pc_plus_8, bc_decomposition_sel_pc_plus_9, bc_retrieval_address, bc_retrieval_artifact_hash, bc_retrieval_bytecode_id, bc_retrieval_class_id, bc_retrieval_deployer_addr, bc_retrieval_err, bc_retrieval_incoming_viewing_key_x, bc_retrieval_incoming_viewing_key_y, bc_retrieval_init_hash, bc_retrieval_nullifier_key_x, bc_retrieval_nullifier_key_y, bc_retrieval_outgoing_viewing_key_x, bc_retrieval_outgoing_viewing_key_y, bc_retrieval_private_function_root, bc_retrieval_public_bytecode_commitment, bc_retrieval_salt, bc_retrieval_sel, bc_retrieval_tagging_key_x, bc_retrieval_tagging_key_y, bitwise_acc_ia, bitwise_acc_ib, bitwise_acc_ic, bitwise_ctr, bitwise_ctr_inv, bitwise_ctr_min_one_inv, bitwise_ia_byte, bitwise_ib_byte, bitwise_ic_byte, bitwise_last, bitwise_op_id, bitwise_sel, bitwise_start, bitwise_tag, ecc_add_op, ecc_double_op, ecc_inv_2_p_y, ecc_inv_x_diff, ecc_inv_y_diff, ecc_lambda, ecc_p_is_inf, ecc_p_x, ecc_p_y, ecc_q_is_inf, ecc_q_x, ecc_q_y, ecc_r_is_inf, ecc_r_x, ecc_r_y, ecc_result_infinity, ecc_sel, ecc_x_match, ecc_y_match, execution_addressing_error_idx, execution_addressing_error_kind, execution_base_address_tag, execution_base_address_val, execution_bytecode_id, execution_clk, execution_ex_opcode, execution_indirect, execution_last, execution_op1, execution_op1_after_relative, execution_op2, execution_op2_after_relative, execution_op3, execution_op3_after_relative, execution_op4, execution_op4_after_relative, execution_pc, execution_rop1, execution_rop2, execution_rop3, execution_rop4, execution_sel, execution_sel_addressing_error, execution_sel_op1_is_address, execution_sel_op2_is_address, execution_sel_op3_is_address, execution_sel_op4_is_address, instr_fetching_bd0, instr_fetching_bd1, instr_fetching_bd10, instr_fetching_bd11, instr_fetching_bd12, instr_fetching_bd13, instr_fetching_bd14, instr_fetching_bd15, instr_fetching_bd16, instr_fetching_bd17, instr_fetching_bd18, instr_fetching_bd19, instr_fetching_bd2, instr_fetching_bd20, instr_fetching_bd21, instr_fetching_bd22, instr_fetching_bd23, instr_fetching_bd24, instr_fetching_bd25, instr_fetching_bd26, instr_fetching_bd27, instr_fetching_bd28, instr_fetching_bd29, instr_fetching_bd3, instr_fetching_bd30, instr_fetching_bd31, instr_fetching_bd32, instr_fetching_bd33, instr_fetching_bd34, instr_fetching_bd35, instr_fetching_bd4, instr_fetching_bd5, instr_fetching_bd6, instr_fetching_bd7, instr_fetching_bd8, instr_fetching_bd9, instr_fetching_bytecode_id, instr_fetching_ex_opcode, instr_fetching_fmt_3_op_u8, instr_fetching_indirect, instr_fetching_op1, instr_fetching_op2, instr_fetching_op3, instr_fetching_op4, instr_fetching_pc, instr_fetching_sel, range_check_dyn_diff, range_check_dyn_rng_chk_bits, range_check_dyn_rng_chk_pow_2, range_check_is_lte_u112, range_check_is_lte_u128, range_check_is_lte_u16, range_check_is_lte_u32, range_check_is_lte_u48, range_check_is_lte_u64, range_check_is_lte_u80, range_check_is_lte_u96, range_check_rng_chk_bits, range_check_sel, range_check_sel_r0_16_bit_rng_lookup, range_check_sel_r1_16_bit_rng_lookup, range_check_sel_r2_16_bit_rng_lookup, range_check_sel_r3_16_bit_rng_lookup, range_check_sel_r4_16_bit_rng_lookup, range_check_sel_r5_16_bit_rng_lookup, range_check_sel_r6_16_bit_rng_lookup, range_check_u16_r0, range_check_u16_r1, range_check_u16_r2, range_check_u16_r3, range_check_u16_r4, range_check_u16_r5, range_check_u16_r6, range_check_u16_r7, range_check_value, sha256_a, sha256_a_and_b, sha256_a_and_b_xor_a_and_c, sha256_a_and_c, sha256_a_rotr_13, sha256_a_rotr_2, sha256_a_rotr_22, sha256_a_rotr_2_xor_a_rotr_13, sha256_and_sel, sha256_b, sha256_b_and_c, sha256_c, sha256_ch, sha256_clk, sha256_computed_w_lhs, sha256_computed_w_rhs, sha256_d, sha256_dummy_zero, sha256_e, sha256_e_and_f, sha256_e_rotr_11, sha256_e_rotr_25, sha256_e_rotr_6, sha256_e_rotr_6_xor_e_rotr_11, sha256_f, sha256_g, sha256_h, sha256_helper_w0, sha256_helper_w1, sha256_helper_w10, sha256_helper_w11, sha256_helper_w12, sha256_helper_w13, sha256_helper_w14, sha256_helper_w15, sha256_helper_w2, sha256_helper_w3, sha256_helper_w4, sha256_helper_w5, sha256_helper_w6, sha256_helper_w7, sha256_helper_w8, sha256_helper_w9, sha256_init_a, sha256_init_b, sha256_init_c, sha256_init_d, sha256_init_e, sha256_init_f, sha256_init_g, sha256_init_h, sha256_input_offset, sha256_is_input_round, sha256_latch, sha256_lhs_a_13, sha256_lhs_a_2, sha256_lhs_a_22, sha256_lhs_e_11, sha256_lhs_e_25, sha256_lhs_e_6, sha256_lhs_w_10, sha256_lhs_w_17, sha256_lhs_w_18, sha256_lhs_w_19, sha256_lhs_w_3, sha256_lhs_w_7, sha256_maj, sha256_next_a_lhs, sha256_next_a_rhs, sha256_next_e_lhs, sha256_next_e_rhs, sha256_not_e, sha256_not_e_and_g, sha256_output_a_lhs, sha256_output_a_rhs, sha256_output_b_lhs, sha256_output_b_rhs, sha256_output_c_lhs, sha256_output_c_rhs, sha256_output_d_lhs, sha256_output_d_rhs, sha256_output_e_lhs, sha256_output_e_rhs, sha256_output_f_lhs, sha256_output_f_rhs, sha256_output_g_lhs, sha256_output_g_rhs, sha256_output_h_lhs, sha256_output_h_rhs, sha256_output_offset, sha256_perform_round, sha256_rhs_a_13, sha256_rhs_a_2, sha256_rhs_a_22, sha256_rhs_e_11, sha256_rhs_e_25, sha256_rhs_e_6, sha256_rhs_w_10, sha256_rhs_w_17, sha256_rhs_w_18, sha256_rhs_w_19, sha256_rhs_w_3, sha256_rhs_w_7, sha256_round_constant, sha256_round_count, sha256_rounds_remaining, sha256_rounds_remaining_inv, sha256_s_0, sha256_s_1, sha256_sel, sha256_start, sha256_state_offset, sha256_w, sha256_w_15_rotr_18, sha256_w_15_rotr_7, sha256_w_15_rotr_7_xor_w_15_rotr_18, sha256_w_15_rshift_3, sha256_w_2_rotr_17, sha256_w_2_rotr_17_xor_w_2_rotr_19, sha256_w_2_rotr_19, sha256_w_2_rshift_10, sha256_w_s_0, sha256_w_s_1, sha256_xor_sel, lookup_bytecode_bytes_are_bytes_counts, lookup_bytecode_remaining_abs_diff_u16_counts, lookup_bytecode_to_read_unary_counts, lookup_rng_chk_pow_2_counts, lookup_rng_chk_diff_counts, lookup_rng_chk_is_r0_16_bit_counts, lookup_rng_chk_is_r1_16_bit_counts, lookup_rng_chk_is_r2_16_bit_counts, lookup_rng_chk_is_r3_16_bit_counts, lookup_rng_chk_is_r4_16_bit_counts, lookup_rng_chk_is_r5_16_bit_counts, lookup_rng_chk_is_r6_16_bit_counts, lookup_rng_chk_is_r7_16_bit_counts, lookup_bitw_byte_lengths_counts, lookup_bitw_byte_operations_counts, lookup_sha256_round_constant_counts, lookup_dummy_precomputed_counts, lookup_dummy_dynamic_counts -#define AVM2_DERIVED_WITNESS_ENTITIES perm_dummy_dynamic_inv, lookup_bytecode_bytes_are_bytes_inv, lookup_bytecode_remaining_abs_diff_u16_inv, lookup_bytecode_to_read_unary_inv, lookup_rng_chk_pow_2_inv, lookup_rng_chk_diff_inv, lookup_rng_chk_is_r0_16_bit_inv, lookup_rng_chk_is_r1_16_bit_inv, lookup_rng_chk_is_r2_16_bit_inv, lookup_rng_chk_is_r3_16_bit_inv, lookup_rng_chk_is_r4_16_bit_inv, lookup_rng_chk_is_r5_16_bit_inv, lookup_rng_chk_is_r6_16_bit_inv, lookup_rng_chk_is_r7_16_bit_inv, lookup_bitw_byte_lengths_inv, lookup_bitw_byte_operations_inv, lookup_sha256_round_constant_inv, lookup_dummy_precomputed_inv, lookup_dummy_dynamic_inv -#define AVM2_SHIFTED_ENTITIES bc_decomposition_bytes_shift, bc_decomposition_bytes_pc_plus_1_shift, bc_decomposition_bytes_pc_plus_10_shift, bc_decomposition_bytes_pc_plus_11_shift, bc_decomposition_bytes_pc_plus_12_shift, bc_decomposition_bytes_pc_plus_13_shift, bc_decomposition_bytes_pc_plus_14_shift, bc_decomposition_bytes_pc_plus_15_shift, bc_decomposition_bytes_pc_plus_16_shift, bc_decomposition_bytes_pc_plus_17_shift, bc_decomposition_bytes_pc_plus_18_shift, bc_decomposition_bytes_pc_plus_19_shift, bc_decomposition_bytes_pc_plus_2_shift, bc_decomposition_bytes_pc_plus_20_shift, bc_decomposition_bytes_pc_plus_21_shift, bc_decomposition_bytes_pc_plus_22_shift, bc_decomposition_bytes_pc_plus_23_shift, bc_decomposition_bytes_pc_plus_24_shift, bc_decomposition_bytes_pc_plus_25_shift, bc_decomposition_bytes_pc_plus_26_shift, bc_decomposition_bytes_pc_plus_27_shift, bc_decomposition_bytes_pc_plus_28_shift, bc_decomposition_bytes_pc_plus_29_shift, bc_decomposition_bytes_pc_plus_3_shift, bc_decomposition_bytes_pc_plus_30_shift, bc_decomposition_bytes_pc_plus_31_shift, bc_decomposition_bytes_pc_plus_32_shift, bc_decomposition_bytes_pc_plus_33_shift, bc_decomposition_bytes_pc_plus_34_shift, bc_decomposition_bytes_pc_plus_4_shift, bc_decomposition_bytes_pc_plus_5_shift, bc_decomposition_bytes_pc_plus_6_shift, bc_decomposition_bytes_pc_plus_7_shift, bc_decomposition_bytes_pc_plus_8_shift, bc_decomposition_bytes_pc_plus_9_shift, bc_decomposition_bytes_remaining_shift, bc_decomposition_id_shift, bc_decomposition_pc_shift, bc_decomposition_sel_shift, bitwise_acc_ia_shift, bitwise_acc_ib_shift, bitwise_acc_ic_shift, bitwise_ctr_shift, bitwise_op_id_shift, execution_sel_shift, sha256_a_shift, sha256_b_shift, sha256_c_shift, sha256_d_shift, sha256_e_shift, sha256_f_shift, sha256_g_shift, sha256_h_shift, sha256_helper_w0_shift, sha256_helper_w1_shift, sha256_helper_w10_shift, sha256_helper_w11_shift, sha256_helper_w12_shift, sha256_helper_w13_shift, sha256_helper_w14_shift, sha256_helper_w15_shift, sha256_helper_w2_shift, sha256_helper_w3_shift, sha256_helper_w4_shift, sha256_helper_w5_shift, sha256_helper_w6_shift, sha256_helper_w7_shift, sha256_helper_w8_shift, sha256_helper_w9_shift, sha256_rounds_remaining_shift, sha256_sel_shift, sha256_start_shift -#define AVM2_TO_BE_SHIFTED(e) e.bc_decomposition_bytes, e.bc_decomposition_bytes_pc_plus_1, e.bc_decomposition_bytes_pc_plus_10, e.bc_decomposition_bytes_pc_plus_11, e.bc_decomposition_bytes_pc_plus_12, e.bc_decomposition_bytes_pc_plus_13, e.bc_decomposition_bytes_pc_plus_14, e.bc_decomposition_bytes_pc_plus_15, e.bc_decomposition_bytes_pc_plus_16, e.bc_decomposition_bytes_pc_plus_17, e.bc_decomposition_bytes_pc_plus_18, e.bc_decomposition_bytes_pc_plus_19, e.bc_decomposition_bytes_pc_plus_2, e.bc_decomposition_bytes_pc_plus_20, e.bc_decomposition_bytes_pc_plus_21, e.bc_decomposition_bytes_pc_plus_22, e.bc_decomposition_bytes_pc_plus_23, e.bc_decomposition_bytes_pc_plus_24, e.bc_decomposition_bytes_pc_plus_25, e.bc_decomposition_bytes_pc_plus_26, e.bc_decomposition_bytes_pc_plus_27, e.bc_decomposition_bytes_pc_plus_28, e.bc_decomposition_bytes_pc_plus_29, e.bc_decomposition_bytes_pc_plus_3, e.bc_decomposition_bytes_pc_plus_30, e.bc_decomposition_bytes_pc_plus_31, e.bc_decomposition_bytes_pc_plus_32, e.bc_decomposition_bytes_pc_plus_33, e.bc_decomposition_bytes_pc_plus_34, e.bc_decomposition_bytes_pc_plus_4, e.bc_decomposition_bytes_pc_plus_5, e.bc_decomposition_bytes_pc_plus_6, e.bc_decomposition_bytes_pc_plus_7, e.bc_decomposition_bytes_pc_plus_8, e.bc_decomposition_bytes_pc_plus_9, e.bc_decomposition_bytes_remaining, e.bc_decomposition_id, e.bc_decomposition_pc, e.bc_decomposition_sel, e.bitwise_acc_ia, e.bitwise_acc_ib, e.bitwise_acc_ic, e.bitwise_ctr, e.bitwise_op_id, e.execution_sel, e.sha256_a, e.sha256_b, e.sha256_c, e.sha256_d, e.sha256_e, e.sha256_f, e.sha256_g, e.sha256_h, e.sha256_helper_w0, e.sha256_helper_w1, e.sha256_helper_w10, e.sha256_helper_w11, e.sha256_helper_w12, e.sha256_helper_w13, e.sha256_helper_w14, e.sha256_helper_w15, e.sha256_helper_w2, e.sha256_helper_w3, e.sha256_helper_w4, e.sha256_helper_w5, e.sha256_helper_w6, e.sha256_helper_w7, e.sha256_helper_w8, e.sha256_helper_w9, e.sha256_rounds_remaining, e.sha256_sel, e.sha256_start +#define AVM2_WIRE_ENTITIES execution_input, alu_dst_addr, alu_ia, alu_ia_addr, alu_ib, alu_ib_addr, alu_ic, alu_op, alu_sel_op_add, bc_decomposition_abs_diff, bc_decomposition_bytes, bc_decomposition_bytes_pc_plus_1, bc_decomposition_bytes_pc_plus_10, bc_decomposition_bytes_pc_plus_11, bc_decomposition_bytes_pc_plus_12, bc_decomposition_bytes_pc_plus_13, bc_decomposition_bytes_pc_plus_14, bc_decomposition_bytes_pc_plus_15, bc_decomposition_bytes_pc_plus_16, bc_decomposition_bytes_pc_plus_17, bc_decomposition_bytes_pc_plus_18, bc_decomposition_bytes_pc_plus_19, bc_decomposition_bytes_pc_plus_2, bc_decomposition_bytes_pc_plus_20, bc_decomposition_bytes_pc_plus_21, bc_decomposition_bytes_pc_plus_22, bc_decomposition_bytes_pc_plus_23, bc_decomposition_bytes_pc_plus_24, bc_decomposition_bytes_pc_plus_25, bc_decomposition_bytes_pc_plus_26, bc_decomposition_bytes_pc_plus_27, bc_decomposition_bytes_pc_plus_28, bc_decomposition_bytes_pc_plus_29, bc_decomposition_bytes_pc_plus_3, bc_decomposition_bytes_pc_plus_30, bc_decomposition_bytes_pc_plus_31, bc_decomposition_bytes_pc_plus_32, bc_decomposition_bytes_pc_plus_33, bc_decomposition_bytes_pc_plus_34, bc_decomposition_bytes_pc_plus_35, bc_decomposition_bytes_pc_plus_4, bc_decomposition_bytes_pc_plus_5, bc_decomposition_bytes_pc_plus_6, bc_decomposition_bytes_pc_plus_7, bc_decomposition_bytes_pc_plus_8, bc_decomposition_bytes_pc_plus_9, bc_decomposition_bytes_rem_inv, bc_decomposition_bytes_rem_min_one_inv, bc_decomposition_bytes_remaining, bc_decomposition_bytes_to_read, bc_decomposition_bytes_to_read_unary, bc_decomposition_id, bc_decomposition_last_of_contract, bc_decomposition_pc, bc_decomposition_sel, bc_decomposition_sel_overflow_correction_needed, bc_decomposition_sel_pc_plus_1, bc_decomposition_sel_pc_plus_10, bc_decomposition_sel_pc_plus_11, bc_decomposition_sel_pc_plus_12, bc_decomposition_sel_pc_plus_13, bc_decomposition_sel_pc_plus_14, bc_decomposition_sel_pc_plus_15, bc_decomposition_sel_pc_plus_16, bc_decomposition_sel_pc_plus_17, bc_decomposition_sel_pc_plus_18, bc_decomposition_sel_pc_plus_19, bc_decomposition_sel_pc_plus_2, bc_decomposition_sel_pc_plus_20, bc_decomposition_sel_pc_plus_21, bc_decomposition_sel_pc_plus_22, bc_decomposition_sel_pc_plus_23, bc_decomposition_sel_pc_plus_24, bc_decomposition_sel_pc_plus_25, bc_decomposition_sel_pc_plus_26, bc_decomposition_sel_pc_plus_27, bc_decomposition_sel_pc_plus_28, bc_decomposition_sel_pc_plus_29, bc_decomposition_sel_pc_plus_3, bc_decomposition_sel_pc_plus_30, bc_decomposition_sel_pc_plus_31, bc_decomposition_sel_pc_plus_32, bc_decomposition_sel_pc_plus_33, bc_decomposition_sel_pc_plus_34, bc_decomposition_sel_pc_plus_35, bc_decomposition_sel_pc_plus_4, bc_decomposition_sel_pc_plus_5, bc_decomposition_sel_pc_plus_6, bc_decomposition_sel_pc_plus_7, bc_decomposition_sel_pc_plus_8, bc_decomposition_sel_pc_plus_9, bc_retrieval_address, bc_retrieval_artifact_hash, bc_retrieval_bytecode_id, bc_retrieval_class_id, bc_retrieval_deployer_addr, bc_retrieval_err, bc_retrieval_incoming_viewing_key_x, bc_retrieval_incoming_viewing_key_y, bc_retrieval_init_hash, bc_retrieval_nullifier_key_x, bc_retrieval_nullifier_key_y, bc_retrieval_outgoing_viewing_key_x, bc_retrieval_outgoing_viewing_key_y, bc_retrieval_private_function_root, bc_retrieval_public_bytecode_commitment, bc_retrieval_salt, bc_retrieval_sel, bc_retrieval_tagging_key_x, bc_retrieval_tagging_key_y, bitwise_acc_ia, bitwise_acc_ib, bitwise_acc_ic, bitwise_ctr, bitwise_ctr_inv, bitwise_ctr_min_one_inv, bitwise_ia_byte, bitwise_ib_byte, bitwise_ic_byte, bitwise_last, bitwise_op_id, bitwise_sel, bitwise_start, bitwise_tag, ecc_add_op, ecc_double_op, ecc_inv_2_p_y, ecc_inv_x_diff, ecc_inv_y_diff, ecc_lambda, ecc_p_is_inf, ecc_p_x, ecc_p_y, ecc_q_is_inf, ecc_q_x, ecc_q_y, ecc_r_is_inf, ecc_r_x, ecc_r_y, ecc_result_infinity, ecc_sel, ecc_x_match, ecc_y_match, execution_addressing_error_idx, execution_addressing_error_kind, execution_base_address_tag, execution_base_address_val, execution_bytecode_id, execution_clk, execution_ex_opcode, execution_indirect, execution_last, execution_op1, execution_op1_after_relative, execution_op2, execution_op2_after_relative, execution_op3, execution_op3_after_relative, execution_op4, execution_op4_after_relative, execution_pc, execution_rop1, execution_rop2, execution_rop3, execution_rop4, execution_sel, execution_sel_addressing_error, execution_sel_op1_is_address, execution_sel_op2_is_address, execution_sel_op3_is_address, execution_sel_op4_is_address, instr_fetching_bd0, instr_fetching_bd1, instr_fetching_bd10, instr_fetching_bd11, instr_fetching_bd12, instr_fetching_bd13, instr_fetching_bd14, instr_fetching_bd15, instr_fetching_bd16, instr_fetching_bd17, instr_fetching_bd18, instr_fetching_bd19, instr_fetching_bd2, instr_fetching_bd20, instr_fetching_bd21, instr_fetching_bd22, instr_fetching_bd23, instr_fetching_bd24, instr_fetching_bd25, instr_fetching_bd26, instr_fetching_bd27, instr_fetching_bd28, instr_fetching_bd29, instr_fetching_bd3, instr_fetching_bd30, instr_fetching_bd31, instr_fetching_bd32, instr_fetching_bd33, instr_fetching_bd34, instr_fetching_bd35, instr_fetching_bd4, instr_fetching_bd5, instr_fetching_bd6, instr_fetching_bd7, instr_fetching_bd8, instr_fetching_bd9, instr_fetching_bytecode_id, instr_fetching_ex_opcode, instr_fetching_fmt_3_op_u8, instr_fetching_indirect, instr_fetching_op1, instr_fetching_op2, instr_fetching_op3, instr_fetching_op4, instr_fetching_pc, instr_fetching_sel, poseidon2_hash_a_0, poseidon2_hash_a_1, poseidon2_hash_a_2, poseidon2_hash_a_3, poseidon2_hash_b_0, poseidon2_hash_b_1, poseidon2_hash_b_2, poseidon2_hash_b_3, poseidon2_hash_end, poseidon2_hash_execute_perm, poseidon2_hash_input_0, poseidon2_hash_input_1, poseidon2_hash_input_2, poseidon2_hash_input_len, poseidon2_hash_num_perm_rounds_rem, poseidon2_hash_num_perm_rounds_rem_inv, poseidon2_hash_output, poseidon2_hash_padding, poseidon2_hash_sel, poseidon2_hash_start, poseidon2_perm_B_10_0, poseidon2_perm_B_10_1, poseidon2_perm_B_10_2, poseidon2_perm_B_10_3, poseidon2_perm_B_11_0, poseidon2_perm_B_11_1, poseidon2_perm_B_11_2, poseidon2_perm_B_11_3, poseidon2_perm_B_12_0, poseidon2_perm_B_12_1, poseidon2_perm_B_12_2, poseidon2_perm_B_12_3, poseidon2_perm_B_13_0, poseidon2_perm_B_13_1, poseidon2_perm_B_13_2, poseidon2_perm_B_13_3, poseidon2_perm_B_14_0, poseidon2_perm_B_14_1, poseidon2_perm_B_14_2, poseidon2_perm_B_14_3, poseidon2_perm_B_15_0, poseidon2_perm_B_15_1, poseidon2_perm_B_15_2, poseidon2_perm_B_15_3, poseidon2_perm_B_16_0, poseidon2_perm_B_16_1, poseidon2_perm_B_16_2, poseidon2_perm_B_16_3, poseidon2_perm_B_17_0, poseidon2_perm_B_17_1, poseidon2_perm_B_17_2, poseidon2_perm_B_17_3, poseidon2_perm_B_18_0, poseidon2_perm_B_18_1, poseidon2_perm_B_18_2, poseidon2_perm_B_18_3, poseidon2_perm_B_19_0, poseidon2_perm_B_19_1, poseidon2_perm_B_19_2, poseidon2_perm_B_19_3, poseidon2_perm_B_20_0, poseidon2_perm_B_20_1, poseidon2_perm_B_20_2, poseidon2_perm_B_20_3, poseidon2_perm_B_21_0, poseidon2_perm_B_21_1, poseidon2_perm_B_21_2, poseidon2_perm_B_21_3, poseidon2_perm_B_22_0, poseidon2_perm_B_22_1, poseidon2_perm_B_22_2, poseidon2_perm_B_22_3, poseidon2_perm_B_23_0, poseidon2_perm_B_23_1, poseidon2_perm_B_23_2, poseidon2_perm_B_23_3, poseidon2_perm_B_24_0, poseidon2_perm_B_24_1, poseidon2_perm_B_24_2, poseidon2_perm_B_24_3, poseidon2_perm_B_25_0, poseidon2_perm_B_25_1, poseidon2_perm_B_25_2, poseidon2_perm_B_25_3, poseidon2_perm_B_26_0, poseidon2_perm_B_26_1, poseidon2_perm_B_26_2, poseidon2_perm_B_26_3, poseidon2_perm_B_27_0, poseidon2_perm_B_27_1, poseidon2_perm_B_27_2, poseidon2_perm_B_27_3, poseidon2_perm_B_28_0, poseidon2_perm_B_28_1, poseidon2_perm_B_28_2, poseidon2_perm_B_28_3, poseidon2_perm_B_29_0, poseidon2_perm_B_29_1, poseidon2_perm_B_29_2, poseidon2_perm_B_29_3, poseidon2_perm_B_30_0, poseidon2_perm_B_30_1, poseidon2_perm_B_30_2, poseidon2_perm_B_30_3, poseidon2_perm_B_31_0, poseidon2_perm_B_31_1, poseidon2_perm_B_31_2, poseidon2_perm_B_31_3, poseidon2_perm_B_32_0, poseidon2_perm_B_32_1, poseidon2_perm_B_32_2, poseidon2_perm_B_32_3, poseidon2_perm_B_33_0, poseidon2_perm_B_33_1, poseidon2_perm_B_33_2, poseidon2_perm_B_33_3, poseidon2_perm_B_34_0, poseidon2_perm_B_34_1, poseidon2_perm_B_34_2, poseidon2_perm_B_34_3, poseidon2_perm_B_35_0, poseidon2_perm_B_35_1, poseidon2_perm_B_35_2, poseidon2_perm_B_35_3, poseidon2_perm_B_36_0, poseidon2_perm_B_36_1, poseidon2_perm_B_36_2, poseidon2_perm_B_36_3, poseidon2_perm_B_37_0, poseidon2_perm_B_37_1, poseidon2_perm_B_37_2, poseidon2_perm_B_37_3, poseidon2_perm_B_38_0, poseidon2_perm_B_38_1, poseidon2_perm_B_38_2, poseidon2_perm_B_38_3, poseidon2_perm_B_39_0, poseidon2_perm_B_39_1, poseidon2_perm_B_39_2, poseidon2_perm_B_39_3, poseidon2_perm_B_40_0, poseidon2_perm_B_40_1, poseidon2_perm_B_40_2, poseidon2_perm_B_40_3, poseidon2_perm_B_41_0, poseidon2_perm_B_41_1, poseidon2_perm_B_41_2, poseidon2_perm_B_41_3, poseidon2_perm_B_42_0, poseidon2_perm_B_42_1, poseidon2_perm_B_42_2, poseidon2_perm_B_42_3, poseidon2_perm_B_43_0, poseidon2_perm_B_43_1, poseidon2_perm_B_43_2, poseidon2_perm_B_43_3, poseidon2_perm_B_44_0, poseidon2_perm_B_44_1, poseidon2_perm_B_44_2, poseidon2_perm_B_44_3, poseidon2_perm_B_45_0, poseidon2_perm_B_45_1, poseidon2_perm_B_45_2, poseidon2_perm_B_45_3, poseidon2_perm_B_46_0, poseidon2_perm_B_46_1, poseidon2_perm_B_46_2, poseidon2_perm_B_46_3, poseidon2_perm_B_47_0, poseidon2_perm_B_47_1, poseidon2_perm_B_47_2, poseidon2_perm_B_47_3, poseidon2_perm_B_48_0, poseidon2_perm_B_48_1, poseidon2_perm_B_48_2, poseidon2_perm_B_48_3, poseidon2_perm_B_49_0, poseidon2_perm_B_49_1, poseidon2_perm_B_49_2, poseidon2_perm_B_49_3, poseidon2_perm_B_4_0, poseidon2_perm_B_4_1, poseidon2_perm_B_4_2, poseidon2_perm_B_4_3, poseidon2_perm_B_50_0, poseidon2_perm_B_50_1, poseidon2_perm_B_50_2, poseidon2_perm_B_50_3, poseidon2_perm_B_51_0, poseidon2_perm_B_51_1, poseidon2_perm_B_51_2, poseidon2_perm_B_51_3, poseidon2_perm_B_52_0, poseidon2_perm_B_52_1, poseidon2_perm_B_52_2, poseidon2_perm_B_52_3, poseidon2_perm_B_53_0, poseidon2_perm_B_53_1, poseidon2_perm_B_53_2, poseidon2_perm_B_53_3, poseidon2_perm_B_54_0, poseidon2_perm_B_54_1, poseidon2_perm_B_54_2, poseidon2_perm_B_54_3, poseidon2_perm_B_55_0, poseidon2_perm_B_55_1, poseidon2_perm_B_55_2, poseidon2_perm_B_55_3, poseidon2_perm_B_56_0, poseidon2_perm_B_56_1, poseidon2_perm_B_56_2, poseidon2_perm_B_56_3, poseidon2_perm_B_57_0, poseidon2_perm_B_57_1, poseidon2_perm_B_57_2, poseidon2_perm_B_57_3, poseidon2_perm_B_58_0, poseidon2_perm_B_58_1, poseidon2_perm_B_58_2, poseidon2_perm_B_58_3, poseidon2_perm_B_59_0, poseidon2_perm_B_59_1, poseidon2_perm_B_59_2, poseidon2_perm_B_59_3, poseidon2_perm_B_5_0, poseidon2_perm_B_5_1, poseidon2_perm_B_5_2, poseidon2_perm_B_5_3, poseidon2_perm_B_6_0, poseidon2_perm_B_6_1, poseidon2_perm_B_6_2, poseidon2_perm_B_6_3, poseidon2_perm_B_7_0, poseidon2_perm_B_7_1, poseidon2_perm_B_7_2, poseidon2_perm_B_7_3, poseidon2_perm_B_8_0, poseidon2_perm_B_8_1, poseidon2_perm_B_8_2, poseidon2_perm_B_8_3, poseidon2_perm_B_9_0, poseidon2_perm_B_9_1, poseidon2_perm_B_9_2, poseidon2_perm_B_9_3, poseidon2_perm_EXT_LAYER_4, poseidon2_perm_EXT_LAYER_5, poseidon2_perm_EXT_LAYER_6, poseidon2_perm_EXT_LAYER_7, poseidon2_perm_T_0_4, poseidon2_perm_T_0_5, poseidon2_perm_T_0_6, poseidon2_perm_T_0_7, poseidon2_perm_T_1_4, poseidon2_perm_T_1_5, poseidon2_perm_T_1_6, poseidon2_perm_T_1_7, poseidon2_perm_T_2_4, poseidon2_perm_T_2_5, poseidon2_perm_T_2_6, poseidon2_perm_T_2_7, poseidon2_perm_T_3_4, poseidon2_perm_T_3_5, poseidon2_perm_T_3_6, poseidon2_perm_T_3_7, poseidon2_perm_T_60_4, poseidon2_perm_T_60_5, poseidon2_perm_T_60_6, poseidon2_perm_T_60_7, poseidon2_perm_T_61_4, poseidon2_perm_T_61_5, poseidon2_perm_T_61_6, poseidon2_perm_T_61_7, poseidon2_perm_T_62_4, poseidon2_perm_T_62_5, poseidon2_perm_T_62_6, poseidon2_perm_T_62_7, poseidon2_perm_T_63_4, poseidon2_perm_T_63_5, poseidon2_perm_T_63_6, poseidon2_perm_T_63_7, poseidon2_perm_a_0, poseidon2_perm_a_1, poseidon2_perm_a_2, poseidon2_perm_a_3, poseidon2_perm_b_0, poseidon2_perm_b_1, poseidon2_perm_b_2, poseidon2_perm_b_3, poseidon2_perm_sel, range_check_dyn_diff, range_check_dyn_rng_chk_bits, range_check_dyn_rng_chk_pow_2, range_check_is_lte_u112, range_check_is_lte_u128, range_check_is_lte_u16, range_check_is_lte_u32, range_check_is_lte_u48, range_check_is_lte_u64, range_check_is_lte_u80, range_check_is_lte_u96, range_check_rng_chk_bits, range_check_sel, range_check_sel_r0_16_bit_rng_lookup, range_check_sel_r1_16_bit_rng_lookup, range_check_sel_r2_16_bit_rng_lookup, range_check_sel_r3_16_bit_rng_lookup, range_check_sel_r4_16_bit_rng_lookup, range_check_sel_r5_16_bit_rng_lookup, range_check_sel_r6_16_bit_rng_lookup, range_check_u16_r0, range_check_u16_r1, range_check_u16_r2, range_check_u16_r3, range_check_u16_r4, range_check_u16_r5, range_check_u16_r6, range_check_u16_r7, range_check_value, sha256_a, sha256_a_and_b, sha256_a_and_b_xor_a_and_c, sha256_a_and_c, sha256_a_rotr_13, sha256_a_rotr_2, sha256_a_rotr_22, sha256_a_rotr_2_xor_a_rotr_13, sha256_and_sel, sha256_b, sha256_b_and_c, sha256_c, sha256_ch, sha256_clk, sha256_computed_w_lhs, sha256_computed_w_rhs, sha256_d, sha256_dummy_zero, sha256_e, sha256_e_and_f, sha256_e_rotr_11, sha256_e_rotr_25, sha256_e_rotr_6, sha256_e_rotr_6_xor_e_rotr_11, sha256_f, sha256_g, sha256_h, sha256_helper_w0, sha256_helper_w1, sha256_helper_w10, sha256_helper_w11, sha256_helper_w12, sha256_helper_w13, sha256_helper_w14, sha256_helper_w15, sha256_helper_w2, sha256_helper_w3, sha256_helper_w4, sha256_helper_w5, sha256_helper_w6, sha256_helper_w7, sha256_helper_w8, sha256_helper_w9, sha256_init_a, sha256_init_b, sha256_init_c, sha256_init_d, sha256_init_e, sha256_init_f, sha256_init_g, sha256_init_h, sha256_input_offset, sha256_is_input_round, sha256_latch, sha256_lhs_a_13, sha256_lhs_a_2, sha256_lhs_a_22, sha256_lhs_e_11, sha256_lhs_e_25, sha256_lhs_e_6, sha256_lhs_w_10, sha256_lhs_w_17, sha256_lhs_w_18, sha256_lhs_w_19, sha256_lhs_w_3, sha256_lhs_w_7, sha256_maj, sha256_next_a_lhs, sha256_next_a_rhs, sha256_next_e_lhs, sha256_next_e_rhs, sha256_not_e, sha256_not_e_and_g, sha256_output_a_lhs, sha256_output_a_rhs, sha256_output_b_lhs, sha256_output_b_rhs, sha256_output_c_lhs, sha256_output_c_rhs, sha256_output_d_lhs, sha256_output_d_rhs, sha256_output_e_lhs, sha256_output_e_rhs, sha256_output_f_lhs, sha256_output_f_rhs, sha256_output_g_lhs, sha256_output_g_rhs, sha256_output_h_lhs, sha256_output_h_rhs, sha256_output_offset, sha256_perform_round, sha256_rhs_a_13, sha256_rhs_a_2, sha256_rhs_a_22, sha256_rhs_e_11, sha256_rhs_e_25, sha256_rhs_e_6, sha256_rhs_w_10, sha256_rhs_w_17, sha256_rhs_w_18, sha256_rhs_w_19, sha256_rhs_w_3, sha256_rhs_w_7, sha256_round_constant, sha256_round_count, sha256_rounds_remaining, sha256_rounds_remaining_inv, sha256_s_0, sha256_s_1, sha256_sel, sha256_start, sha256_state_offset, sha256_w, sha256_w_15_rotr_18, sha256_w_15_rotr_7, sha256_w_15_rotr_7_xor_w_15_rotr_18, sha256_w_15_rshift_3, sha256_w_2_rotr_17, sha256_w_2_rotr_17_xor_w_2_rotr_19, sha256_w_2_rotr_19, sha256_w_2_rshift_10, sha256_w_s_0, sha256_w_s_1, sha256_xor_sel, lookup_bytecode_bytes_are_bytes_counts, lookup_bytecode_remaining_abs_diff_u16_counts, lookup_bytecode_to_read_unary_counts, lookup_rng_chk_pow_2_counts, lookup_rng_chk_diff_counts, lookup_rng_chk_is_r0_16_bit_counts, lookup_rng_chk_is_r1_16_bit_counts, lookup_rng_chk_is_r2_16_bit_counts, lookup_rng_chk_is_r3_16_bit_counts, lookup_rng_chk_is_r4_16_bit_counts, lookup_rng_chk_is_r5_16_bit_counts, lookup_rng_chk_is_r6_16_bit_counts, lookup_rng_chk_is_r7_16_bit_counts, lookup_bitw_byte_lengths_counts, lookup_bitw_byte_operations_counts, lookup_sha256_round_constant_counts, lookup_pos2_perm_counts, lookup_dummy_precomputed_counts, lookup_dummy_dynamic_counts +#define AVM2_DERIVED_WITNESS_ENTITIES perm_dummy_dynamic_inv, lookup_bytecode_bytes_are_bytes_inv, lookup_bytecode_remaining_abs_diff_u16_inv, lookup_bytecode_to_read_unary_inv, lookup_rng_chk_pow_2_inv, lookup_rng_chk_diff_inv, lookup_rng_chk_is_r0_16_bit_inv, lookup_rng_chk_is_r1_16_bit_inv, lookup_rng_chk_is_r2_16_bit_inv, lookup_rng_chk_is_r3_16_bit_inv, lookup_rng_chk_is_r4_16_bit_inv, lookup_rng_chk_is_r5_16_bit_inv, lookup_rng_chk_is_r6_16_bit_inv, lookup_rng_chk_is_r7_16_bit_inv, lookup_bitw_byte_lengths_inv, lookup_bitw_byte_operations_inv, lookup_sha256_round_constant_inv, lookup_pos2_perm_inv, lookup_dummy_precomputed_inv, lookup_dummy_dynamic_inv +#define AVM2_SHIFTED_ENTITIES bc_decomposition_bytes_shift, bc_decomposition_bytes_pc_plus_1_shift, bc_decomposition_bytes_pc_plus_10_shift, bc_decomposition_bytes_pc_plus_11_shift, bc_decomposition_bytes_pc_plus_12_shift, bc_decomposition_bytes_pc_plus_13_shift, bc_decomposition_bytes_pc_plus_14_shift, bc_decomposition_bytes_pc_plus_15_shift, bc_decomposition_bytes_pc_plus_16_shift, bc_decomposition_bytes_pc_plus_17_shift, bc_decomposition_bytes_pc_plus_18_shift, bc_decomposition_bytes_pc_plus_19_shift, bc_decomposition_bytes_pc_plus_2_shift, bc_decomposition_bytes_pc_plus_20_shift, bc_decomposition_bytes_pc_plus_21_shift, bc_decomposition_bytes_pc_plus_22_shift, bc_decomposition_bytes_pc_plus_23_shift, bc_decomposition_bytes_pc_plus_24_shift, bc_decomposition_bytes_pc_plus_25_shift, bc_decomposition_bytes_pc_plus_26_shift, bc_decomposition_bytes_pc_plus_27_shift, bc_decomposition_bytes_pc_plus_28_shift, bc_decomposition_bytes_pc_plus_29_shift, bc_decomposition_bytes_pc_plus_3_shift, bc_decomposition_bytes_pc_plus_30_shift, bc_decomposition_bytes_pc_plus_31_shift, bc_decomposition_bytes_pc_plus_32_shift, bc_decomposition_bytes_pc_plus_33_shift, bc_decomposition_bytes_pc_plus_34_shift, bc_decomposition_bytes_pc_plus_4_shift, bc_decomposition_bytes_pc_plus_5_shift, bc_decomposition_bytes_pc_plus_6_shift, bc_decomposition_bytes_pc_plus_7_shift, bc_decomposition_bytes_pc_plus_8_shift, bc_decomposition_bytes_pc_plus_9_shift, bc_decomposition_bytes_remaining_shift, bc_decomposition_id_shift, bc_decomposition_pc_shift, bc_decomposition_sel_shift, bitwise_acc_ia_shift, bitwise_acc_ib_shift, bitwise_acc_ic_shift, bitwise_ctr_shift, bitwise_op_id_shift, execution_sel_shift, poseidon2_hash_a_0_shift, poseidon2_hash_a_1_shift, poseidon2_hash_a_2_shift, poseidon2_hash_a_3_shift, poseidon2_hash_execute_perm_shift, poseidon2_hash_input_0_shift, poseidon2_hash_input_1_shift, poseidon2_hash_input_2_shift, poseidon2_hash_num_perm_rounds_rem_shift, poseidon2_hash_sel_shift, poseidon2_hash_start_shift, sha256_a_shift, sha256_b_shift, sha256_c_shift, sha256_d_shift, sha256_e_shift, sha256_f_shift, sha256_g_shift, sha256_h_shift, sha256_helper_w0_shift, sha256_helper_w1_shift, sha256_helper_w10_shift, sha256_helper_w11_shift, sha256_helper_w12_shift, sha256_helper_w13_shift, sha256_helper_w14_shift, sha256_helper_w15_shift, sha256_helper_w2_shift, sha256_helper_w3_shift, sha256_helper_w4_shift, sha256_helper_w5_shift, sha256_helper_w6_shift, sha256_helper_w7_shift, sha256_helper_w8_shift, sha256_helper_w9_shift, sha256_rounds_remaining_shift, sha256_sel_shift, sha256_start_shift +#define AVM2_TO_BE_SHIFTED(e) e.bc_decomposition_bytes, e.bc_decomposition_bytes_pc_plus_1, e.bc_decomposition_bytes_pc_plus_10, e.bc_decomposition_bytes_pc_plus_11, e.bc_decomposition_bytes_pc_plus_12, e.bc_decomposition_bytes_pc_plus_13, e.bc_decomposition_bytes_pc_plus_14, e.bc_decomposition_bytes_pc_plus_15, e.bc_decomposition_bytes_pc_plus_16, e.bc_decomposition_bytes_pc_plus_17, e.bc_decomposition_bytes_pc_plus_18, e.bc_decomposition_bytes_pc_plus_19, e.bc_decomposition_bytes_pc_plus_2, e.bc_decomposition_bytes_pc_plus_20, e.bc_decomposition_bytes_pc_plus_21, e.bc_decomposition_bytes_pc_plus_22, e.bc_decomposition_bytes_pc_plus_23, e.bc_decomposition_bytes_pc_plus_24, e.bc_decomposition_bytes_pc_plus_25, e.bc_decomposition_bytes_pc_plus_26, e.bc_decomposition_bytes_pc_plus_27, e.bc_decomposition_bytes_pc_plus_28, e.bc_decomposition_bytes_pc_plus_29, e.bc_decomposition_bytes_pc_plus_3, e.bc_decomposition_bytes_pc_plus_30, e.bc_decomposition_bytes_pc_plus_31, e.bc_decomposition_bytes_pc_plus_32, e.bc_decomposition_bytes_pc_plus_33, e.bc_decomposition_bytes_pc_plus_34, e.bc_decomposition_bytes_pc_plus_4, e.bc_decomposition_bytes_pc_plus_5, e.bc_decomposition_bytes_pc_plus_6, e.bc_decomposition_bytes_pc_plus_7, e.bc_decomposition_bytes_pc_plus_8, e.bc_decomposition_bytes_pc_plus_9, e.bc_decomposition_bytes_remaining, e.bc_decomposition_id, e.bc_decomposition_pc, e.bc_decomposition_sel, e.bitwise_acc_ia, e.bitwise_acc_ib, e.bitwise_acc_ic, e.bitwise_ctr, e.bitwise_op_id, e.execution_sel, e.poseidon2_hash_a_0, e.poseidon2_hash_a_1, e.poseidon2_hash_a_2, e.poseidon2_hash_a_3, e.poseidon2_hash_execute_perm, e.poseidon2_hash_input_0, e.poseidon2_hash_input_1, e.poseidon2_hash_input_2, e.poseidon2_hash_num_perm_rounds_rem, e.poseidon2_hash_sel, e.poseidon2_hash_start, e.sha256_a, e.sha256_b, e.sha256_c, e.sha256_d, e.sha256_e, e.sha256_f, e.sha256_g, e.sha256_h, e.sha256_helper_w0, e.sha256_helper_w1, e.sha256_helper_w10, e.sha256_helper_w11, e.sha256_helper_w12, e.sha256_helper_w13, e.sha256_helper_w14, e.sha256_helper_w15, e.sha256_helper_w2, e.sha256_helper_w3, e.sha256_helper_w4, e.sha256_helper_w5, e.sha256_helper_w6, e.sha256_helper_w7, e.sha256_helper_w8, e.sha256_helper_w9, e.sha256_rounds_remaining, e.sha256_sel, e.sha256_start #define AVM2_ALL_ENTITIES AVM2_PRECOMPUTED_ENTITIES, AVM2_WIRE_ENTITIES, AVM2_DERIVED_WITNESS_ENTITIES, AVM2_SHIFTED_ENTITIES #define AVM2_UNSHIFTED_ENTITIES AVM2_PRECOMPUTED_ENTITIES, AVM2_WIRE_ENTITIES, AVM2_DERIVED_WITNESS_ENTITIES #define AVM2_WITNESS_ENTITIES AVM2_WIRE_ENTITIES, AVM2_DERIVED_WITNESS_ENTITIES -#define AVM2_TO_BE_SHIFTED_COLUMNS Column::bc_decomposition_bytes, Column::bc_decomposition_bytes_pc_plus_1, Column::bc_decomposition_bytes_pc_plus_10, Column::bc_decomposition_bytes_pc_plus_11, Column::bc_decomposition_bytes_pc_plus_12, Column::bc_decomposition_bytes_pc_plus_13, Column::bc_decomposition_bytes_pc_plus_14, Column::bc_decomposition_bytes_pc_plus_15, Column::bc_decomposition_bytes_pc_plus_16, Column::bc_decomposition_bytes_pc_plus_17, Column::bc_decomposition_bytes_pc_plus_18, Column::bc_decomposition_bytes_pc_plus_19, Column::bc_decomposition_bytes_pc_plus_2, Column::bc_decomposition_bytes_pc_plus_20, Column::bc_decomposition_bytes_pc_plus_21, Column::bc_decomposition_bytes_pc_plus_22, Column::bc_decomposition_bytes_pc_plus_23, Column::bc_decomposition_bytes_pc_plus_24, Column::bc_decomposition_bytes_pc_plus_25, Column::bc_decomposition_bytes_pc_plus_26, Column::bc_decomposition_bytes_pc_plus_27, Column::bc_decomposition_bytes_pc_plus_28, Column::bc_decomposition_bytes_pc_plus_29, Column::bc_decomposition_bytes_pc_plus_3, Column::bc_decomposition_bytes_pc_plus_30, Column::bc_decomposition_bytes_pc_plus_31, Column::bc_decomposition_bytes_pc_plus_32, Column::bc_decomposition_bytes_pc_plus_33, Column::bc_decomposition_bytes_pc_plus_34, Column::bc_decomposition_bytes_pc_plus_4, Column::bc_decomposition_bytes_pc_plus_5, Column::bc_decomposition_bytes_pc_plus_6, Column::bc_decomposition_bytes_pc_plus_7, Column::bc_decomposition_bytes_pc_plus_8, Column::bc_decomposition_bytes_pc_plus_9, Column::bc_decomposition_bytes_remaining, Column::bc_decomposition_id, Column::bc_decomposition_pc, Column::bc_decomposition_sel, Column::bitwise_acc_ia, Column::bitwise_acc_ib, Column::bitwise_acc_ic, Column::bitwise_ctr, Column::bitwise_op_id, Column::execution_sel, Column::sha256_a, Column::sha256_b, Column::sha256_c, Column::sha256_d, Column::sha256_e, Column::sha256_f, Column::sha256_g, Column::sha256_h, Column::sha256_helper_w0, Column::sha256_helper_w1, Column::sha256_helper_w10, Column::sha256_helper_w11, Column::sha256_helper_w12, Column::sha256_helper_w13, Column::sha256_helper_w14, Column::sha256_helper_w15, Column::sha256_helper_w2, Column::sha256_helper_w3, Column::sha256_helper_w4, Column::sha256_helper_w5, Column::sha256_helper_w6, Column::sha256_helper_w7, Column::sha256_helper_w8, Column::sha256_helper_w9, Column::sha256_rounds_remaining, Column::sha256_sel, Column::sha256_start -#define AVM2_SHIFTED_COLUMNS ColumnAndShifts::bc_decomposition_bytes_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_1_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_10_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_11_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_12_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_13_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_14_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_15_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_16_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_17_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_18_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_19_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_2_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_20_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_21_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_22_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_23_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_24_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_25_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_26_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_27_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_28_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_29_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_3_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_30_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_31_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_32_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_33_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_34_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_4_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_5_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_6_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_7_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_8_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_9_shift, ColumnAndShifts::bc_decomposition_bytes_remaining_shift, ColumnAndShifts::bc_decomposition_id_shift, ColumnAndShifts::bc_decomposition_pc_shift, ColumnAndShifts::bc_decomposition_sel_shift, ColumnAndShifts::bitwise_acc_ia_shift, ColumnAndShifts::bitwise_acc_ib_shift, ColumnAndShifts::bitwise_acc_ic_shift, ColumnAndShifts::bitwise_ctr_shift, ColumnAndShifts::bitwise_op_id_shift, ColumnAndShifts::execution_sel_shift, ColumnAndShifts::sha256_a_shift, ColumnAndShifts::sha256_b_shift, ColumnAndShifts::sha256_c_shift, ColumnAndShifts::sha256_d_shift, ColumnAndShifts::sha256_e_shift, ColumnAndShifts::sha256_f_shift, ColumnAndShifts::sha256_g_shift, ColumnAndShifts::sha256_h_shift, ColumnAndShifts::sha256_helper_w0_shift, ColumnAndShifts::sha256_helper_w1_shift, ColumnAndShifts::sha256_helper_w10_shift, ColumnAndShifts::sha256_helper_w11_shift, ColumnAndShifts::sha256_helper_w12_shift, ColumnAndShifts::sha256_helper_w13_shift, ColumnAndShifts::sha256_helper_w14_shift, ColumnAndShifts::sha256_helper_w15_shift, ColumnAndShifts::sha256_helper_w2_shift, ColumnAndShifts::sha256_helper_w3_shift, ColumnAndShifts::sha256_helper_w4_shift, ColumnAndShifts::sha256_helper_w5_shift, ColumnAndShifts::sha256_helper_w6_shift, ColumnAndShifts::sha256_helper_w7_shift, ColumnAndShifts::sha256_helper_w8_shift, ColumnAndShifts::sha256_helper_w9_shift, ColumnAndShifts::sha256_rounds_remaining_shift, ColumnAndShifts::sha256_sel_shift, ColumnAndShifts::sha256_start_shift +#define AVM2_TO_BE_SHIFTED_COLUMNS Column::bc_decomposition_bytes, Column::bc_decomposition_bytes_pc_plus_1, Column::bc_decomposition_bytes_pc_plus_10, Column::bc_decomposition_bytes_pc_plus_11, Column::bc_decomposition_bytes_pc_plus_12, Column::bc_decomposition_bytes_pc_plus_13, Column::bc_decomposition_bytes_pc_plus_14, Column::bc_decomposition_bytes_pc_plus_15, Column::bc_decomposition_bytes_pc_plus_16, Column::bc_decomposition_bytes_pc_plus_17, Column::bc_decomposition_bytes_pc_plus_18, Column::bc_decomposition_bytes_pc_plus_19, Column::bc_decomposition_bytes_pc_plus_2, Column::bc_decomposition_bytes_pc_plus_20, Column::bc_decomposition_bytes_pc_plus_21, Column::bc_decomposition_bytes_pc_plus_22, Column::bc_decomposition_bytes_pc_plus_23, Column::bc_decomposition_bytes_pc_plus_24, Column::bc_decomposition_bytes_pc_plus_25, Column::bc_decomposition_bytes_pc_plus_26, Column::bc_decomposition_bytes_pc_plus_27, Column::bc_decomposition_bytes_pc_plus_28, Column::bc_decomposition_bytes_pc_plus_29, Column::bc_decomposition_bytes_pc_plus_3, Column::bc_decomposition_bytes_pc_plus_30, Column::bc_decomposition_bytes_pc_plus_31, Column::bc_decomposition_bytes_pc_plus_32, Column::bc_decomposition_bytes_pc_plus_33, Column::bc_decomposition_bytes_pc_plus_34, Column::bc_decomposition_bytes_pc_plus_4, Column::bc_decomposition_bytes_pc_plus_5, Column::bc_decomposition_bytes_pc_plus_6, Column::bc_decomposition_bytes_pc_plus_7, Column::bc_decomposition_bytes_pc_plus_8, Column::bc_decomposition_bytes_pc_plus_9, Column::bc_decomposition_bytes_remaining, Column::bc_decomposition_id, Column::bc_decomposition_pc, Column::bc_decomposition_sel, Column::bitwise_acc_ia, Column::bitwise_acc_ib, Column::bitwise_acc_ic, Column::bitwise_ctr, Column::bitwise_op_id, Column::execution_sel, Column::poseidon2_hash_a_0, Column::poseidon2_hash_a_1, Column::poseidon2_hash_a_2, Column::poseidon2_hash_a_3, Column::poseidon2_hash_execute_perm, Column::poseidon2_hash_input_0, Column::poseidon2_hash_input_1, Column::poseidon2_hash_input_2, Column::poseidon2_hash_num_perm_rounds_rem, Column::poseidon2_hash_sel, Column::poseidon2_hash_start, Column::sha256_a, Column::sha256_b, Column::sha256_c, Column::sha256_d, Column::sha256_e, Column::sha256_f, Column::sha256_g, Column::sha256_h, Column::sha256_helper_w0, Column::sha256_helper_w1, Column::sha256_helper_w10, Column::sha256_helper_w11, Column::sha256_helper_w12, Column::sha256_helper_w13, Column::sha256_helper_w14, Column::sha256_helper_w15, Column::sha256_helper_w2, Column::sha256_helper_w3, Column::sha256_helper_w4, Column::sha256_helper_w5, Column::sha256_helper_w6, Column::sha256_helper_w7, Column::sha256_helper_w8, Column::sha256_helper_w9, Column::sha256_rounds_remaining, Column::sha256_sel, Column::sha256_start +#define AVM2_SHIFTED_COLUMNS ColumnAndShifts::bc_decomposition_bytes_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_1_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_10_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_11_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_12_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_13_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_14_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_15_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_16_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_17_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_18_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_19_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_2_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_20_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_21_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_22_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_23_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_24_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_25_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_26_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_27_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_28_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_29_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_3_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_30_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_31_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_32_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_33_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_34_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_4_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_5_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_6_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_7_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_8_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_9_shift, ColumnAndShifts::bc_decomposition_bytes_remaining_shift, ColumnAndShifts::bc_decomposition_id_shift, ColumnAndShifts::bc_decomposition_pc_shift, ColumnAndShifts::bc_decomposition_sel_shift, ColumnAndShifts::bitwise_acc_ia_shift, ColumnAndShifts::bitwise_acc_ib_shift, ColumnAndShifts::bitwise_acc_ic_shift, ColumnAndShifts::bitwise_ctr_shift, ColumnAndShifts::bitwise_op_id_shift, ColumnAndShifts::execution_sel_shift, ColumnAndShifts::poseidon2_hash_a_0_shift, ColumnAndShifts::poseidon2_hash_a_1_shift, ColumnAndShifts::poseidon2_hash_a_2_shift, ColumnAndShifts::poseidon2_hash_a_3_shift, ColumnAndShifts::poseidon2_hash_execute_perm_shift, ColumnAndShifts::poseidon2_hash_input_0_shift, ColumnAndShifts::poseidon2_hash_input_1_shift, ColumnAndShifts::poseidon2_hash_input_2_shift, ColumnAndShifts::poseidon2_hash_num_perm_rounds_rem_shift, ColumnAndShifts::poseidon2_hash_sel_shift, ColumnAndShifts::poseidon2_hash_start_shift, ColumnAndShifts::sha256_a_shift, ColumnAndShifts::sha256_b_shift, ColumnAndShifts::sha256_c_shift, ColumnAndShifts::sha256_d_shift, ColumnAndShifts::sha256_e_shift, ColumnAndShifts::sha256_f_shift, ColumnAndShifts::sha256_g_shift, ColumnAndShifts::sha256_h_shift, ColumnAndShifts::sha256_helper_w0_shift, ColumnAndShifts::sha256_helper_w1_shift, ColumnAndShifts::sha256_helper_w10_shift, ColumnAndShifts::sha256_helper_w11_shift, ColumnAndShifts::sha256_helper_w12_shift, ColumnAndShifts::sha256_helper_w13_shift, ColumnAndShifts::sha256_helper_w14_shift, ColumnAndShifts::sha256_helper_w15_shift, ColumnAndShifts::sha256_helper_w2_shift, ColumnAndShifts::sha256_helper_w3_shift, ColumnAndShifts::sha256_helper_w4_shift, ColumnAndShifts::sha256_helper_w5_shift, ColumnAndShifts::sha256_helper_w6_shift, ColumnAndShifts::sha256_helper_w7_shift, ColumnAndShifts::sha256_helper_w8_shift, ColumnAndShifts::sha256_helper_w9_shift, ColumnAndShifts::sha256_rounds_remaining_shift, ColumnAndShifts::sha256_sel_shift, ColumnAndShifts::sha256_start_shift // clang-format on // All columns minus shifts. @@ -31,8 +31,8 @@ enum class ColumnAndShifts { SENTINEL_DO_NOT_USE, }; -constexpr auto NUM_COLUMNS_WITH_SHIFTS = 495; -constexpr auto NUM_COLUMNS_WITHOUT_SHIFTS = 423; +constexpr auto NUM_COLUMNS_WITH_SHIFTS = 797; +constexpr auto NUM_COLUMNS_WITHOUT_SHIFTS = 714; constexpr auto TO_BE_SHIFTED_COLUMNS_ARRAY = []() { return std::array{ AVM2_TO_BE_SHIFTED_COLUMNS }; }(); constexpr auto SHIFTED_COLUMNS_ARRAY = []() { return std::array{ AVM2_SHIFTED_COLUMNS }; }(); static_assert(TO_BE_SHIFTED_COLUMNS_ARRAY.size() == SHIFTED_COLUMNS_ARRAY.size()); diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/flavor.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/flavor.hpp index ce332646db4..24e4fdc6ddf 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/flavor.hpp @@ -25,6 +25,8 @@ #include "relations/ecc.hpp" #include "relations/execution.hpp" #include "relations/instr_fetching.hpp" +#include "relations/poseidon2_hash.hpp" +#include "relations/poseidon2_perm.hpp" #include "relations/range_check.hpp" #include "relations/sha256.hpp" @@ -32,6 +34,7 @@ #include "relations/lookups_bc_decomposition.hpp" #include "relations/lookups_bitwise.hpp" #include "relations/lookups_execution.hpp" +#include "relations/lookups_poseidon2_hash.hpp" #include "relations/lookups_range_check.hpp" #include "relations/lookups_sha256.hpp" #include "relations/perms_execution.hpp" @@ -77,12 +80,12 @@ class AvmFlavor { static constexpr bool HasZK = false; static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 16; - static constexpr size_t NUM_WITNESS_ENTITIES = 407; - static constexpr size_t NUM_SHIFTED_ENTITIES = 72; + static constexpr size_t NUM_WITNESS_ENTITIES = 698; + static constexpr size_t NUM_SHIFTED_ENTITIES = 83; static constexpr size_t NUM_WIRES = NUM_WITNESS_ENTITIES + NUM_PRECOMPUTED_ENTITIES; // We have two copies of the witness entities, so we subtract the number of fixed ones (they have no shift), one for // the unshifted and one for the shifted - static constexpr size_t NUM_ALL_ENTITIES = 495; + static constexpr size_t NUM_ALL_ENTITIES = 797; // Need to be templated for recursive verifier template @@ -95,6 +98,8 @@ class AvmFlavor { avm2::ecc, avm2::execution, avm2::instr_fetching, + avm2::poseidon2_hash, + avm2::poseidon2_perm, avm2::range_check, avm2::sha256>; @@ -111,6 +116,7 @@ class AvmFlavor { lookup_bytecode_to_read_unary_relation, lookup_dummy_dynamic_relation, lookup_dummy_precomputed_relation, + lookup_pos2_perm_relation, lookup_rng_chk_diff_relation, lookup_rng_chk_is_r0_16_bit_relation, lookup_rng_chk_is_r1_16_bit_relation, diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_poseidon2_hash.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_poseidon2_hash.hpp new file mode 100644 index 00000000000..cfae61f9f46 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_poseidon2_hash.hpp @@ -0,0 +1,113 @@ +// AUTOGENERATED FILE +#pragma once + +#include "../columns.hpp" +#include "barretenberg/relations/generic_lookup/generic_lookup_relation.hpp" + +#include +#include +#include + +namespace bb::avm2 { + +/////////////////// lookup_pos2_perm /////////////////// + +class lookup_pos2_perm_lookup_settings { + public: + static constexpr std::string_view NAME = "LOOKUP_POS2_PERM"; + + static constexpr size_t READ_TERMS = 1; + static constexpr size_t WRITE_TERMS = 1; + static constexpr size_t READ_TERM_TYPES[READ_TERMS] = { 0 }; + static constexpr size_t WRITE_TERM_TYPES[WRITE_TERMS] = { 0 }; + static constexpr size_t LOOKUP_TUPLE_SIZE = 8; + static constexpr size_t INVERSE_EXISTS_POLYNOMIAL_DEGREE = 4; + static constexpr size_t READ_TERM_DEGREE = 0; + static constexpr size_t WRITE_TERM_DEGREE = 0; + + // Columns using the Column enum. + static constexpr Column SRC_SELECTOR = Column::poseidon2_hash_sel; + static constexpr Column DST_SELECTOR = Column::poseidon2_perm_sel; + static constexpr Column COUNTS = Column::lookup_pos2_perm_counts; + static constexpr Column INVERSES = Column::lookup_pos2_perm_inv; + static constexpr std::array SRC_COLUMNS = { + Column::poseidon2_hash_a_0, Column::poseidon2_hash_a_1, Column::poseidon2_hash_a_2, Column::poseidon2_hash_a_3, + Column::poseidon2_hash_b_0, Column::poseidon2_hash_b_1, Column::poseidon2_hash_b_2, Column::poseidon2_hash_b_3 + }; + static constexpr std::array DST_COLUMNS = { + Column::poseidon2_perm_a_0, Column::poseidon2_perm_a_1, Column::poseidon2_perm_a_2, Column::poseidon2_perm_a_3, + Column::poseidon2_perm_b_0, Column::poseidon2_perm_b_1, Column::poseidon2_perm_b_2, Column::poseidon2_perm_b_3 + }; + + template static inline auto inverse_polynomial_is_computed_at_row(const AllEntities& in) + { + return (in._poseidon2_hash_sel() == 1 || in._poseidon2_perm_sel() == 1); + } + + template + static inline auto compute_inverse_exists(const AllEntities& in) + { + using View = typename Accumulator::View; + const auto is_operation = View(in._poseidon2_hash_sel()); + const auto is_table_entry = View(in._poseidon2_perm_sel()); + return (is_operation + is_table_entry - is_operation * is_table_entry); + } + + template static inline auto get_const_entities(const AllEntities& in) + { + return get_entities(in); + } + + template static inline auto get_nonconst_entities(AllEntities& in) + { + return get_entities(in); + } + + template static inline auto get_entities(AllEntities&& in) + { + return std::forward_as_tuple(in._lookup_pos2_perm_inv(), + in._lookup_pos2_perm_counts(), + in._poseidon2_hash_sel(), + in._poseidon2_perm_sel(), + in._poseidon2_hash_a_0(), + in._poseidon2_hash_a_1(), + in._poseidon2_hash_a_2(), + in._poseidon2_hash_a_3(), + in._poseidon2_hash_b_0(), + in._poseidon2_hash_b_1(), + in._poseidon2_hash_b_2(), + in._poseidon2_hash_b_3(), + in._poseidon2_perm_a_0(), + in._poseidon2_perm_a_1(), + in._poseidon2_perm_a_2(), + in._poseidon2_perm_a_3(), + in._poseidon2_perm_b_0(), + in._poseidon2_perm_b_1(), + in._poseidon2_perm_b_2(), + in._poseidon2_perm_b_3()); + } +}; + +template +class lookup_pos2_perm_relation : public GenericLookupRelation { + public: + using Settings = lookup_pos2_perm_lookup_settings; + static constexpr std::string_view NAME = lookup_pos2_perm_lookup_settings::NAME; + + template inline static bool skip(const AllEntities& in) + { + return in.poseidon2_hash_sel.is_zero() && in.poseidon2_perm_sel.is_zero(); + } + + static std::string get_subrelation_label(size_t index) + { + if (index == 0) { + return "INVERSES_ARE_CORRECT"; + } else if (index == 1) { + return "ACCUMULATION_IS_CORRECT"; + } + return std::to_string(index); + } +}; + +} // namespace bb::avm2 \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/poseidon2_hash.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/poseidon2_hash.hpp new file mode 100644 index 00000000000..0ea9834af53 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/poseidon2_hash.hpp @@ -0,0 +1,191 @@ +// AUTOGENERATED FILE +#pragma once + +#include + +#include "barretenberg/relations/relation_parameters.hpp" +#include "barretenberg/relations/relation_types.hpp" + +namespace bb::avm2 { + +template class poseidon2_hashImpl { + public: + using FF = FF_; + + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { 3, 2, 3, 4, 4, 3, 3, 3, 5, 3, + 3, 3, 3, 6, 3, 6, 3, 6, 3, 6 }; + + template inline static bool skip(const AllEntities& in) + { + const auto& new_term = in; + return (new_term.poseidon2_hash_sel).is_zero(); + } + + template + void static accumulate(ContainerOverSubrelations& evals, + const AllEntities& new_term, + [[maybe_unused]] const RelationParameters&, + [[maybe_unused]] const FF& scaling_factor) + { + const auto poseidon2_hash_TWOPOW64 = FF(uint256_t{ 0UL, 1UL, 0UL, 0UL }); + const auto poseidon2_hash_IV = poseidon2_hash_TWOPOW64 * new_term.poseidon2_hash_input_len; + const auto poseidon2_hash_PADDED_LEN = new_term.poseidon2_hash_input_len + new_term.poseidon2_hash_padding; + const auto poseidon2_hash_NEXT_INPUT_IS_PREV_OUTPUT_SEL = new_term.poseidon2_hash_execute_perm_shift * + (FF(1) - new_term.poseidon2_hash_start) * + new_term.poseidon2_hash_execute_perm; + + { + using Accumulator = typename std::tuple_element_t<0, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_hash_sel * (FF(1) - new_term.poseidon2_hash_sel); + tmp *= scaling_factor; + std::get<0>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<1, ContainerOverSubrelations>; + auto tmp = + (new_term.poseidon2_hash_sel - (new_term.poseidon2_hash_execute_perm + new_term.poseidon2_hash_end)); + tmp *= scaling_factor; + std::get<1>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<2, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_hash_start * (FF(1) - new_term.poseidon2_hash_start); + tmp *= scaling_factor; + std::get<2>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<3, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_hash_sel_shift * (FF(1) - new_term.precomputed_first_row) * + (new_term.poseidon2_hash_start_shift - new_term.poseidon2_hash_end); + tmp *= scaling_factor; + std::get<3>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<4, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_hash_padding * (new_term.poseidon2_hash_padding - FF(1)) * + (new_term.poseidon2_hash_padding - FF(2)); + tmp *= scaling_factor; + std::get<4>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<5, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_hash_start * + ((new_term.poseidon2_hash_num_perm_rounds_rem + FF(1)) * FF(3) - poseidon2_hash_PADDED_LEN); + tmp *= scaling_factor; + std::get<5>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<6, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_hash_end * (FF(1) - new_term.poseidon2_hash_end); + tmp *= scaling_factor; + std::get<6>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<7, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_hash_end * (new_term.poseidon2_hash_output - new_term.poseidon2_hash_b_0); + tmp *= scaling_factor; + std::get<7>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<8, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_hash_sel * + ((new_term.poseidon2_hash_num_perm_rounds_rem * + (new_term.poseidon2_hash_end * (FF(1) - new_term.poseidon2_hash_num_perm_rounds_rem_inv) + + new_term.poseidon2_hash_num_perm_rounds_rem_inv) - + FF(1)) + + new_term.poseidon2_hash_end); + tmp *= scaling_factor; + std::get<8>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<9, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_hash_execute_perm * (FF(1) - new_term.poseidon2_hash_execute_perm); + tmp *= scaling_factor; + std::get<9>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<10, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_hash_sel * + ((FF(1) - new_term.poseidon2_hash_end) - new_term.poseidon2_hash_execute_perm); + tmp *= scaling_factor; + std::get<10>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<11, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_hash_execute_perm * + ((new_term.poseidon2_hash_num_perm_rounds_rem_shift - new_term.poseidon2_hash_num_perm_rounds_rem) + + FF(1)); + tmp *= scaling_factor; + std::get<11>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<12, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_hash_start * (new_term.poseidon2_hash_a_0 - new_term.poseidon2_hash_input_0); + tmp *= scaling_factor; + std::get<12>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<13, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_hash_sel * poseidon2_hash_NEXT_INPUT_IS_PREV_OUTPUT_SEL * + ((new_term.poseidon2_hash_a_0_shift - new_term.poseidon2_hash_b_0) - + new_term.poseidon2_hash_input_0_shift); + tmp *= scaling_factor; + std::get<13>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<14, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_hash_start * (new_term.poseidon2_hash_a_1 - new_term.poseidon2_hash_input_1); + tmp *= scaling_factor; + std::get<14>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<15, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_hash_sel * poseidon2_hash_NEXT_INPUT_IS_PREV_OUTPUT_SEL * + ((new_term.poseidon2_hash_a_1_shift - new_term.poseidon2_hash_b_1) - + new_term.poseidon2_hash_input_1_shift); + tmp *= scaling_factor; + std::get<15>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<16, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_hash_start * (new_term.poseidon2_hash_a_2 - new_term.poseidon2_hash_input_2); + tmp *= scaling_factor; + std::get<16>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<17, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_hash_sel * poseidon2_hash_NEXT_INPUT_IS_PREV_OUTPUT_SEL * + ((new_term.poseidon2_hash_a_2_shift - new_term.poseidon2_hash_b_2) - + new_term.poseidon2_hash_input_2_shift); + tmp *= scaling_factor; + std::get<17>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<18, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_hash_start * (new_term.poseidon2_hash_a_3 - poseidon2_hash_IV); + tmp *= scaling_factor; + std::get<18>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<19, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_hash_sel * poseidon2_hash_NEXT_INPUT_IS_PREV_OUTPUT_SEL * + (new_term.poseidon2_hash_a_3_shift - new_term.poseidon2_hash_b_3); + tmp *= scaling_factor; + std::get<19>(evals) += typename Accumulator::View(tmp); + } + } +}; + +template class poseidon2_hash : public Relation> { + public: + static constexpr const std::string_view NAME = "poseidon2_hash"; + + static std::string get_subrelation_label(size_t index) + { + switch (index) {} + return std::to_string(index); + } +}; + +} // namespace bb::avm2 \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/poseidon2_perm.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/poseidon2_perm.hpp new file mode 100644 index 00000000000..1ee4079a428 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/poseidon2_perm.hpp @@ -0,0 +1,3231 @@ +// AUTOGENERATED FILE +#pragma once + +#include + +#include "barretenberg/relations/relation_parameters.hpp" +#include "barretenberg/relations/relation_types.hpp" + +namespace bb::avm2 { + +template class poseidon2_permImpl { + public: + using FF = FF_; + + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { + 3, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 3, 3, 3, 3 + }; + + template inline static bool skip(const AllEntities& in) + { + const auto& new_term = in; + return (new_term.poseidon2_perm_sel).is_zero(); + } + + template + void static accumulate(ContainerOverSubrelations& evals, + const AllEntities& new_term, + [[maybe_unused]] const RelationParameters&, + [[maybe_unused]] const FF& scaling_factor) + { + const auto poseidon2_params_MU_0 = + FF(uint256_t{ 13071735289386612455UL, 937867514930142591UL, 338297992309721356UL, 1214967615784395659UL }); + const auto poseidon2_params_MU_1 = + FF(uint256_t{ 12135856085615145995UL, 11087747206803725188UL, 92802976007797685UL, 875972510381039422UL }); + const auto poseidon2_params_MU_2 = + FF(uint256_t{ 8072276821399088149UL, 12835106910674049377UL, 12882375598172350360UL, 23726925003953432UL }); + const auto poseidon2_params_MU_3 = + FF(uint256_t{ 1422103134736368267UL, 5972060781611222310UL, 3327741120806881763UL, 2462344296021899375UL }); + const auto poseidon2_params_C_0_0 = + FF(uint256_t{ 10018390284920759269UL, 196898842818127395UL, 5249540449481148995UL, 1853312570062057576UL }); + const auto poseidon2_params_C_0_1 = FF( + uint256_t{ 12486221224710452438UL, 2372038863109147677UL, 8230667498854222355UL, 2764611904404804029UL }); + const auto poseidon2_params_C_0_2 = FF( + uint256_t{ 4466505105966356650UL, 4686185096558265002UL, 16210260819355521378UL, 1844031548168280073UL }); + const auto poseidon2_params_C_0_3 = FF( + uint256_t{ 15002325471271702008UL, 5581154705073500415UL, 1229208533183169201UL, 1549225070791782920UL }); + const auto poseidon2_params_C_1_0 = + FF(uint256_t{ 18309653156114024706UL, 798761732958817262UL, 6904962453156279281UL, 3335412762186210716UL }); + const auto poseidon2_params_C_1_1 = + FF(uint256_t{ 2824096028161810206UL, 14640933461146357672UL, 957840840567621315UL, 1024001058677493842UL }); + const auto poseidon2_params_C_1_2 = FF( + uint256_t{ 14339023814126516630UL, 12239068001133297662UL, 428134084092645147UL, 2673682960814460689UL }); + const auto poseidon2_params_C_1_3 = FF( + uint256_t{ 6214865908119297870UL, 17923963059035301363UL, 10985380589240272449UL, 1430464474809378870UL }); + const auto poseidon2_params_C_2_0 = + FF(uint256_t{ 5109255232332580664UL, 11913027714091798733UL, 4449570166290740355UL, 864862123557185234UL }); + const auto poseidon2_params_C_2_1 = + FF(uint256_t{ 2323272968957708806UL, 354488099726909104UL, 115174089281514891UL, 80808271106704719UL }); + const auto poseidon2_params_C_2_2 = + FF(uint256_t{ 9646436663147525449UL, 3404572679246369876UL, 2350204275212843361UL, 1069216089054537871UL }); + const auto poseidon2_params_C_2_3 = + FF(uint256_t{ 5059356740217174171UL, 4245857056683447103UL, 2426504795124362174UL, 350059533408463330UL }); + const auto poseidon2_params_C_3_0 = + FF(uint256_t{ 14876286709841668328UL, 6932857857384975351UL, 7976037835777844091UL, 738350885205242785UL }); + const auto poseidon2_params_C_3_1 = FF( + uint256_t{ 16522097747524989503UL, 4157368317794149558UL, 10343110624935622906UL, 2709590753056582169UL }); + const auto poseidon2_params_C_3_2 = FF( + uint256_t{ 8805379462752425633UL, 8594508728147436821UL, 15629690186821248127UL, 2936193411053712582UL }); + const auto poseidon2_params_C_3_3 = FF( + uint256_t{ 17046614324338172999UL, 14086280776151114414UL, 2804088968006330580UL, 728643340397380469UL }); + const auto poseidon2_params_C_4_0 = + FF(uint256_t{ 12986735346000814543UL, 6140074342411686364UL, 6041575944194691717UL, 896092723329689904UL }); + const auto poseidon2_params_C_4_1 = FF(0); + const auto poseidon2_params_C_4_2 = FF(0); + const auto poseidon2_params_C_4_3 = FF(0); + const auto poseidon2_params_C_5_0 = FF( + uint256_t{ 9573905030842087441UL, 12243211539080976096UL, 15287161151491266826UL, 1310836290481124728UL }); + const auto poseidon2_params_C_5_1 = FF(0); + const auto poseidon2_params_C_5_2 = FF(0); + const auto poseidon2_params_C_5_3 = FF(0); + const auto poseidon2_params_C_6_0 = + FF(uint256_t{ 8865134002163281525UL, 6813849753829831047UL, 9066778847678578696UL, 2801725307463304665UL }); + const auto poseidon2_params_C_6_1 = FF(0); + const auto poseidon2_params_C_6_2 = FF(0); + const auto poseidon2_params_C_6_3 = FF(0); + const auto poseidon2_params_C_7_0 = FF( + uint256_t{ 4931814869361681093UL, 13712769805002511750UL, 1776191062268299644UL, 2068661504023016414UL }); + const auto poseidon2_params_C_7_1 = FF(0); + const auto poseidon2_params_C_7_2 = FF(0); + const auto poseidon2_params_C_7_3 = FF(0); + const auto poseidon2_params_C_8_0 = + FF(uint256_t{ 8161631444256445904UL, 3049786034047984668UL, 1021328518293651309UL, 2147500022207188878UL }); + const auto poseidon2_params_C_8_1 = FF(0); + const auto poseidon2_params_C_8_2 = FF(0); + const auto poseidon2_params_C_8_3 = FF(0); + const auto poseidon2_params_C_9_0 = + FF(uint256_t{ 12766468767470212468UL, 926098071429114297UL, 17691598410912255471UL, 76565467953470566UL }); + const auto poseidon2_params_C_9_1 = FF(0); + const auto poseidon2_params_C_9_2 = FF(0); + const auto poseidon2_params_C_9_3 = FF(0); + const auto poseidon2_params_C_10_0 = FF( + uint256_t{ 15547843034426617484UL, 13465733818561903358UL, 11157089789589945854UL, 3107062195097242290UL }); + const auto poseidon2_params_C_10_1 = FF(0); + const auto poseidon2_params_C_10_2 = FF(0); + const auto poseidon2_params_C_10_3 = FF(0); + const auto poseidon2_params_C_11_0 = FF( + uint256_t{ 16908372174309343397UL, 17264932925429761530UL, 11508063480483774160UL, 2682419245684831641UL }); + const auto poseidon2_params_C_11_1 = FF(0); + const auto poseidon2_params_C_11_2 = FF(0); + const auto poseidon2_params_C_11_3 = FF(0); + const auto poseidon2_params_C_12_0 = + FF(uint256_t{ 4870692136216401181UL, 17645600130793395310UL, 2758876031472241166UL, 874943362207641089UL }); + const auto poseidon2_params_C_12_1 = FF(0); + const auto poseidon2_params_C_12_2 = FF(0); + const auto poseidon2_params_C_12_3 = FF(0); + const auto poseidon2_params_C_13_0 = FF( + uint256_t{ 4540479402638267003UL, 13477556963426049071UL, 6055112305493291757UL, 1810598527648098537UL }); + const auto poseidon2_params_C_13_1 = FF(0); + const auto poseidon2_params_C_13_2 = FF(0); + const auto poseidon2_params_C_13_3 = FF(0); + const auto poseidon2_params_C_14_0 = + FF(uint256_t{ 7894770769272900997UL, 9595210915998428021UL, 7642295683223718917UL, 2210716392790471408UL }); + const auto poseidon2_params_C_14_1 = FF(0); + const auto poseidon2_params_C_14_2 = FF(0); + const auto poseidon2_params_C_14_3 = FF(0); + const auto poseidon2_params_C_15_0 = FF( + uint256_t{ 10910178561156475899UL, 15811627963917441510UL, 16460518660187536520UL, 1698297851221778809UL }); + const auto poseidon2_params_C_15_1 = FF(0); + const auto poseidon2_params_C_15_2 = FF(0); + const auto poseidon2_params_C_15_3 = FF(0); + const auto poseidon2_params_C_16_0 = + FF(uint256_t{ 7831732902708890908UL, 1464390598836302271UL, 8568564606321342514UL, 3007171090439369509UL }); + const auto poseidon2_params_C_16_1 = FF(0); + const auto poseidon2_params_C_16_2 = FF(0); + const auto poseidon2_params_C_16_3 = FF(0); + const auto poseidon2_params_C_17_0 = FF( + uint256_t{ 12758232712903990792UL, 5937193763836963893UL, 4629415695575460109UL, 2476198378403296665UL }); + const auto poseidon2_params_C_17_1 = FF(0); + const auto poseidon2_params_C_17_2 = FF(0); + const auto poseidon2_params_C_17_3 = FF(0); + const auto poseidon2_params_C_18_0 = + FF(uint256_t{ 16185652584871361881UL, 3161867062328690813UL, 8447947510117581907UL, 452436262606194895UL }); + const auto poseidon2_params_C_18_1 = FF(0); + const auto poseidon2_params_C_18_2 = FF(0); + const auto poseidon2_params_C_18_3 = FF(0); + const auto poseidon2_params_C_19_0 = FF( + uint256_t{ 10531967515434376071UL, 5577695765815843856UL, 9164856352050088505UL, 1205339682110411496UL }); + const auto poseidon2_params_C_19_1 = FF(0); + const auto poseidon2_params_C_19_2 = FF(0); + const auto poseidon2_params_C_19_3 = FF(0); + const auto poseidon2_params_C_20_0 = FF( + uint256_t{ 3898841196333713180UL, 14650521577519770525UL, 5736581618852866049UL, 1010789789328495026UL }); + const auto poseidon2_params_C_20_1 = FF(0); + const auto poseidon2_params_C_20_2 = FF(0); + const auto poseidon2_params_C_20_3 = FF(0); + const auto poseidon2_params_C_21_0 = FF( + uint256_t{ 12103741763020280571UL, 14760208106156268938UL, 15246749619665902195UL, 1987439155030896717UL }); + const auto poseidon2_params_C_21_1 = FF(0); + const auto poseidon2_params_C_21_2 = FF(0); + const auto poseidon2_params_C_21_3 = FF(0); + const auto poseidon2_params_C_22_0 = FF( + uint256_t{ 326429241861474059UL, 11335157279655967493UL, 16233357323017397007UL, 2124770605461456708UL }); + const auto poseidon2_params_C_22_1 = FF(0); + const auto poseidon2_params_C_22_2 = FF(0); + const auto poseidon2_params_C_22_3 = FF(0); + const auto poseidon2_params_C_23_0 = FF( + uint256_t{ 13507610432344102875UL, 9765425316929074945UL, 10455054851855122687UL, 3371280263716451574UL }); + const auto poseidon2_params_C_23_1 = FF(0); + const auto poseidon2_params_C_23_2 = FF(0); + const auto poseidon2_params_C_23_3 = FF(0); + const auto poseidon2_params_C_24_0 = FF( + uint256_t{ 9433430149246843174UL, 16916651192445074064UL, 12002862125451454299UL, 3293088726774108791UL }); + const auto poseidon2_params_C_24_1 = FF(0); + const auto poseidon2_params_C_24_2 = FF(0); + const auto poseidon2_params_C_24_3 = FF(0); + const auto poseidon2_params_C_25_0 = FF( + uint256_t{ 15895963712096768440UL, 10975964170403460506UL, 7594578539046143282UL, 441635248990433378UL }); + const auto poseidon2_params_C_25_1 = FF(0); + const auto poseidon2_params_C_25_2 = FF(0); + const auto poseidon2_params_C_25_3 = FF(0); + const auto poseidon2_params_C_26_0 = + FF(uint256_t{ 55564641555031451UL, 2316046008873247993UL, 6273091099984972305UL, 531938487375579818UL }); + const auto poseidon2_params_C_26_1 = FF(0); + const auto poseidon2_params_C_26_2 = FF(0); + const auto poseidon2_params_C_26_3 = FF(0); + const auto poseidon2_params_C_27_0 = FF( + uint256_t{ 17845282940759944461UL, 6735239388814238924UL, 3181517889518583601UL, 2376846283559998361UL }); + const auto poseidon2_params_C_27_1 = FF(0); + const auto poseidon2_params_C_27_2 = FF(0); + const auto poseidon2_params_C_27_3 = FF(0); + const auto poseidon2_params_C_28_0 = FF( + uint256_t{ 14097127963645492314UL, 1165420652731038559UL, 12527303660854712762UL, 2717289076364278965UL }); + const auto poseidon2_params_C_28_1 = FF(0); + const auto poseidon2_params_C_28_2 = FF(0); + const auto poseidon2_params_C_28_3 = FF(0); + const auto poseidon2_params_C_29_0 = FF( + uint256_t{ 15600044695084040011UL, 255324662529267034UL, 11859356122961343981UL, 2571979992654075442UL }); + const auto poseidon2_params_C_29_1 = FF(0); + const auto poseidon2_params_C_29_2 = FF(0); + const auto poseidon2_params_C_29_3 = FF(0); + const auto poseidon2_params_C_30_0 = + FF(uint256_t{ 1589817027469470176UL, 1086723465680833706UL, 6948011514366564799UL, 2482410610948543635UL }); + const auto poseidon2_params_C_30_1 = FF(0); + const auto poseidon2_params_C_30_2 = FF(0); + const auto poseidon2_params_C_30_3 = FF(0); + const auto poseidon2_params_C_31_0 = FF( + uint256_t{ 6071201116374785253UL, 16554668458221199618UL, 16319484688832471879UL, 2792452762383364279UL }); + const auto poseidon2_params_C_31_1 = FF(0); + const auto poseidon2_params_C_31_2 = FF(0); + const auto poseidon2_params_C_31_3 = FF(0); + const auto poseidon2_params_C_32_0 = FF( + uint256_t{ 13535048470209809113UL, 1831807297936988201UL, 16757520396573457190UL, 508291910620511162UL }); + const auto poseidon2_params_C_32_1 = FF(0); + const auto poseidon2_params_C_32_2 = FF(0); + const auto poseidon2_params_C_32_3 = FF(0); + const auto poseidon2_params_C_33_0 = FF( + uint256_t{ 6946737468087619802UL, 14033399912488027565UL, 12701200401813783486UL, 1348363389498465135UL }); + const auto poseidon2_params_C_33_1 = FF(0); + const auto poseidon2_params_C_33_2 = FF(0); + const auto poseidon2_params_C_33_3 = FF(0); + const auto poseidon2_params_C_34_0 = FF( + uint256_t{ 6788008051328210729UL, 13866524545426155292UL, 4317879914214157329UL, 2633928310905799638UL }); + const auto poseidon2_params_C_34_1 = FF(0); + const auto poseidon2_params_C_34_2 = FF(0); + const auto poseidon2_params_C_34_3 = FF(0); + const auto poseidon2_params_C_35_0 = FF( + uint256_t{ 1183626302001490602UL, 10035686235057284266UL, 1656321729167440177UL, 1887128381037099784UL }); + const auto poseidon2_params_C_35_1 = FF(0); + const auto poseidon2_params_C_35_2 = FF(0); + const auto poseidon2_params_C_35_3 = FF(0); + const auto poseidon2_params_C_36_0 = FF( + uint256_t{ 964566190254741199UL, 17650087760652370459UL, 14904592615785317921UL, 2929864473487096026UL }); + const auto poseidon2_params_C_36_1 = FF(0); + const auto poseidon2_params_C_36_2 = FF(0); + const auto poseidon2_params_C_36_3 = FF(0); + const auto poseidon2_params_C_37_0 = + FF(uint256_t{ 13584300701347139198UL, 512534187550045064UL, 13489711551083721364UL, 41824696873363624UL }); + const auto poseidon2_params_C_37_1 = FF(0); + const auto poseidon2_params_C_37_2 = FF(0); + const auto poseidon2_params_C_37_3 = FF(0); + const auto poseidon2_params_C_38_0 = + FF(uint256_t{ 17586611824788147557UL, 6430987250922925699UL, 9294838151373947091UL, 348446557360066429UL }); + const auto poseidon2_params_C_38_1 = FF(0); + const auto poseidon2_params_C_38_2 = FF(0); + const auto poseidon2_params_C_38_3 = FF(0); + const auto poseidon2_params_C_39_0 = FF( + uint256_t{ 15025298913764434311UL, 14393211163878018166UL, 7154440178410267241UL, 3057088631006286899UL }); + const auto poseidon2_params_C_39_1 = FF(0); + const auto poseidon2_params_C_39_2 = FF(0); + const auto poseidon2_params_C_39_3 = FF(0); + const auto poseidon2_params_C_40_0 = FF( + uint256_t{ 13451769229280519155UL, 17839347496757587523UL, 10553299811918798519UL, 2523373819901075642UL }); + const auto poseidon2_params_C_40_1 = FF(0); + const auto poseidon2_params_C_40_2 = FF(0); + const auto poseidon2_params_C_40_3 = FF(0); + const auto poseidon2_params_C_41_0 = FF( + uint256_t{ 16267315463205810352UL, 13830706729545301172UL, 15413288900478726729UL, 287556136711008934UL }); + const auto poseidon2_params_C_41_1 = FF(0); + const auto poseidon2_params_C_41_2 = FF(0); + const auto poseidon2_params_C_41_3 = FF(0); + const auto poseidon2_params_C_42_0 = + FF(uint256_t{ 4573780169675443044UL, 8758089751960064775UL, 2470295096511057988UL, 51551212240288730UL }); + const auto poseidon2_params_C_42_1 = FF(0); + const auto poseidon2_params_C_42_2 = FF(0); + const auto poseidon2_params_C_42_3 = FF(0); + const auto poseidon2_params_C_43_0 = FF( + uint256_t{ 7093949836145798554UL, 12771428392262798771UL, 17021632567931004395UL, 1558106578814965657UL }); + const auto poseidon2_params_C_43_1 = FF(0); + const auto poseidon2_params_C_43_2 = FF(0); + const auto poseidon2_params_C_43_3 = FF(0); + const auto poseidon2_params_C_44_0 = FF( + uint256_t{ 8205915653008540447UL, 10376314495036230740UL, 5774593793305666491UL, 2231830927015656581UL }); + const auto poseidon2_params_C_44_1 = FF(0); + const auto poseidon2_params_C_44_2 = FF(0); + const auto poseidon2_params_C_44_3 = FF(0); + const auto poseidon2_params_C_45_0 = FF( + uint256_t{ 10783762484003267341UL, 10229708558604896492UL, 1831638669050696278UL, 2190429714552610800UL }); + const auto poseidon2_params_C_45_1 = FF(0); + const auto poseidon2_params_C_45_2 = FF(0); + const auto poseidon2_params_C_45_3 = FF(0); + const auto poseidon2_params_C_46_0 = FF( + uint256_t{ 7310961803978392383UL, 12793746113455595394UL, 17036245927795997300UL, 3106081169494120044UL }); + const auto poseidon2_params_C_46_1 = FF(0); + const auto poseidon2_params_C_46_2 = FF(0); + const auto poseidon2_params_C_46_3 = FF(0); + const auto poseidon2_params_C_47_0 = + FF(uint256_t{ 17421859032088162675UL, 7339791467855418851UL, 4622175020331968961UL, 590786792834928630UL }); + const auto poseidon2_params_C_47_1 = FF(0); + const auto poseidon2_params_C_47_2 = FF(0); + const auto poseidon2_params_C_47_3 = FF(0); + const auto poseidon2_params_C_48_0 = FF( + uint256_t{ 14242884250645212438UL, 12806057845811725595UL, 7743423753614082490UL, 213381026777379804UL }); + const auto poseidon2_params_C_48_1 = FF(0); + const auto poseidon2_params_C_48_2 = FF(0); + const auto poseidon2_params_C_48_3 = FF(0); + const auto poseidon2_params_C_49_0 = FF( + uint256_t{ 1110713325513004805UL, 8318407684973846516UL, 15952888485475298710UL, 1018983205230111328UL }); + const auto poseidon2_params_C_49_1 = FF(0); + const auto poseidon2_params_C_49_2 = FF(0); + const auto poseidon2_params_C_49_3 = FF(0); + const auto poseidon2_params_C_50_0 = + FF(uint256_t{ 533883137631233338UL, 333001117808183237UL, 16968583542443855481UL, 329716098711096173UL }); + const auto poseidon2_params_C_50_1 = FF(0); + const auto poseidon2_params_C_50_2 = FF(0); + const auto poseidon2_params_C_50_3 = FF(0); + const auto poseidon2_params_C_51_0 = + FF(uint256_t{ 4449676039486426793UL, 7760073051300251162UL, 5615103291054015906UL, 2516053143677338215UL }); + const auto poseidon2_params_C_51_1 = FF(0); + const auto poseidon2_params_C_51_2 = FF(0); + const auto poseidon2_params_C_51_3 = FF(0); + const auto poseidon2_params_C_52_0 = FF( + uint256_t{ 16503526645482286870UL, 6358830762575712333UL, 12313512559299087688UL, 2716767262544184013UL }); + const auto poseidon2_params_C_52_1 = FF(0); + const auto poseidon2_params_C_52_2 = FF(0); + const auto poseidon2_params_C_52_3 = FF(0); + const auto poseidon2_params_C_53_0 = FF( + uint256_t{ 5426798011730033104UL, 13085704829880126552UL, 6356732802364281819UL, 2175930396888807151UL }); + const auto poseidon2_params_C_53_1 = FF(0); + const auto poseidon2_params_C_53_2 = FF(0); + const auto poseidon2_params_C_53_3 = FF(0); + const auto poseidon2_params_C_54_0 = FF( + uint256_t{ 8262282602783970021UL, 2576069526442506486UL, 14199683559983367515UL, 3432491072538425468UL }); + const auto poseidon2_params_C_54_1 = FF(0); + const auto poseidon2_params_C_54_2 = FF(0); + const auto poseidon2_params_C_54_3 = FF(0); + const auto poseidon2_params_C_55_0 = FF( + uint256_t{ 14778817021916755205UL, 6110468871588391807UL, 2850248286812407967UL, 3411084787375678665UL }); + const auto poseidon2_params_C_55_1 = FF(0); + const auto poseidon2_params_C_55_2 = FF(0); + const auto poseidon2_params_C_55_3 = FF(0); + const auto poseidon2_params_C_56_0 = + FF(uint256_t{ 4906200604739023933UL, 12096549814065429793UL, 5988343102643160344UL, 309820751832846301UL }); + const auto poseidon2_params_C_56_1 = FF(0); + const auto poseidon2_params_C_56_2 = FF(0); + const auto poseidon2_params_C_56_3 = FF(0); + const auto poseidon2_params_C_57_0 = FF( + uint256_t{ 8709336210313678885UL, 10520000332606345601UL, 4756441214598660785UL, 2483744946546306397UL }); + const auto poseidon2_params_C_57_1 = FF(0); + const auto poseidon2_params_C_57_2 = FF(0); + const auto poseidon2_params_C_57_3 = FF(0); + const auto poseidon2_params_C_58_0 = + FF(uint256_t{ 9617950371599090517UL, 6702332727289490762UL, 7078214601245292934UL, 215269160536524476UL }); + const auto poseidon2_params_C_58_1 = FF(0); + const auto poseidon2_params_C_58_2 = FF(0); + const auto poseidon2_params_C_58_3 = FF(0); + const auto poseidon2_params_C_59_0 = FF( + uint256_t{ 14694170287735041964UL, 13462371741453101277UL, 7691247574208617782UL, 1078917709155142535UL }); + const auto poseidon2_params_C_59_1 = FF(0); + const auto poseidon2_params_C_59_2 = FF(0); + const auto poseidon2_params_C_59_3 = FF(0); + const auto poseidon2_params_C_60_0 = FF( + uint256_t{ 17559938410729200952UL, 12326273425107991305UL, 8641129484519639030UL, 1699848340767391255UL }); + const auto poseidon2_params_C_60_1 = + FF(uint256_t{ 3946956839294125797UL, 10123891284815211853UL, 3676846437799665248UL, 753827773683953838UL }); + const auto poseidon2_params_C_60_2 = FF( + uint256_t{ 10815195850656127580UL, 17940782720817522247UL, 11666428030894512886UL, 2305765957929457259UL }); + const auto poseidon2_params_C_60_3 = + FF(uint256_t{ 437280840171101279UL, 6885928680245806601UL, 6031863836827793624UL, 2698250255620259624UL }); + const auto poseidon2_params_C_61_0 = FF( + uint256_t{ 16961604592822056794UL, 12516844188945734293UL, 2404426354458718742UL, 901141949721836097UL }); + const auto poseidon2_params_C_61_1 = FF( + uint256_t{ 3152898413090790038UL, 16108523113696338432UL, 11492645026300260534UL, 1417477149741880787UL }); + const auto poseidon2_params_C_61_2 = FF( + uint256_t{ 10578217394647568846UL, 6637113826221079930UL, 1364449097464563400UL, 2379869735503406314UL }); + const auto poseidon2_params_C_61_3 = FF( + uint256_t{ 6332539588517624153UL, 17422837239624809585UL, 12296960536238467913UL, 2434905421004621494UL }); + const auto poseidon2_params_C_62_0 = + FF(uint256_t{ 10311634121439582299UL, 2959376558854333994UL, 6697398963915560134UL, 417944321386245900UL }); + const auto poseidon2_params_C_62_1 = FF( + uint256_t{ 16872849857899172004UL, 1640712307042701286UL, 16457516735210998920UL, 1084862449077757478UL }); + const auto poseidon2_params_C_62_2 = + FF(uint256_t{ 10329879351081882815UL, 5178010365334480003UL, 7014208314719145622UL, 385149140585498380UL }); + const auto poseidon2_params_C_62_3 = FF( + uint256_t{ 13199866221884806229UL, 10541991787372042848UL, 14909749656931548440UL, 708152185224876794UL }); + const auto poseidon2_params_C_63_0 = + FF(uint256_t{ 1717216310632203061UL, 17455832130858697862UL, 5278085098799702411UL, 227655898188482835UL }); + const auto poseidon2_params_C_63_1 = FF( + uint256_t{ 17164141620747686731UL, 16689913387728553544UL, 2568326884589391367UL, 3166155980659486882UL }); + const auto poseidon2_params_C_63_2 = FF( + uint256_t{ 1233442753680249567UL, 15490006495937952898UL, 7249042245074469654UL, 2138985910652398451UL }); + const auto poseidon2_params_C_63_3 = + FF(uint256_t{ 4115849303762846724UL, 2230284817967990783UL, 5095423606777193313UL, 1685862792723606183UL }); + const auto poseidon2_perm_EXT_LAYER_0 = new_term.poseidon2_perm_a_0 + new_term.poseidon2_perm_a_1; + const auto poseidon2_perm_EXT_LAYER_1 = new_term.poseidon2_perm_a_2 + new_term.poseidon2_perm_a_3; + const auto poseidon2_perm_EXT_LAYER_2 = FF(2) * new_term.poseidon2_perm_a_1 + poseidon2_perm_EXT_LAYER_1; + const auto poseidon2_perm_EXT_LAYER_3 = FF(2) * new_term.poseidon2_perm_a_3 + poseidon2_perm_EXT_LAYER_0; + const auto poseidon2_perm_ARK_0_0 = new_term.poseidon2_perm_EXT_LAYER_6 + poseidon2_params_C_0_0; + const auto poseidon2_perm_ARK_0_1 = new_term.poseidon2_perm_EXT_LAYER_5 + poseidon2_params_C_0_1; + const auto poseidon2_perm_ARK_0_2 = new_term.poseidon2_perm_EXT_LAYER_7 + poseidon2_params_C_0_2; + const auto poseidon2_perm_ARK_0_3 = new_term.poseidon2_perm_EXT_LAYER_4 + poseidon2_params_C_0_3; + const auto poseidon2_perm_A_0_0 = poseidon2_perm_ARK_0_0 * poseidon2_perm_ARK_0_0 * poseidon2_perm_ARK_0_0 * + poseidon2_perm_ARK_0_0 * poseidon2_perm_ARK_0_0; + const auto poseidon2_perm_A_0_1 = poseidon2_perm_ARK_0_1 * poseidon2_perm_ARK_0_1 * poseidon2_perm_ARK_0_1 * + poseidon2_perm_ARK_0_1 * poseidon2_perm_ARK_0_1; + const auto poseidon2_perm_A_0_2 = poseidon2_perm_ARK_0_2 * poseidon2_perm_ARK_0_2 * poseidon2_perm_ARK_0_2 * + poseidon2_perm_ARK_0_2 * poseidon2_perm_ARK_0_2; + const auto poseidon2_perm_A_0_3 = poseidon2_perm_ARK_0_3 * poseidon2_perm_ARK_0_3 * poseidon2_perm_ARK_0_3 * + poseidon2_perm_ARK_0_3 * poseidon2_perm_ARK_0_3; + const auto poseidon2_perm_T_0_0 = poseidon2_perm_A_0_0 + poseidon2_perm_A_0_1; + const auto poseidon2_perm_T_0_1 = poseidon2_perm_A_0_2 + poseidon2_perm_A_0_3; + const auto poseidon2_perm_T_0_2 = FF(2) * poseidon2_perm_A_0_1 + poseidon2_perm_T_0_1; + const auto poseidon2_perm_T_0_3 = FF(2) * poseidon2_perm_A_0_3 + poseidon2_perm_T_0_0; + const auto poseidon2_perm_ARK_1_0 = new_term.poseidon2_perm_T_0_6 + poseidon2_params_C_1_0; + const auto poseidon2_perm_ARK_1_1 = new_term.poseidon2_perm_T_0_5 + poseidon2_params_C_1_1; + const auto poseidon2_perm_ARK_1_2 = new_term.poseidon2_perm_T_0_7 + poseidon2_params_C_1_2; + const auto poseidon2_perm_ARK_1_3 = new_term.poseidon2_perm_T_0_4 + poseidon2_params_C_1_3; + const auto poseidon2_perm_A_1_0 = poseidon2_perm_ARK_1_0 * poseidon2_perm_ARK_1_0 * poseidon2_perm_ARK_1_0 * + poseidon2_perm_ARK_1_0 * poseidon2_perm_ARK_1_0; + const auto poseidon2_perm_A_1_1 = poseidon2_perm_ARK_1_1 * poseidon2_perm_ARK_1_1 * poseidon2_perm_ARK_1_1 * + poseidon2_perm_ARK_1_1 * poseidon2_perm_ARK_1_1; + const auto poseidon2_perm_A_1_2 = poseidon2_perm_ARK_1_2 * poseidon2_perm_ARK_1_2 * poseidon2_perm_ARK_1_2 * + poseidon2_perm_ARK_1_2 * poseidon2_perm_ARK_1_2; + const auto poseidon2_perm_A_1_3 = poseidon2_perm_ARK_1_3 * poseidon2_perm_ARK_1_3 * poseidon2_perm_ARK_1_3 * + poseidon2_perm_ARK_1_3 * poseidon2_perm_ARK_1_3; + const auto poseidon2_perm_T_1_0 = poseidon2_perm_A_1_0 + poseidon2_perm_A_1_1; + const auto poseidon2_perm_T_1_1 = poseidon2_perm_A_1_2 + poseidon2_perm_A_1_3; + const auto poseidon2_perm_T_1_2 = FF(2) * poseidon2_perm_A_1_1 + poseidon2_perm_T_1_1; + const auto poseidon2_perm_T_1_3 = FF(2) * poseidon2_perm_A_1_3 + poseidon2_perm_T_1_0; + const auto poseidon2_perm_ARK_2_0 = new_term.poseidon2_perm_T_1_6 + poseidon2_params_C_2_0; + const auto poseidon2_perm_ARK_2_1 = new_term.poseidon2_perm_T_1_5 + poseidon2_params_C_2_1; + const auto poseidon2_perm_ARK_2_2 = new_term.poseidon2_perm_T_1_7 + poseidon2_params_C_2_2; + const auto poseidon2_perm_ARK_2_3 = new_term.poseidon2_perm_T_1_4 + poseidon2_params_C_2_3; + const auto poseidon2_perm_A_2_0 = poseidon2_perm_ARK_2_0 * poseidon2_perm_ARK_2_0 * poseidon2_perm_ARK_2_0 * + poseidon2_perm_ARK_2_0 * poseidon2_perm_ARK_2_0; + const auto poseidon2_perm_A_2_1 = poseidon2_perm_ARK_2_1 * poseidon2_perm_ARK_2_1 * poseidon2_perm_ARK_2_1 * + poseidon2_perm_ARK_2_1 * poseidon2_perm_ARK_2_1; + const auto poseidon2_perm_A_2_2 = poseidon2_perm_ARK_2_2 * poseidon2_perm_ARK_2_2 * poseidon2_perm_ARK_2_2 * + poseidon2_perm_ARK_2_2 * poseidon2_perm_ARK_2_2; + const auto poseidon2_perm_A_2_3 = poseidon2_perm_ARK_2_3 * poseidon2_perm_ARK_2_3 * poseidon2_perm_ARK_2_3 * + poseidon2_perm_ARK_2_3 * poseidon2_perm_ARK_2_3; + const auto poseidon2_perm_T_2_0 = poseidon2_perm_A_2_0 + poseidon2_perm_A_2_1; + const auto poseidon2_perm_T_2_1 = poseidon2_perm_A_2_2 + poseidon2_perm_A_2_3; + const auto poseidon2_perm_T_2_2 = FF(2) * poseidon2_perm_A_2_1 + poseidon2_perm_T_2_1; + const auto poseidon2_perm_T_2_3 = FF(2) * poseidon2_perm_A_2_3 + poseidon2_perm_T_2_0; + const auto poseidon2_perm_ARK_3_0 = new_term.poseidon2_perm_T_2_6 + poseidon2_params_C_3_0; + const auto poseidon2_perm_ARK_3_1 = new_term.poseidon2_perm_T_2_5 + poseidon2_params_C_3_1; + const auto poseidon2_perm_ARK_3_2 = new_term.poseidon2_perm_T_2_7 + poseidon2_params_C_3_2; + const auto poseidon2_perm_ARK_3_3 = new_term.poseidon2_perm_T_2_4 + poseidon2_params_C_3_3; + const auto poseidon2_perm_A_3_0 = poseidon2_perm_ARK_3_0 * poseidon2_perm_ARK_3_0 * poseidon2_perm_ARK_3_0 * + poseidon2_perm_ARK_3_0 * poseidon2_perm_ARK_3_0; + const auto poseidon2_perm_A_3_1 = poseidon2_perm_ARK_3_1 * poseidon2_perm_ARK_3_1 * poseidon2_perm_ARK_3_1 * + poseidon2_perm_ARK_3_1 * poseidon2_perm_ARK_3_1; + const auto poseidon2_perm_A_3_2 = poseidon2_perm_ARK_3_2 * poseidon2_perm_ARK_3_2 * poseidon2_perm_ARK_3_2 * + poseidon2_perm_ARK_3_2 * poseidon2_perm_ARK_3_2; + const auto poseidon2_perm_A_3_3 = poseidon2_perm_ARK_3_3 * poseidon2_perm_ARK_3_3 * poseidon2_perm_ARK_3_3 * + poseidon2_perm_ARK_3_3 * poseidon2_perm_ARK_3_3; + const auto poseidon2_perm_T_3_0 = poseidon2_perm_A_3_0 + poseidon2_perm_A_3_1; + const auto poseidon2_perm_T_3_1 = poseidon2_perm_A_3_2 + poseidon2_perm_A_3_3; + const auto poseidon2_perm_T_3_2 = FF(2) * poseidon2_perm_A_3_1 + poseidon2_perm_T_3_1; + const auto poseidon2_perm_T_3_3 = FF(2) * poseidon2_perm_A_3_3 + poseidon2_perm_T_3_0; + const auto poseidon2_perm_ARK_4_0 = new_term.poseidon2_perm_T_3_6 + poseidon2_params_C_4_0; + const auto poseidon2_perm_ARK_4_1 = new_term.poseidon2_perm_T_3_5 + poseidon2_params_C_4_1; + const auto poseidon2_perm_ARK_4_2 = new_term.poseidon2_perm_T_3_7 + poseidon2_params_C_4_2; + const auto poseidon2_perm_ARK_4_3 = new_term.poseidon2_perm_T_3_4 + poseidon2_params_C_4_3; + const auto poseidon2_perm_A_4_0 = poseidon2_perm_ARK_4_0 * poseidon2_perm_ARK_4_0 * poseidon2_perm_ARK_4_0 * + poseidon2_perm_ARK_4_0 * poseidon2_perm_ARK_4_0; + const auto poseidon2_perm_A_4_1 = poseidon2_perm_ARK_4_1; + const auto poseidon2_perm_A_4_2 = poseidon2_perm_ARK_4_2; + const auto poseidon2_perm_A_4_3 = poseidon2_perm_ARK_4_3; + const auto poseidon2_perm_SUM_4 = + poseidon2_perm_A_4_0 + poseidon2_perm_A_4_1 + poseidon2_perm_A_4_2 + poseidon2_perm_A_4_3; + const auto poseidon2_perm_ARK_5_0 = new_term.poseidon2_perm_B_4_0 + poseidon2_params_C_5_0; + const auto poseidon2_perm_ARK_5_1 = new_term.poseidon2_perm_B_4_1 + poseidon2_params_C_5_1; + const auto poseidon2_perm_ARK_5_2 = new_term.poseidon2_perm_B_4_2 + poseidon2_params_C_5_2; + const auto poseidon2_perm_ARK_5_3 = new_term.poseidon2_perm_B_4_3 + poseidon2_params_C_5_3; + const auto poseidon2_perm_A_5_0 = poseidon2_perm_ARK_5_0 * poseidon2_perm_ARK_5_0 * poseidon2_perm_ARK_5_0 * + poseidon2_perm_ARK_5_0 * poseidon2_perm_ARK_5_0; + const auto poseidon2_perm_A_5_1 = poseidon2_perm_ARK_5_1; + const auto poseidon2_perm_A_5_2 = poseidon2_perm_ARK_5_2; + const auto poseidon2_perm_A_5_3 = poseidon2_perm_ARK_5_3; + const auto poseidon2_perm_SUM_5 = + poseidon2_perm_A_5_0 + poseidon2_perm_A_5_1 + poseidon2_perm_A_5_2 + poseidon2_perm_A_5_3; + const auto poseidon2_perm_ARK_6_0 = new_term.poseidon2_perm_B_5_0 + poseidon2_params_C_6_0; + const auto poseidon2_perm_ARK_6_1 = new_term.poseidon2_perm_B_5_1 + poseidon2_params_C_6_1; + const auto poseidon2_perm_ARK_6_2 = new_term.poseidon2_perm_B_5_2 + poseidon2_params_C_6_2; + const auto poseidon2_perm_ARK_6_3 = new_term.poseidon2_perm_B_5_3 + poseidon2_params_C_6_3; + const auto poseidon2_perm_A_6_0 = poseidon2_perm_ARK_6_0 * poseidon2_perm_ARK_6_0 * poseidon2_perm_ARK_6_0 * + poseidon2_perm_ARK_6_0 * poseidon2_perm_ARK_6_0; + const auto poseidon2_perm_A_6_1 = poseidon2_perm_ARK_6_1; + const auto poseidon2_perm_A_6_2 = poseidon2_perm_ARK_6_2; + const auto poseidon2_perm_A_6_3 = poseidon2_perm_ARK_6_3; + const auto poseidon2_perm_SUM_6 = + poseidon2_perm_A_6_0 + poseidon2_perm_A_6_1 + poseidon2_perm_A_6_2 + poseidon2_perm_A_6_3; + const auto poseidon2_perm_ARK_7_0 = new_term.poseidon2_perm_B_6_0 + poseidon2_params_C_7_0; + const auto poseidon2_perm_ARK_7_1 = new_term.poseidon2_perm_B_6_1 + poseidon2_params_C_7_1; + const auto poseidon2_perm_ARK_7_2 = new_term.poseidon2_perm_B_6_2 + poseidon2_params_C_7_2; + const auto poseidon2_perm_ARK_7_3 = new_term.poseidon2_perm_B_6_3 + poseidon2_params_C_7_3; + const auto poseidon2_perm_A_7_0 = poseidon2_perm_ARK_7_0 * poseidon2_perm_ARK_7_0 * poseidon2_perm_ARK_7_0 * + poseidon2_perm_ARK_7_0 * poseidon2_perm_ARK_7_0; + const auto poseidon2_perm_A_7_1 = poseidon2_perm_ARK_7_1; + const auto poseidon2_perm_A_7_2 = poseidon2_perm_ARK_7_2; + const auto poseidon2_perm_A_7_3 = poseidon2_perm_ARK_7_3; + const auto poseidon2_perm_SUM_7 = + poseidon2_perm_A_7_0 + poseidon2_perm_A_7_1 + poseidon2_perm_A_7_2 + poseidon2_perm_A_7_3; + const auto poseidon2_perm_ARK_8_0 = new_term.poseidon2_perm_B_7_0 + poseidon2_params_C_8_0; + const auto poseidon2_perm_ARK_8_1 = new_term.poseidon2_perm_B_7_1 + poseidon2_params_C_8_1; + const auto poseidon2_perm_ARK_8_2 = new_term.poseidon2_perm_B_7_2 + poseidon2_params_C_8_2; + const auto poseidon2_perm_ARK_8_3 = new_term.poseidon2_perm_B_7_3 + poseidon2_params_C_8_3; + const auto poseidon2_perm_A_8_0 = poseidon2_perm_ARK_8_0 * poseidon2_perm_ARK_8_0 * poseidon2_perm_ARK_8_0 * + poseidon2_perm_ARK_8_0 * poseidon2_perm_ARK_8_0; + const auto poseidon2_perm_A_8_1 = poseidon2_perm_ARK_8_1; + const auto poseidon2_perm_A_8_2 = poseidon2_perm_ARK_8_2; + const auto poseidon2_perm_A_8_3 = poseidon2_perm_ARK_8_3; + const auto poseidon2_perm_SUM_8 = + poseidon2_perm_A_8_0 + poseidon2_perm_A_8_1 + poseidon2_perm_A_8_2 + poseidon2_perm_A_8_3; + const auto poseidon2_perm_ARK_9_0 = new_term.poseidon2_perm_B_8_0 + poseidon2_params_C_9_0; + const auto poseidon2_perm_ARK_9_1 = new_term.poseidon2_perm_B_8_1 + poseidon2_params_C_9_1; + const auto poseidon2_perm_ARK_9_2 = new_term.poseidon2_perm_B_8_2 + poseidon2_params_C_9_2; + const auto poseidon2_perm_ARK_9_3 = new_term.poseidon2_perm_B_8_3 + poseidon2_params_C_9_3; + const auto poseidon2_perm_A_9_0 = poseidon2_perm_ARK_9_0 * poseidon2_perm_ARK_9_0 * poseidon2_perm_ARK_9_0 * + poseidon2_perm_ARK_9_0 * poseidon2_perm_ARK_9_0; + const auto poseidon2_perm_A_9_1 = poseidon2_perm_ARK_9_1; + const auto poseidon2_perm_A_9_2 = poseidon2_perm_ARK_9_2; + const auto poseidon2_perm_A_9_3 = poseidon2_perm_ARK_9_3; + const auto poseidon2_perm_SUM_9 = + poseidon2_perm_A_9_0 + poseidon2_perm_A_9_1 + poseidon2_perm_A_9_2 + poseidon2_perm_A_9_3; + const auto poseidon2_perm_ARK_10_0 = new_term.poseidon2_perm_B_9_0 + poseidon2_params_C_10_0; + const auto poseidon2_perm_ARK_10_1 = new_term.poseidon2_perm_B_9_1 + poseidon2_params_C_10_1; + const auto poseidon2_perm_ARK_10_2 = new_term.poseidon2_perm_B_9_2 + poseidon2_params_C_10_2; + const auto poseidon2_perm_ARK_10_3 = new_term.poseidon2_perm_B_9_3 + poseidon2_params_C_10_3; + const auto poseidon2_perm_A_10_0 = poseidon2_perm_ARK_10_0 * poseidon2_perm_ARK_10_0 * poseidon2_perm_ARK_10_0 * + poseidon2_perm_ARK_10_0 * poseidon2_perm_ARK_10_0; + const auto poseidon2_perm_A_10_1 = poseidon2_perm_ARK_10_1; + const auto poseidon2_perm_A_10_2 = poseidon2_perm_ARK_10_2; + const auto poseidon2_perm_A_10_3 = poseidon2_perm_ARK_10_3; + const auto poseidon2_perm_SUM_10 = + poseidon2_perm_A_10_0 + poseidon2_perm_A_10_1 + poseidon2_perm_A_10_2 + poseidon2_perm_A_10_3; + const auto poseidon2_perm_ARK_11_0 = new_term.poseidon2_perm_B_10_0 + poseidon2_params_C_11_0; + const auto poseidon2_perm_ARK_11_1 = new_term.poseidon2_perm_B_10_1 + poseidon2_params_C_11_1; + const auto poseidon2_perm_ARK_11_2 = new_term.poseidon2_perm_B_10_2 + poseidon2_params_C_11_2; + const auto poseidon2_perm_ARK_11_3 = new_term.poseidon2_perm_B_10_3 + poseidon2_params_C_11_3; + const auto poseidon2_perm_A_11_0 = poseidon2_perm_ARK_11_0 * poseidon2_perm_ARK_11_0 * poseidon2_perm_ARK_11_0 * + poseidon2_perm_ARK_11_0 * poseidon2_perm_ARK_11_0; + const auto poseidon2_perm_A_11_1 = poseidon2_perm_ARK_11_1; + const auto poseidon2_perm_A_11_2 = poseidon2_perm_ARK_11_2; + const auto poseidon2_perm_A_11_3 = poseidon2_perm_ARK_11_3; + const auto poseidon2_perm_SUM_11 = + poseidon2_perm_A_11_0 + poseidon2_perm_A_11_1 + poseidon2_perm_A_11_2 + poseidon2_perm_A_11_3; + const auto poseidon2_perm_ARK_12_0 = new_term.poseidon2_perm_B_11_0 + poseidon2_params_C_12_0; + const auto poseidon2_perm_ARK_12_1 = new_term.poseidon2_perm_B_11_1 + poseidon2_params_C_12_1; + const auto poseidon2_perm_ARK_12_2 = new_term.poseidon2_perm_B_11_2 + poseidon2_params_C_12_2; + const auto poseidon2_perm_ARK_12_3 = new_term.poseidon2_perm_B_11_3 + poseidon2_params_C_12_3; + const auto poseidon2_perm_A_12_0 = poseidon2_perm_ARK_12_0 * poseidon2_perm_ARK_12_0 * poseidon2_perm_ARK_12_0 * + poseidon2_perm_ARK_12_0 * poseidon2_perm_ARK_12_0; + const auto poseidon2_perm_A_12_1 = poseidon2_perm_ARK_12_1; + const auto poseidon2_perm_A_12_2 = poseidon2_perm_ARK_12_2; + const auto poseidon2_perm_A_12_3 = poseidon2_perm_ARK_12_3; + const auto poseidon2_perm_SUM_12 = + poseidon2_perm_A_12_0 + poseidon2_perm_A_12_1 + poseidon2_perm_A_12_2 + poseidon2_perm_A_12_3; + const auto poseidon2_perm_ARK_13_0 = new_term.poseidon2_perm_B_12_0 + poseidon2_params_C_13_0; + const auto poseidon2_perm_ARK_13_1 = new_term.poseidon2_perm_B_12_1 + poseidon2_params_C_13_1; + const auto poseidon2_perm_ARK_13_2 = new_term.poseidon2_perm_B_12_2 + poseidon2_params_C_13_2; + const auto poseidon2_perm_ARK_13_3 = new_term.poseidon2_perm_B_12_3 + poseidon2_params_C_13_3; + const auto poseidon2_perm_A_13_0 = poseidon2_perm_ARK_13_0 * poseidon2_perm_ARK_13_0 * poseidon2_perm_ARK_13_0 * + poseidon2_perm_ARK_13_0 * poseidon2_perm_ARK_13_0; + const auto poseidon2_perm_A_13_1 = poseidon2_perm_ARK_13_1; + const auto poseidon2_perm_A_13_2 = poseidon2_perm_ARK_13_2; + const auto poseidon2_perm_A_13_3 = poseidon2_perm_ARK_13_3; + const auto poseidon2_perm_SUM_13 = + poseidon2_perm_A_13_0 + poseidon2_perm_A_13_1 + poseidon2_perm_A_13_2 + poseidon2_perm_A_13_3; + const auto poseidon2_perm_ARK_14_0 = new_term.poseidon2_perm_B_13_0 + poseidon2_params_C_14_0; + const auto poseidon2_perm_ARK_14_1 = new_term.poseidon2_perm_B_13_1 + poseidon2_params_C_14_1; + const auto poseidon2_perm_ARK_14_2 = new_term.poseidon2_perm_B_13_2 + poseidon2_params_C_14_2; + const auto poseidon2_perm_ARK_14_3 = new_term.poseidon2_perm_B_13_3 + poseidon2_params_C_14_3; + const auto poseidon2_perm_A_14_0 = poseidon2_perm_ARK_14_0 * poseidon2_perm_ARK_14_0 * poseidon2_perm_ARK_14_0 * + poseidon2_perm_ARK_14_0 * poseidon2_perm_ARK_14_0; + const auto poseidon2_perm_A_14_1 = poseidon2_perm_ARK_14_1; + const auto poseidon2_perm_A_14_2 = poseidon2_perm_ARK_14_2; + const auto poseidon2_perm_A_14_3 = poseidon2_perm_ARK_14_3; + const auto poseidon2_perm_SUM_14 = + poseidon2_perm_A_14_0 + poseidon2_perm_A_14_1 + poseidon2_perm_A_14_2 + poseidon2_perm_A_14_3; + const auto poseidon2_perm_ARK_15_0 = new_term.poseidon2_perm_B_14_0 + poseidon2_params_C_15_0; + const auto poseidon2_perm_ARK_15_1 = new_term.poseidon2_perm_B_14_1 + poseidon2_params_C_15_1; + const auto poseidon2_perm_ARK_15_2 = new_term.poseidon2_perm_B_14_2 + poseidon2_params_C_15_2; + const auto poseidon2_perm_ARK_15_3 = new_term.poseidon2_perm_B_14_3 + poseidon2_params_C_15_3; + const auto poseidon2_perm_A_15_0 = poseidon2_perm_ARK_15_0 * poseidon2_perm_ARK_15_0 * poseidon2_perm_ARK_15_0 * + poseidon2_perm_ARK_15_0 * poseidon2_perm_ARK_15_0; + const auto poseidon2_perm_A_15_1 = poseidon2_perm_ARK_15_1; + const auto poseidon2_perm_A_15_2 = poseidon2_perm_ARK_15_2; + const auto poseidon2_perm_A_15_3 = poseidon2_perm_ARK_15_3; + const auto poseidon2_perm_SUM_15 = + poseidon2_perm_A_15_0 + poseidon2_perm_A_15_1 + poseidon2_perm_A_15_2 + poseidon2_perm_A_15_3; + const auto poseidon2_perm_ARK_16_0 = new_term.poseidon2_perm_B_15_0 + poseidon2_params_C_16_0; + const auto poseidon2_perm_ARK_16_1 = new_term.poseidon2_perm_B_15_1 + poseidon2_params_C_16_1; + const auto poseidon2_perm_ARK_16_2 = new_term.poseidon2_perm_B_15_2 + poseidon2_params_C_16_2; + const auto poseidon2_perm_ARK_16_3 = new_term.poseidon2_perm_B_15_3 + poseidon2_params_C_16_3; + const auto poseidon2_perm_A_16_0 = poseidon2_perm_ARK_16_0 * poseidon2_perm_ARK_16_0 * poseidon2_perm_ARK_16_0 * + poseidon2_perm_ARK_16_0 * poseidon2_perm_ARK_16_0; + const auto poseidon2_perm_A_16_1 = poseidon2_perm_ARK_16_1; + const auto poseidon2_perm_A_16_2 = poseidon2_perm_ARK_16_2; + const auto poseidon2_perm_A_16_3 = poseidon2_perm_ARK_16_3; + const auto poseidon2_perm_SUM_16 = + poseidon2_perm_A_16_0 + poseidon2_perm_A_16_1 + poseidon2_perm_A_16_2 + poseidon2_perm_A_16_3; + const auto poseidon2_perm_ARK_17_0 = new_term.poseidon2_perm_B_16_0 + poseidon2_params_C_17_0; + const auto poseidon2_perm_ARK_17_1 = new_term.poseidon2_perm_B_16_1 + poseidon2_params_C_17_1; + const auto poseidon2_perm_ARK_17_2 = new_term.poseidon2_perm_B_16_2 + poseidon2_params_C_17_2; + const auto poseidon2_perm_ARK_17_3 = new_term.poseidon2_perm_B_16_3 + poseidon2_params_C_17_3; + const auto poseidon2_perm_A_17_0 = poseidon2_perm_ARK_17_0 * poseidon2_perm_ARK_17_0 * poseidon2_perm_ARK_17_0 * + poseidon2_perm_ARK_17_0 * poseidon2_perm_ARK_17_0; + const auto poseidon2_perm_A_17_1 = poseidon2_perm_ARK_17_1; + const auto poseidon2_perm_A_17_2 = poseidon2_perm_ARK_17_2; + const auto poseidon2_perm_A_17_3 = poseidon2_perm_ARK_17_3; + const auto poseidon2_perm_SUM_17 = + poseidon2_perm_A_17_0 + poseidon2_perm_A_17_1 + poseidon2_perm_A_17_2 + poseidon2_perm_A_17_3; + const auto poseidon2_perm_ARK_18_0 = new_term.poseidon2_perm_B_17_0 + poseidon2_params_C_18_0; + const auto poseidon2_perm_ARK_18_1 = new_term.poseidon2_perm_B_17_1 + poseidon2_params_C_18_1; + const auto poseidon2_perm_ARK_18_2 = new_term.poseidon2_perm_B_17_2 + poseidon2_params_C_18_2; + const auto poseidon2_perm_ARK_18_3 = new_term.poseidon2_perm_B_17_3 + poseidon2_params_C_18_3; + const auto poseidon2_perm_A_18_0 = poseidon2_perm_ARK_18_0 * poseidon2_perm_ARK_18_0 * poseidon2_perm_ARK_18_0 * + poseidon2_perm_ARK_18_0 * poseidon2_perm_ARK_18_0; + const auto poseidon2_perm_A_18_1 = poseidon2_perm_ARK_18_1; + const auto poseidon2_perm_A_18_2 = poseidon2_perm_ARK_18_2; + const auto poseidon2_perm_A_18_3 = poseidon2_perm_ARK_18_3; + const auto poseidon2_perm_SUM_18 = + poseidon2_perm_A_18_0 + poseidon2_perm_A_18_1 + poseidon2_perm_A_18_2 + poseidon2_perm_A_18_3; + const auto poseidon2_perm_ARK_19_0 = new_term.poseidon2_perm_B_18_0 + poseidon2_params_C_19_0; + const auto poseidon2_perm_ARK_19_1 = new_term.poseidon2_perm_B_18_1 + poseidon2_params_C_19_1; + const auto poseidon2_perm_ARK_19_2 = new_term.poseidon2_perm_B_18_2 + poseidon2_params_C_19_2; + const auto poseidon2_perm_ARK_19_3 = new_term.poseidon2_perm_B_18_3 + poseidon2_params_C_19_3; + const auto poseidon2_perm_A_19_0 = poseidon2_perm_ARK_19_0 * poseidon2_perm_ARK_19_0 * poseidon2_perm_ARK_19_0 * + poseidon2_perm_ARK_19_0 * poseidon2_perm_ARK_19_0; + const auto poseidon2_perm_A_19_1 = poseidon2_perm_ARK_19_1; + const auto poseidon2_perm_A_19_2 = poseidon2_perm_ARK_19_2; + const auto poseidon2_perm_A_19_3 = poseidon2_perm_ARK_19_3; + const auto poseidon2_perm_SUM_19 = + poseidon2_perm_A_19_0 + poseidon2_perm_A_19_1 + poseidon2_perm_A_19_2 + poseidon2_perm_A_19_3; + const auto poseidon2_perm_ARK_20_0 = new_term.poseidon2_perm_B_19_0 + poseidon2_params_C_20_0; + const auto poseidon2_perm_ARK_20_1 = new_term.poseidon2_perm_B_19_1 + poseidon2_params_C_20_1; + const auto poseidon2_perm_ARK_20_2 = new_term.poseidon2_perm_B_19_2 + poseidon2_params_C_20_2; + const auto poseidon2_perm_ARK_20_3 = new_term.poseidon2_perm_B_19_3 + poseidon2_params_C_20_3; + const auto poseidon2_perm_A_20_0 = poseidon2_perm_ARK_20_0 * poseidon2_perm_ARK_20_0 * poseidon2_perm_ARK_20_0 * + poseidon2_perm_ARK_20_0 * poseidon2_perm_ARK_20_0; + const auto poseidon2_perm_A_20_1 = poseidon2_perm_ARK_20_1; + const auto poseidon2_perm_A_20_2 = poseidon2_perm_ARK_20_2; + const auto poseidon2_perm_A_20_3 = poseidon2_perm_ARK_20_3; + const auto poseidon2_perm_SUM_20 = + poseidon2_perm_A_20_0 + poseidon2_perm_A_20_1 + poseidon2_perm_A_20_2 + poseidon2_perm_A_20_3; + const auto poseidon2_perm_ARK_21_0 = new_term.poseidon2_perm_B_20_0 + poseidon2_params_C_21_0; + const auto poseidon2_perm_ARK_21_1 = new_term.poseidon2_perm_B_20_1 + poseidon2_params_C_21_1; + const auto poseidon2_perm_ARK_21_2 = new_term.poseidon2_perm_B_20_2 + poseidon2_params_C_21_2; + const auto poseidon2_perm_ARK_21_3 = new_term.poseidon2_perm_B_20_3 + poseidon2_params_C_21_3; + const auto poseidon2_perm_A_21_0 = poseidon2_perm_ARK_21_0 * poseidon2_perm_ARK_21_0 * poseidon2_perm_ARK_21_0 * + poseidon2_perm_ARK_21_0 * poseidon2_perm_ARK_21_0; + const auto poseidon2_perm_A_21_1 = poseidon2_perm_ARK_21_1; + const auto poseidon2_perm_A_21_2 = poseidon2_perm_ARK_21_2; + const auto poseidon2_perm_A_21_3 = poseidon2_perm_ARK_21_3; + const auto poseidon2_perm_SUM_21 = + poseidon2_perm_A_21_0 + poseidon2_perm_A_21_1 + poseidon2_perm_A_21_2 + poseidon2_perm_A_21_3; + const auto poseidon2_perm_ARK_22_0 = new_term.poseidon2_perm_B_21_0 + poseidon2_params_C_22_0; + const auto poseidon2_perm_ARK_22_1 = new_term.poseidon2_perm_B_21_1 + poseidon2_params_C_22_1; + const auto poseidon2_perm_ARK_22_2 = new_term.poseidon2_perm_B_21_2 + poseidon2_params_C_22_2; + const auto poseidon2_perm_ARK_22_3 = new_term.poseidon2_perm_B_21_3 + poseidon2_params_C_22_3; + const auto poseidon2_perm_A_22_0 = poseidon2_perm_ARK_22_0 * poseidon2_perm_ARK_22_0 * poseidon2_perm_ARK_22_0 * + poseidon2_perm_ARK_22_0 * poseidon2_perm_ARK_22_0; + const auto poseidon2_perm_A_22_1 = poseidon2_perm_ARK_22_1; + const auto poseidon2_perm_A_22_2 = poseidon2_perm_ARK_22_2; + const auto poseidon2_perm_A_22_3 = poseidon2_perm_ARK_22_3; + const auto poseidon2_perm_SUM_22 = + poseidon2_perm_A_22_0 + poseidon2_perm_A_22_1 + poseidon2_perm_A_22_2 + poseidon2_perm_A_22_3; + const auto poseidon2_perm_ARK_23_0 = new_term.poseidon2_perm_B_22_0 + poseidon2_params_C_23_0; + const auto poseidon2_perm_ARK_23_1 = new_term.poseidon2_perm_B_22_1 + poseidon2_params_C_23_1; + const auto poseidon2_perm_ARK_23_2 = new_term.poseidon2_perm_B_22_2 + poseidon2_params_C_23_2; + const auto poseidon2_perm_ARK_23_3 = new_term.poseidon2_perm_B_22_3 + poseidon2_params_C_23_3; + const auto poseidon2_perm_A_23_0 = poseidon2_perm_ARK_23_0 * poseidon2_perm_ARK_23_0 * poseidon2_perm_ARK_23_0 * + poseidon2_perm_ARK_23_0 * poseidon2_perm_ARK_23_0; + const auto poseidon2_perm_A_23_1 = poseidon2_perm_ARK_23_1; + const auto poseidon2_perm_A_23_2 = poseidon2_perm_ARK_23_2; + const auto poseidon2_perm_A_23_3 = poseidon2_perm_ARK_23_3; + const auto poseidon2_perm_SUM_23 = + poseidon2_perm_A_23_0 + poseidon2_perm_A_23_1 + poseidon2_perm_A_23_2 + poseidon2_perm_A_23_3; + const auto poseidon2_perm_ARK_24_0 = new_term.poseidon2_perm_B_23_0 + poseidon2_params_C_24_0; + const auto poseidon2_perm_ARK_24_1 = new_term.poseidon2_perm_B_23_1 + poseidon2_params_C_24_1; + const auto poseidon2_perm_ARK_24_2 = new_term.poseidon2_perm_B_23_2 + poseidon2_params_C_24_2; + const auto poseidon2_perm_ARK_24_3 = new_term.poseidon2_perm_B_23_3 + poseidon2_params_C_24_3; + const auto poseidon2_perm_A_24_0 = poseidon2_perm_ARK_24_0 * poseidon2_perm_ARK_24_0 * poseidon2_perm_ARK_24_0 * + poseidon2_perm_ARK_24_0 * poseidon2_perm_ARK_24_0; + const auto poseidon2_perm_A_24_1 = poseidon2_perm_ARK_24_1; + const auto poseidon2_perm_A_24_2 = poseidon2_perm_ARK_24_2; + const auto poseidon2_perm_A_24_3 = poseidon2_perm_ARK_24_3; + const auto poseidon2_perm_SUM_24 = + poseidon2_perm_A_24_0 + poseidon2_perm_A_24_1 + poseidon2_perm_A_24_2 + poseidon2_perm_A_24_3; + const auto poseidon2_perm_ARK_25_0 = new_term.poseidon2_perm_B_24_0 + poseidon2_params_C_25_0; + const auto poseidon2_perm_ARK_25_1 = new_term.poseidon2_perm_B_24_1 + poseidon2_params_C_25_1; + const auto poseidon2_perm_ARK_25_2 = new_term.poseidon2_perm_B_24_2 + poseidon2_params_C_25_2; + const auto poseidon2_perm_ARK_25_3 = new_term.poseidon2_perm_B_24_3 + poseidon2_params_C_25_3; + const auto poseidon2_perm_A_25_0 = poseidon2_perm_ARK_25_0 * poseidon2_perm_ARK_25_0 * poseidon2_perm_ARK_25_0 * + poseidon2_perm_ARK_25_0 * poseidon2_perm_ARK_25_0; + const auto poseidon2_perm_A_25_1 = poseidon2_perm_ARK_25_1; + const auto poseidon2_perm_A_25_2 = poseidon2_perm_ARK_25_2; + const auto poseidon2_perm_A_25_3 = poseidon2_perm_ARK_25_3; + const auto poseidon2_perm_SUM_25 = + poseidon2_perm_A_25_0 + poseidon2_perm_A_25_1 + poseidon2_perm_A_25_2 + poseidon2_perm_A_25_3; + const auto poseidon2_perm_ARK_26_0 = new_term.poseidon2_perm_B_25_0 + poseidon2_params_C_26_0; + const auto poseidon2_perm_ARK_26_1 = new_term.poseidon2_perm_B_25_1 + poseidon2_params_C_26_1; + const auto poseidon2_perm_ARK_26_2 = new_term.poseidon2_perm_B_25_2 + poseidon2_params_C_26_2; + const auto poseidon2_perm_ARK_26_3 = new_term.poseidon2_perm_B_25_3 + poseidon2_params_C_26_3; + const auto poseidon2_perm_A_26_0 = poseidon2_perm_ARK_26_0 * poseidon2_perm_ARK_26_0 * poseidon2_perm_ARK_26_0 * + poseidon2_perm_ARK_26_0 * poseidon2_perm_ARK_26_0; + const auto poseidon2_perm_A_26_1 = poseidon2_perm_ARK_26_1; + const auto poseidon2_perm_A_26_2 = poseidon2_perm_ARK_26_2; + const auto poseidon2_perm_A_26_3 = poseidon2_perm_ARK_26_3; + const auto poseidon2_perm_SUM_26 = + poseidon2_perm_A_26_0 + poseidon2_perm_A_26_1 + poseidon2_perm_A_26_2 + poseidon2_perm_A_26_3; + const auto poseidon2_perm_ARK_27_0 = new_term.poseidon2_perm_B_26_0 + poseidon2_params_C_27_0; + const auto poseidon2_perm_ARK_27_1 = new_term.poseidon2_perm_B_26_1 + poseidon2_params_C_27_1; + const auto poseidon2_perm_ARK_27_2 = new_term.poseidon2_perm_B_26_2 + poseidon2_params_C_27_2; + const auto poseidon2_perm_ARK_27_3 = new_term.poseidon2_perm_B_26_3 + poseidon2_params_C_27_3; + const auto poseidon2_perm_A_27_0 = poseidon2_perm_ARK_27_0 * poseidon2_perm_ARK_27_0 * poseidon2_perm_ARK_27_0 * + poseidon2_perm_ARK_27_0 * poseidon2_perm_ARK_27_0; + const auto poseidon2_perm_A_27_1 = poseidon2_perm_ARK_27_1; + const auto poseidon2_perm_A_27_2 = poseidon2_perm_ARK_27_2; + const auto poseidon2_perm_A_27_3 = poseidon2_perm_ARK_27_3; + const auto poseidon2_perm_SUM_27 = + poseidon2_perm_A_27_0 + poseidon2_perm_A_27_1 + poseidon2_perm_A_27_2 + poseidon2_perm_A_27_3; + const auto poseidon2_perm_ARK_28_0 = new_term.poseidon2_perm_B_27_0 + poseidon2_params_C_28_0; + const auto poseidon2_perm_ARK_28_1 = new_term.poseidon2_perm_B_27_1 + poseidon2_params_C_28_1; + const auto poseidon2_perm_ARK_28_2 = new_term.poseidon2_perm_B_27_2 + poseidon2_params_C_28_2; + const auto poseidon2_perm_ARK_28_3 = new_term.poseidon2_perm_B_27_3 + poseidon2_params_C_28_3; + const auto poseidon2_perm_A_28_0 = poseidon2_perm_ARK_28_0 * poseidon2_perm_ARK_28_0 * poseidon2_perm_ARK_28_0 * + poseidon2_perm_ARK_28_0 * poseidon2_perm_ARK_28_0; + const auto poseidon2_perm_A_28_1 = poseidon2_perm_ARK_28_1; + const auto poseidon2_perm_A_28_2 = poseidon2_perm_ARK_28_2; + const auto poseidon2_perm_A_28_3 = poseidon2_perm_ARK_28_3; + const auto poseidon2_perm_SUM_28 = + poseidon2_perm_A_28_0 + poseidon2_perm_A_28_1 + poseidon2_perm_A_28_2 + poseidon2_perm_A_28_3; + const auto poseidon2_perm_ARK_29_0 = new_term.poseidon2_perm_B_28_0 + poseidon2_params_C_29_0; + const auto poseidon2_perm_ARK_29_1 = new_term.poseidon2_perm_B_28_1 + poseidon2_params_C_29_1; + const auto poseidon2_perm_ARK_29_2 = new_term.poseidon2_perm_B_28_2 + poseidon2_params_C_29_2; + const auto poseidon2_perm_ARK_29_3 = new_term.poseidon2_perm_B_28_3 + poseidon2_params_C_29_3; + const auto poseidon2_perm_A_29_0 = poseidon2_perm_ARK_29_0 * poseidon2_perm_ARK_29_0 * poseidon2_perm_ARK_29_0 * + poseidon2_perm_ARK_29_0 * poseidon2_perm_ARK_29_0; + const auto poseidon2_perm_A_29_1 = poseidon2_perm_ARK_29_1; + const auto poseidon2_perm_A_29_2 = poseidon2_perm_ARK_29_2; + const auto poseidon2_perm_A_29_3 = poseidon2_perm_ARK_29_3; + const auto poseidon2_perm_SUM_29 = + poseidon2_perm_A_29_0 + poseidon2_perm_A_29_1 + poseidon2_perm_A_29_2 + poseidon2_perm_A_29_3; + const auto poseidon2_perm_ARK_30_0 = new_term.poseidon2_perm_B_29_0 + poseidon2_params_C_30_0; + const auto poseidon2_perm_ARK_30_1 = new_term.poseidon2_perm_B_29_1 + poseidon2_params_C_30_1; + const auto poseidon2_perm_ARK_30_2 = new_term.poseidon2_perm_B_29_2 + poseidon2_params_C_30_2; + const auto poseidon2_perm_ARK_30_3 = new_term.poseidon2_perm_B_29_3 + poseidon2_params_C_30_3; + const auto poseidon2_perm_A_30_0 = poseidon2_perm_ARK_30_0 * poseidon2_perm_ARK_30_0 * poseidon2_perm_ARK_30_0 * + poseidon2_perm_ARK_30_0 * poseidon2_perm_ARK_30_0; + const auto poseidon2_perm_A_30_1 = poseidon2_perm_ARK_30_1; + const auto poseidon2_perm_A_30_2 = poseidon2_perm_ARK_30_2; + const auto poseidon2_perm_A_30_3 = poseidon2_perm_ARK_30_3; + const auto poseidon2_perm_SUM_30 = + poseidon2_perm_A_30_0 + poseidon2_perm_A_30_1 + poseidon2_perm_A_30_2 + poseidon2_perm_A_30_3; + const auto poseidon2_perm_ARK_31_0 = new_term.poseidon2_perm_B_30_0 + poseidon2_params_C_31_0; + const auto poseidon2_perm_ARK_31_1 = new_term.poseidon2_perm_B_30_1 + poseidon2_params_C_31_1; + const auto poseidon2_perm_ARK_31_2 = new_term.poseidon2_perm_B_30_2 + poseidon2_params_C_31_2; + const auto poseidon2_perm_ARK_31_3 = new_term.poseidon2_perm_B_30_3 + poseidon2_params_C_31_3; + const auto poseidon2_perm_A_31_0 = poseidon2_perm_ARK_31_0 * poseidon2_perm_ARK_31_0 * poseidon2_perm_ARK_31_0 * + poseidon2_perm_ARK_31_0 * poseidon2_perm_ARK_31_0; + const auto poseidon2_perm_A_31_1 = poseidon2_perm_ARK_31_1; + const auto poseidon2_perm_A_31_2 = poseidon2_perm_ARK_31_2; + const auto poseidon2_perm_A_31_3 = poseidon2_perm_ARK_31_3; + const auto poseidon2_perm_SUM_31 = + poseidon2_perm_A_31_0 + poseidon2_perm_A_31_1 + poseidon2_perm_A_31_2 + poseidon2_perm_A_31_3; + const auto poseidon2_perm_ARK_32_0 = new_term.poseidon2_perm_B_31_0 + poseidon2_params_C_32_0; + const auto poseidon2_perm_ARK_32_1 = new_term.poseidon2_perm_B_31_1 + poseidon2_params_C_32_1; + const auto poseidon2_perm_ARK_32_2 = new_term.poseidon2_perm_B_31_2 + poseidon2_params_C_32_2; + const auto poseidon2_perm_ARK_32_3 = new_term.poseidon2_perm_B_31_3 + poseidon2_params_C_32_3; + const auto poseidon2_perm_A_32_0 = poseidon2_perm_ARK_32_0 * poseidon2_perm_ARK_32_0 * poseidon2_perm_ARK_32_0 * + poseidon2_perm_ARK_32_0 * poseidon2_perm_ARK_32_0; + const auto poseidon2_perm_A_32_1 = poseidon2_perm_ARK_32_1; + const auto poseidon2_perm_A_32_2 = poseidon2_perm_ARK_32_2; + const auto poseidon2_perm_A_32_3 = poseidon2_perm_ARK_32_3; + const auto poseidon2_perm_SUM_32 = + poseidon2_perm_A_32_0 + poseidon2_perm_A_32_1 + poseidon2_perm_A_32_2 + poseidon2_perm_A_32_3; + const auto poseidon2_perm_ARK_33_0 = new_term.poseidon2_perm_B_32_0 + poseidon2_params_C_33_0; + const auto poseidon2_perm_ARK_33_1 = new_term.poseidon2_perm_B_32_1 + poseidon2_params_C_33_1; + const auto poseidon2_perm_ARK_33_2 = new_term.poseidon2_perm_B_32_2 + poseidon2_params_C_33_2; + const auto poseidon2_perm_ARK_33_3 = new_term.poseidon2_perm_B_32_3 + poseidon2_params_C_33_3; + const auto poseidon2_perm_A_33_0 = poseidon2_perm_ARK_33_0 * poseidon2_perm_ARK_33_0 * poseidon2_perm_ARK_33_0 * + poseidon2_perm_ARK_33_0 * poseidon2_perm_ARK_33_0; + const auto poseidon2_perm_A_33_1 = poseidon2_perm_ARK_33_1; + const auto poseidon2_perm_A_33_2 = poseidon2_perm_ARK_33_2; + const auto poseidon2_perm_A_33_3 = poseidon2_perm_ARK_33_3; + const auto poseidon2_perm_SUM_33 = + poseidon2_perm_A_33_0 + poseidon2_perm_A_33_1 + poseidon2_perm_A_33_2 + poseidon2_perm_A_33_3; + const auto poseidon2_perm_ARK_34_0 = new_term.poseidon2_perm_B_33_0 + poseidon2_params_C_34_0; + const auto poseidon2_perm_ARK_34_1 = new_term.poseidon2_perm_B_33_1 + poseidon2_params_C_34_1; + const auto poseidon2_perm_ARK_34_2 = new_term.poseidon2_perm_B_33_2 + poseidon2_params_C_34_2; + const auto poseidon2_perm_ARK_34_3 = new_term.poseidon2_perm_B_33_3 + poseidon2_params_C_34_3; + const auto poseidon2_perm_A_34_0 = poseidon2_perm_ARK_34_0 * poseidon2_perm_ARK_34_0 * poseidon2_perm_ARK_34_0 * + poseidon2_perm_ARK_34_0 * poseidon2_perm_ARK_34_0; + const auto poseidon2_perm_A_34_1 = poseidon2_perm_ARK_34_1; + const auto poseidon2_perm_A_34_2 = poseidon2_perm_ARK_34_2; + const auto poseidon2_perm_A_34_3 = poseidon2_perm_ARK_34_3; + const auto poseidon2_perm_SUM_34 = + poseidon2_perm_A_34_0 + poseidon2_perm_A_34_1 + poseidon2_perm_A_34_2 + poseidon2_perm_A_34_3; + const auto poseidon2_perm_ARK_35_0 = new_term.poseidon2_perm_B_34_0 + poseidon2_params_C_35_0; + const auto poseidon2_perm_ARK_35_1 = new_term.poseidon2_perm_B_34_1 + poseidon2_params_C_35_1; + const auto poseidon2_perm_ARK_35_2 = new_term.poseidon2_perm_B_34_2 + poseidon2_params_C_35_2; + const auto poseidon2_perm_ARK_35_3 = new_term.poseidon2_perm_B_34_3 + poseidon2_params_C_35_3; + const auto poseidon2_perm_A_35_0 = poseidon2_perm_ARK_35_0 * poseidon2_perm_ARK_35_0 * poseidon2_perm_ARK_35_0 * + poseidon2_perm_ARK_35_0 * poseidon2_perm_ARK_35_0; + const auto poseidon2_perm_A_35_1 = poseidon2_perm_ARK_35_1; + const auto poseidon2_perm_A_35_2 = poseidon2_perm_ARK_35_2; + const auto poseidon2_perm_A_35_3 = poseidon2_perm_ARK_35_3; + const auto poseidon2_perm_SUM_35 = + poseidon2_perm_A_35_0 + poseidon2_perm_A_35_1 + poseidon2_perm_A_35_2 + poseidon2_perm_A_35_3; + const auto poseidon2_perm_ARK_36_0 = new_term.poseidon2_perm_B_35_0 + poseidon2_params_C_36_0; + const auto poseidon2_perm_ARK_36_1 = new_term.poseidon2_perm_B_35_1 + poseidon2_params_C_36_1; + const auto poseidon2_perm_ARK_36_2 = new_term.poseidon2_perm_B_35_2 + poseidon2_params_C_36_2; + const auto poseidon2_perm_ARK_36_3 = new_term.poseidon2_perm_B_35_3 + poseidon2_params_C_36_3; + const auto poseidon2_perm_A_36_0 = poseidon2_perm_ARK_36_0 * poseidon2_perm_ARK_36_0 * poseidon2_perm_ARK_36_0 * + poseidon2_perm_ARK_36_0 * poseidon2_perm_ARK_36_0; + const auto poseidon2_perm_A_36_1 = poseidon2_perm_ARK_36_1; + const auto poseidon2_perm_A_36_2 = poseidon2_perm_ARK_36_2; + const auto poseidon2_perm_A_36_3 = poseidon2_perm_ARK_36_3; + const auto poseidon2_perm_SUM_36 = + poseidon2_perm_A_36_0 + poseidon2_perm_A_36_1 + poseidon2_perm_A_36_2 + poseidon2_perm_A_36_3; + const auto poseidon2_perm_ARK_37_0 = new_term.poseidon2_perm_B_36_0 + poseidon2_params_C_37_0; + const auto poseidon2_perm_ARK_37_1 = new_term.poseidon2_perm_B_36_1 + poseidon2_params_C_37_1; + const auto poseidon2_perm_ARK_37_2 = new_term.poseidon2_perm_B_36_2 + poseidon2_params_C_37_2; + const auto poseidon2_perm_ARK_37_3 = new_term.poseidon2_perm_B_36_3 + poseidon2_params_C_37_3; + const auto poseidon2_perm_A_37_0 = poseidon2_perm_ARK_37_0 * poseidon2_perm_ARK_37_0 * poseidon2_perm_ARK_37_0 * + poseidon2_perm_ARK_37_0 * poseidon2_perm_ARK_37_0; + const auto poseidon2_perm_A_37_1 = poseidon2_perm_ARK_37_1; + const auto poseidon2_perm_A_37_2 = poseidon2_perm_ARK_37_2; + const auto poseidon2_perm_A_37_3 = poseidon2_perm_ARK_37_3; + const auto poseidon2_perm_SUM_37 = + poseidon2_perm_A_37_0 + poseidon2_perm_A_37_1 + poseidon2_perm_A_37_2 + poseidon2_perm_A_37_3; + const auto poseidon2_perm_ARK_38_0 = new_term.poseidon2_perm_B_37_0 + poseidon2_params_C_38_0; + const auto poseidon2_perm_ARK_38_1 = new_term.poseidon2_perm_B_37_1 + poseidon2_params_C_38_1; + const auto poseidon2_perm_ARK_38_2 = new_term.poseidon2_perm_B_37_2 + poseidon2_params_C_38_2; + const auto poseidon2_perm_ARK_38_3 = new_term.poseidon2_perm_B_37_3 + poseidon2_params_C_38_3; + const auto poseidon2_perm_A_38_0 = poseidon2_perm_ARK_38_0 * poseidon2_perm_ARK_38_0 * poseidon2_perm_ARK_38_0 * + poseidon2_perm_ARK_38_0 * poseidon2_perm_ARK_38_0; + const auto poseidon2_perm_A_38_1 = poseidon2_perm_ARK_38_1; + const auto poseidon2_perm_A_38_2 = poseidon2_perm_ARK_38_2; + const auto poseidon2_perm_A_38_3 = poseidon2_perm_ARK_38_3; + const auto poseidon2_perm_SUM_38 = + poseidon2_perm_A_38_0 + poseidon2_perm_A_38_1 + poseidon2_perm_A_38_2 + poseidon2_perm_A_38_3; + const auto poseidon2_perm_ARK_39_0 = new_term.poseidon2_perm_B_38_0 + poseidon2_params_C_39_0; + const auto poseidon2_perm_ARK_39_1 = new_term.poseidon2_perm_B_38_1 + poseidon2_params_C_39_1; + const auto poseidon2_perm_ARK_39_2 = new_term.poseidon2_perm_B_38_2 + poseidon2_params_C_39_2; + const auto poseidon2_perm_ARK_39_3 = new_term.poseidon2_perm_B_38_3 + poseidon2_params_C_39_3; + const auto poseidon2_perm_A_39_0 = poseidon2_perm_ARK_39_0 * poseidon2_perm_ARK_39_0 * poseidon2_perm_ARK_39_0 * + poseidon2_perm_ARK_39_0 * poseidon2_perm_ARK_39_0; + const auto poseidon2_perm_A_39_1 = poseidon2_perm_ARK_39_1; + const auto poseidon2_perm_A_39_2 = poseidon2_perm_ARK_39_2; + const auto poseidon2_perm_A_39_3 = poseidon2_perm_ARK_39_3; + const auto poseidon2_perm_SUM_39 = + poseidon2_perm_A_39_0 + poseidon2_perm_A_39_1 + poseidon2_perm_A_39_2 + poseidon2_perm_A_39_3; + const auto poseidon2_perm_ARK_40_0 = new_term.poseidon2_perm_B_39_0 + poseidon2_params_C_40_0; + const auto poseidon2_perm_ARK_40_1 = new_term.poseidon2_perm_B_39_1 + poseidon2_params_C_40_1; + const auto poseidon2_perm_ARK_40_2 = new_term.poseidon2_perm_B_39_2 + poseidon2_params_C_40_2; + const auto poseidon2_perm_ARK_40_3 = new_term.poseidon2_perm_B_39_3 + poseidon2_params_C_40_3; + const auto poseidon2_perm_A_40_0 = poseidon2_perm_ARK_40_0 * poseidon2_perm_ARK_40_0 * poseidon2_perm_ARK_40_0 * + poseidon2_perm_ARK_40_0 * poseidon2_perm_ARK_40_0; + const auto poseidon2_perm_A_40_1 = poseidon2_perm_ARK_40_1; + const auto poseidon2_perm_A_40_2 = poseidon2_perm_ARK_40_2; + const auto poseidon2_perm_A_40_3 = poseidon2_perm_ARK_40_3; + const auto poseidon2_perm_SUM_40 = + poseidon2_perm_A_40_0 + poseidon2_perm_A_40_1 + poseidon2_perm_A_40_2 + poseidon2_perm_A_40_3; + const auto poseidon2_perm_ARK_41_0 = new_term.poseidon2_perm_B_40_0 + poseidon2_params_C_41_0; + const auto poseidon2_perm_ARK_41_1 = new_term.poseidon2_perm_B_40_1 + poseidon2_params_C_41_1; + const auto poseidon2_perm_ARK_41_2 = new_term.poseidon2_perm_B_40_2 + poseidon2_params_C_41_2; + const auto poseidon2_perm_ARK_41_3 = new_term.poseidon2_perm_B_40_3 + poseidon2_params_C_41_3; + const auto poseidon2_perm_A_41_0 = poseidon2_perm_ARK_41_0 * poseidon2_perm_ARK_41_0 * poseidon2_perm_ARK_41_0 * + poseidon2_perm_ARK_41_0 * poseidon2_perm_ARK_41_0; + const auto poseidon2_perm_A_41_1 = poseidon2_perm_ARK_41_1; + const auto poseidon2_perm_A_41_2 = poseidon2_perm_ARK_41_2; + const auto poseidon2_perm_A_41_3 = poseidon2_perm_ARK_41_3; + const auto poseidon2_perm_SUM_41 = + poseidon2_perm_A_41_0 + poseidon2_perm_A_41_1 + poseidon2_perm_A_41_2 + poseidon2_perm_A_41_3; + const auto poseidon2_perm_ARK_42_0 = new_term.poseidon2_perm_B_41_0 + poseidon2_params_C_42_0; + const auto poseidon2_perm_ARK_42_1 = new_term.poseidon2_perm_B_41_1 + poseidon2_params_C_42_1; + const auto poseidon2_perm_ARK_42_2 = new_term.poseidon2_perm_B_41_2 + poseidon2_params_C_42_2; + const auto poseidon2_perm_ARK_42_3 = new_term.poseidon2_perm_B_41_3 + poseidon2_params_C_42_3; + const auto poseidon2_perm_A_42_0 = poseidon2_perm_ARK_42_0 * poseidon2_perm_ARK_42_0 * poseidon2_perm_ARK_42_0 * + poseidon2_perm_ARK_42_0 * poseidon2_perm_ARK_42_0; + const auto poseidon2_perm_A_42_1 = poseidon2_perm_ARK_42_1; + const auto poseidon2_perm_A_42_2 = poseidon2_perm_ARK_42_2; + const auto poseidon2_perm_A_42_3 = poseidon2_perm_ARK_42_3; + const auto poseidon2_perm_SUM_42 = + poseidon2_perm_A_42_0 + poseidon2_perm_A_42_1 + poseidon2_perm_A_42_2 + poseidon2_perm_A_42_3; + const auto poseidon2_perm_ARK_43_0 = new_term.poseidon2_perm_B_42_0 + poseidon2_params_C_43_0; + const auto poseidon2_perm_ARK_43_1 = new_term.poseidon2_perm_B_42_1 + poseidon2_params_C_43_1; + const auto poseidon2_perm_ARK_43_2 = new_term.poseidon2_perm_B_42_2 + poseidon2_params_C_43_2; + const auto poseidon2_perm_ARK_43_3 = new_term.poseidon2_perm_B_42_3 + poseidon2_params_C_43_3; + const auto poseidon2_perm_A_43_0 = poseidon2_perm_ARK_43_0 * poseidon2_perm_ARK_43_0 * poseidon2_perm_ARK_43_0 * + poseidon2_perm_ARK_43_0 * poseidon2_perm_ARK_43_0; + const auto poseidon2_perm_A_43_1 = poseidon2_perm_ARK_43_1; + const auto poseidon2_perm_A_43_2 = poseidon2_perm_ARK_43_2; + const auto poseidon2_perm_A_43_3 = poseidon2_perm_ARK_43_3; + const auto poseidon2_perm_SUM_43 = + poseidon2_perm_A_43_0 + poseidon2_perm_A_43_1 + poseidon2_perm_A_43_2 + poseidon2_perm_A_43_3; + const auto poseidon2_perm_ARK_44_0 = new_term.poseidon2_perm_B_43_0 + poseidon2_params_C_44_0; + const auto poseidon2_perm_ARK_44_1 = new_term.poseidon2_perm_B_43_1 + poseidon2_params_C_44_1; + const auto poseidon2_perm_ARK_44_2 = new_term.poseidon2_perm_B_43_2 + poseidon2_params_C_44_2; + const auto poseidon2_perm_ARK_44_3 = new_term.poseidon2_perm_B_43_3 + poseidon2_params_C_44_3; + const auto poseidon2_perm_A_44_0 = poseidon2_perm_ARK_44_0 * poseidon2_perm_ARK_44_0 * poseidon2_perm_ARK_44_0 * + poseidon2_perm_ARK_44_0 * poseidon2_perm_ARK_44_0; + const auto poseidon2_perm_A_44_1 = poseidon2_perm_ARK_44_1; + const auto poseidon2_perm_A_44_2 = poseidon2_perm_ARK_44_2; + const auto poseidon2_perm_A_44_3 = poseidon2_perm_ARK_44_3; + const auto poseidon2_perm_SUM_44 = + poseidon2_perm_A_44_0 + poseidon2_perm_A_44_1 + poseidon2_perm_A_44_2 + poseidon2_perm_A_44_3; + const auto poseidon2_perm_ARK_45_0 = new_term.poseidon2_perm_B_44_0 + poseidon2_params_C_45_0; + const auto poseidon2_perm_ARK_45_1 = new_term.poseidon2_perm_B_44_1 + poseidon2_params_C_45_1; + const auto poseidon2_perm_ARK_45_2 = new_term.poseidon2_perm_B_44_2 + poseidon2_params_C_45_2; + const auto poseidon2_perm_ARK_45_3 = new_term.poseidon2_perm_B_44_3 + poseidon2_params_C_45_3; + const auto poseidon2_perm_A_45_0 = poseidon2_perm_ARK_45_0 * poseidon2_perm_ARK_45_0 * poseidon2_perm_ARK_45_0 * + poseidon2_perm_ARK_45_0 * poseidon2_perm_ARK_45_0; + const auto poseidon2_perm_A_45_1 = poseidon2_perm_ARK_45_1; + const auto poseidon2_perm_A_45_2 = poseidon2_perm_ARK_45_2; + const auto poseidon2_perm_A_45_3 = poseidon2_perm_ARK_45_3; + const auto poseidon2_perm_SUM_45 = + poseidon2_perm_A_45_0 + poseidon2_perm_A_45_1 + poseidon2_perm_A_45_2 + poseidon2_perm_A_45_3; + const auto poseidon2_perm_ARK_46_0 = new_term.poseidon2_perm_B_45_0 + poseidon2_params_C_46_0; + const auto poseidon2_perm_ARK_46_1 = new_term.poseidon2_perm_B_45_1 + poseidon2_params_C_46_1; + const auto poseidon2_perm_ARK_46_2 = new_term.poseidon2_perm_B_45_2 + poseidon2_params_C_46_2; + const auto poseidon2_perm_ARK_46_3 = new_term.poseidon2_perm_B_45_3 + poseidon2_params_C_46_3; + const auto poseidon2_perm_A_46_0 = poseidon2_perm_ARK_46_0 * poseidon2_perm_ARK_46_0 * poseidon2_perm_ARK_46_0 * + poseidon2_perm_ARK_46_0 * poseidon2_perm_ARK_46_0; + const auto poseidon2_perm_A_46_1 = poseidon2_perm_ARK_46_1; + const auto poseidon2_perm_A_46_2 = poseidon2_perm_ARK_46_2; + const auto poseidon2_perm_A_46_3 = poseidon2_perm_ARK_46_3; + const auto poseidon2_perm_SUM_46 = + poseidon2_perm_A_46_0 + poseidon2_perm_A_46_1 + poseidon2_perm_A_46_2 + poseidon2_perm_A_46_3; + const auto poseidon2_perm_ARK_47_0 = new_term.poseidon2_perm_B_46_0 + poseidon2_params_C_47_0; + const auto poseidon2_perm_ARK_47_1 = new_term.poseidon2_perm_B_46_1 + poseidon2_params_C_47_1; + const auto poseidon2_perm_ARK_47_2 = new_term.poseidon2_perm_B_46_2 + poseidon2_params_C_47_2; + const auto poseidon2_perm_ARK_47_3 = new_term.poseidon2_perm_B_46_3 + poseidon2_params_C_47_3; + const auto poseidon2_perm_A_47_0 = poseidon2_perm_ARK_47_0 * poseidon2_perm_ARK_47_0 * poseidon2_perm_ARK_47_0 * + poseidon2_perm_ARK_47_0 * poseidon2_perm_ARK_47_0; + const auto poseidon2_perm_A_47_1 = poseidon2_perm_ARK_47_1; + const auto poseidon2_perm_A_47_2 = poseidon2_perm_ARK_47_2; + const auto poseidon2_perm_A_47_3 = poseidon2_perm_ARK_47_3; + const auto poseidon2_perm_SUM_47 = + poseidon2_perm_A_47_0 + poseidon2_perm_A_47_1 + poseidon2_perm_A_47_2 + poseidon2_perm_A_47_3; + const auto poseidon2_perm_ARK_48_0 = new_term.poseidon2_perm_B_47_0 + poseidon2_params_C_48_0; + const auto poseidon2_perm_ARK_48_1 = new_term.poseidon2_perm_B_47_1 + poseidon2_params_C_48_1; + const auto poseidon2_perm_ARK_48_2 = new_term.poseidon2_perm_B_47_2 + poseidon2_params_C_48_2; + const auto poseidon2_perm_ARK_48_3 = new_term.poseidon2_perm_B_47_3 + poseidon2_params_C_48_3; + const auto poseidon2_perm_A_48_0 = poseidon2_perm_ARK_48_0 * poseidon2_perm_ARK_48_0 * poseidon2_perm_ARK_48_0 * + poseidon2_perm_ARK_48_0 * poseidon2_perm_ARK_48_0; + const auto poseidon2_perm_A_48_1 = poseidon2_perm_ARK_48_1; + const auto poseidon2_perm_A_48_2 = poseidon2_perm_ARK_48_2; + const auto poseidon2_perm_A_48_3 = poseidon2_perm_ARK_48_3; + const auto poseidon2_perm_SUM_48 = + poseidon2_perm_A_48_0 + poseidon2_perm_A_48_1 + poseidon2_perm_A_48_2 + poseidon2_perm_A_48_3; + const auto poseidon2_perm_ARK_49_0 = new_term.poseidon2_perm_B_48_0 + poseidon2_params_C_49_0; + const auto poseidon2_perm_ARK_49_1 = new_term.poseidon2_perm_B_48_1 + poseidon2_params_C_49_1; + const auto poseidon2_perm_ARK_49_2 = new_term.poseidon2_perm_B_48_2 + poseidon2_params_C_49_2; + const auto poseidon2_perm_ARK_49_3 = new_term.poseidon2_perm_B_48_3 + poseidon2_params_C_49_3; + const auto poseidon2_perm_A_49_0 = poseidon2_perm_ARK_49_0 * poseidon2_perm_ARK_49_0 * poseidon2_perm_ARK_49_0 * + poseidon2_perm_ARK_49_0 * poseidon2_perm_ARK_49_0; + const auto poseidon2_perm_A_49_1 = poseidon2_perm_ARK_49_1; + const auto poseidon2_perm_A_49_2 = poseidon2_perm_ARK_49_2; + const auto poseidon2_perm_A_49_3 = poseidon2_perm_ARK_49_3; + const auto poseidon2_perm_SUM_49 = + poseidon2_perm_A_49_0 + poseidon2_perm_A_49_1 + poseidon2_perm_A_49_2 + poseidon2_perm_A_49_3; + const auto poseidon2_perm_ARK_50_0 = new_term.poseidon2_perm_B_49_0 + poseidon2_params_C_50_0; + const auto poseidon2_perm_ARK_50_1 = new_term.poseidon2_perm_B_49_1 + poseidon2_params_C_50_1; + const auto poseidon2_perm_ARK_50_2 = new_term.poseidon2_perm_B_49_2 + poseidon2_params_C_50_2; + const auto poseidon2_perm_ARK_50_3 = new_term.poseidon2_perm_B_49_3 + poseidon2_params_C_50_3; + const auto poseidon2_perm_A_50_0 = poseidon2_perm_ARK_50_0 * poseidon2_perm_ARK_50_0 * poseidon2_perm_ARK_50_0 * + poseidon2_perm_ARK_50_0 * poseidon2_perm_ARK_50_0; + const auto poseidon2_perm_A_50_1 = poseidon2_perm_ARK_50_1; + const auto poseidon2_perm_A_50_2 = poseidon2_perm_ARK_50_2; + const auto poseidon2_perm_A_50_3 = poseidon2_perm_ARK_50_3; + const auto poseidon2_perm_SUM_50 = + poseidon2_perm_A_50_0 + poseidon2_perm_A_50_1 + poseidon2_perm_A_50_2 + poseidon2_perm_A_50_3; + const auto poseidon2_perm_ARK_51_0 = new_term.poseidon2_perm_B_50_0 + poseidon2_params_C_51_0; + const auto poseidon2_perm_ARK_51_1 = new_term.poseidon2_perm_B_50_1 + poseidon2_params_C_51_1; + const auto poseidon2_perm_ARK_51_2 = new_term.poseidon2_perm_B_50_2 + poseidon2_params_C_51_2; + const auto poseidon2_perm_ARK_51_3 = new_term.poseidon2_perm_B_50_3 + poseidon2_params_C_51_3; + const auto poseidon2_perm_A_51_0 = poseidon2_perm_ARK_51_0 * poseidon2_perm_ARK_51_0 * poseidon2_perm_ARK_51_0 * + poseidon2_perm_ARK_51_0 * poseidon2_perm_ARK_51_0; + const auto poseidon2_perm_A_51_1 = poseidon2_perm_ARK_51_1; + const auto poseidon2_perm_A_51_2 = poseidon2_perm_ARK_51_2; + const auto poseidon2_perm_A_51_3 = poseidon2_perm_ARK_51_3; + const auto poseidon2_perm_SUM_51 = + poseidon2_perm_A_51_0 + poseidon2_perm_A_51_1 + poseidon2_perm_A_51_2 + poseidon2_perm_A_51_3; + const auto poseidon2_perm_ARK_52_0 = new_term.poseidon2_perm_B_51_0 + poseidon2_params_C_52_0; + const auto poseidon2_perm_ARK_52_1 = new_term.poseidon2_perm_B_51_1 + poseidon2_params_C_52_1; + const auto poseidon2_perm_ARK_52_2 = new_term.poseidon2_perm_B_51_2 + poseidon2_params_C_52_2; + const auto poseidon2_perm_ARK_52_3 = new_term.poseidon2_perm_B_51_3 + poseidon2_params_C_52_3; + const auto poseidon2_perm_A_52_0 = poseidon2_perm_ARK_52_0 * poseidon2_perm_ARK_52_0 * poseidon2_perm_ARK_52_0 * + poseidon2_perm_ARK_52_0 * poseidon2_perm_ARK_52_0; + const auto poseidon2_perm_A_52_1 = poseidon2_perm_ARK_52_1; + const auto poseidon2_perm_A_52_2 = poseidon2_perm_ARK_52_2; + const auto poseidon2_perm_A_52_3 = poseidon2_perm_ARK_52_3; + const auto poseidon2_perm_SUM_52 = + poseidon2_perm_A_52_0 + poseidon2_perm_A_52_1 + poseidon2_perm_A_52_2 + poseidon2_perm_A_52_3; + const auto poseidon2_perm_ARK_53_0 = new_term.poseidon2_perm_B_52_0 + poseidon2_params_C_53_0; + const auto poseidon2_perm_ARK_53_1 = new_term.poseidon2_perm_B_52_1 + poseidon2_params_C_53_1; + const auto poseidon2_perm_ARK_53_2 = new_term.poseidon2_perm_B_52_2 + poseidon2_params_C_53_2; + const auto poseidon2_perm_ARK_53_3 = new_term.poseidon2_perm_B_52_3 + poseidon2_params_C_53_3; + const auto poseidon2_perm_A_53_0 = poseidon2_perm_ARK_53_0 * poseidon2_perm_ARK_53_0 * poseidon2_perm_ARK_53_0 * + poseidon2_perm_ARK_53_0 * poseidon2_perm_ARK_53_0; + const auto poseidon2_perm_A_53_1 = poseidon2_perm_ARK_53_1; + const auto poseidon2_perm_A_53_2 = poseidon2_perm_ARK_53_2; + const auto poseidon2_perm_A_53_3 = poseidon2_perm_ARK_53_3; + const auto poseidon2_perm_SUM_53 = + poseidon2_perm_A_53_0 + poseidon2_perm_A_53_1 + poseidon2_perm_A_53_2 + poseidon2_perm_A_53_3; + const auto poseidon2_perm_ARK_54_0 = new_term.poseidon2_perm_B_53_0 + poseidon2_params_C_54_0; + const auto poseidon2_perm_ARK_54_1 = new_term.poseidon2_perm_B_53_1 + poseidon2_params_C_54_1; + const auto poseidon2_perm_ARK_54_2 = new_term.poseidon2_perm_B_53_2 + poseidon2_params_C_54_2; + const auto poseidon2_perm_ARK_54_3 = new_term.poseidon2_perm_B_53_3 + poseidon2_params_C_54_3; + const auto poseidon2_perm_A_54_0 = poseidon2_perm_ARK_54_0 * poseidon2_perm_ARK_54_0 * poseidon2_perm_ARK_54_0 * + poseidon2_perm_ARK_54_0 * poseidon2_perm_ARK_54_0; + const auto poseidon2_perm_A_54_1 = poseidon2_perm_ARK_54_1; + const auto poseidon2_perm_A_54_2 = poseidon2_perm_ARK_54_2; + const auto poseidon2_perm_A_54_3 = poseidon2_perm_ARK_54_3; + const auto poseidon2_perm_SUM_54 = + poseidon2_perm_A_54_0 + poseidon2_perm_A_54_1 + poseidon2_perm_A_54_2 + poseidon2_perm_A_54_3; + const auto poseidon2_perm_ARK_55_0 = new_term.poseidon2_perm_B_54_0 + poseidon2_params_C_55_0; + const auto poseidon2_perm_ARK_55_1 = new_term.poseidon2_perm_B_54_1 + poseidon2_params_C_55_1; + const auto poseidon2_perm_ARK_55_2 = new_term.poseidon2_perm_B_54_2 + poseidon2_params_C_55_2; + const auto poseidon2_perm_ARK_55_3 = new_term.poseidon2_perm_B_54_3 + poseidon2_params_C_55_3; + const auto poseidon2_perm_A_55_0 = poseidon2_perm_ARK_55_0 * poseidon2_perm_ARK_55_0 * poseidon2_perm_ARK_55_0 * + poseidon2_perm_ARK_55_0 * poseidon2_perm_ARK_55_0; + const auto poseidon2_perm_A_55_1 = poseidon2_perm_ARK_55_1; + const auto poseidon2_perm_A_55_2 = poseidon2_perm_ARK_55_2; + const auto poseidon2_perm_A_55_3 = poseidon2_perm_ARK_55_3; + const auto poseidon2_perm_SUM_55 = + poseidon2_perm_A_55_0 + poseidon2_perm_A_55_1 + poseidon2_perm_A_55_2 + poseidon2_perm_A_55_3; + const auto poseidon2_perm_ARK_56_0 = new_term.poseidon2_perm_B_55_0 + poseidon2_params_C_56_0; + const auto poseidon2_perm_ARK_56_1 = new_term.poseidon2_perm_B_55_1 + poseidon2_params_C_56_1; + const auto poseidon2_perm_ARK_56_2 = new_term.poseidon2_perm_B_55_2 + poseidon2_params_C_56_2; + const auto poseidon2_perm_ARK_56_3 = new_term.poseidon2_perm_B_55_3 + poseidon2_params_C_56_3; + const auto poseidon2_perm_A_56_0 = poseidon2_perm_ARK_56_0 * poseidon2_perm_ARK_56_0 * poseidon2_perm_ARK_56_0 * + poseidon2_perm_ARK_56_0 * poseidon2_perm_ARK_56_0; + const auto poseidon2_perm_A_56_1 = poseidon2_perm_ARK_56_1; + const auto poseidon2_perm_A_56_2 = poseidon2_perm_ARK_56_2; + const auto poseidon2_perm_A_56_3 = poseidon2_perm_ARK_56_3; + const auto poseidon2_perm_SUM_56 = + poseidon2_perm_A_56_0 + poseidon2_perm_A_56_1 + poseidon2_perm_A_56_2 + poseidon2_perm_A_56_3; + const auto poseidon2_perm_ARK_57_0 = new_term.poseidon2_perm_B_56_0 + poseidon2_params_C_57_0; + const auto poseidon2_perm_ARK_57_1 = new_term.poseidon2_perm_B_56_1 + poseidon2_params_C_57_1; + const auto poseidon2_perm_ARK_57_2 = new_term.poseidon2_perm_B_56_2 + poseidon2_params_C_57_2; + const auto poseidon2_perm_ARK_57_3 = new_term.poseidon2_perm_B_56_3 + poseidon2_params_C_57_3; + const auto poseidon2_perm_A_57_0 = poseidon2_perm_ARK_57_0 * poseidon2_perm_ARK_57_0 * poseidon2_perm_ARK_57_0 * + poseidon2_perm_ARK_57_0 * poseidon2_perm_ARK_57_0; + const auto poseidon2_perm_A_57_1 = poseidon2_perm_ARK_57_1; + const auto poseidon2_perm_A_57_2 = poseidon2_perm_ARK_57_2; + const auto poseidon2_perm_A_57_3 = poseidon2_perm_ARK_57_3; + const auto poseidon2_perm_SUM_57 = + poseidon2_perm_A_57_0 + poseidon2_perm_A_57_1 + poseidon2_perm_A_57_2 + poseidon2_perm_A_57_3; + const auto poseidon2_perm_ARK_58_0 = new_term.poseidon2_perm_B_57_0 + poseidon2_params_C_58_0; + const auto poseidon2_perm_ARK_58_1 = new_term.poseidon2_perm_B_57_1 + poseidon2_params_C_58_1; + const auto poseidon2_perm_ARK_58_2 = new_term.poseidon2_perm_B_57_2 + poseidon2_params_C_58_2; + const auto poseidon2_perm_ARK_58_3 = new_term.poseidon2_perm_B_57_3 + poseidon2_params_C_58_3; + const auto poseidon2_perm_A_58_0 = poseidon2_perm_ARK_58_0 * poseidon2_perm_ARK_58_0 * poseidon2_perm_ARK_58_0 * + poseidon2_perm_ARK_58_0 * poseidon2_perm_ARK_58_0; + const auto poseidon2_perm_A_58_1 = poseidon2_perm_ARK_58_1; + const auto poseidon2_perm_A_58_2 = poseidon2_perm_ARK_58_2; + const auto poseidon2_perm_A_58_3 = poseidon2_perm_ARK_58_3; + const auto poseidon2_perm_SUM_58 = + poseidon2_perm_A_58_0 + poseidon2_perm_A_58_1 + poseidon2_perm_A_58_2 + poseidon2_perm_A_58_3; + const auto poseidon2_perm_ARK_59_0 = new_term.poseidon2_perm_B_58_0 + poseidon2_params_C_59_0; + const auto poseidon2_perm_ARK_59_1 = new_term.poseidon2_perm_B_58_1 + poseidon2_params_C_59_1; + const auto poseidon2_perm_ARK_59_2 = new_term.poseidon2_perm_B_58_2 + poseidon2_params_C_59_2; + const auto poseidon2_perm_ARK_59_3 = new_term.poseidon2_perm_B_58_3 + poseidon2_params_C_59_3; + const auto poseidon2_perm_A_59_0 = poseidon2_perm_ARK_59_0 * poseidon2_perm_ARK_59_0 * poseidon2_perm_ARK_59_0 * + poseidon2_perm_ARK_59_0 * poseidon2_perm_ARK_59_0; + const auto poseidon2_perm_A_59_1 = poseidon2_perm_ARK_59_1; + const auto poseidon2_perm_A_59_2 = poseidon2_perm_ARK_59_2; + const auto poseidon2_perm_A_59_3 = poseidon2_perm_ARK_59_3; + const auto poseidon2_perm_SUM_59 = + poseidon2_perm_A_59_0 + poseidon2_perm_A_59_1 + poseidon2_perm_A_59_2 + poseidon2_perm_A_59_3; + const auto poseidon2_perm_ARK_60_0 = new_term.poseidon2_perm_B_59_0 + poseidon2_params_C_60_0; + const auto poseidon2_perm_ARK_60_1 = new_term.poseidon2_perm_B_59_1 + poseidon2_params_C_60_1; + const auto poseidon2_perm_ARK_60_2 = new_term.poseidon2_perm_B_59_2 + poseidon2_params_C_60_2; + const auto poseidon2_perm_ARK_60_3 = new_term.poseidon2_perm_B_59_3 + poseidon2_params_C_60_3; + const auto poseidon2_perm_A_60_0 = poseidon2_perm_ARK_60_0 * poseidon2_perm_ARK_60_0 * poseidon2_perm_ARK_60_0 * + poseidon2_perm_ARK_60_0 * poseidon2_perm_ARK_60_0; + const auto poseidon2_perm_A_60_1 = poseidon2_perm_ARK_60_1 * poseidon2_perm_ARK_60_1 * poseidon2_perm_ARK_60_1 * + poseidon2_perm_ARK_60_1 * poseidon2_perm_ARK_60_1; + const auto poseidon2_perm_A_60_2 = poseidon2_perm_ARK_60_2 * poseidon2_perm_ARK_60_2 * poseidon2_perm_ARK_60_2 * + poseidon2_perm_ARK_60_2 * poseidon2_perm_ARK_60_2; + const auto poseidon2_perm_A_60_3 = poseidon2_perm_ARK_60_3 * poseidon2_perm_ARK_60_3 * poseidon2_perm_ARK_60_3 * + poseidon2_perm_ARK_60_3 * poseidon2_perm_ARK_60_3; + const auto poseidon2_perm_T_60_0 = poseidon2_perm_A_60_0 + poseidon2_perm_A_60_1; + const auto poseidon2_perm_T_60_1 = poseidon2_perm_A_60_2 + poseidon2_perm_A_60_3; + const auto poseidon2_perm_T_60_2 = FF(2) * poseidon2_perm_A_60_1 + poseidon2_perm_T_60_1; + const auto poseidon2_perm_T_60_3 = FF(2) * poseidon2_perm_A_60_3 + poseidon2_perm_T_60_0; + const auto poseidon2_perm_ARK_61_0 = new_term.poseidon2_perm_T_60_6 + poseidon2_params_C_61_0; + const auto poseidon2_perm_ARK_61_1 = new_term.poseidon2_perm_T_60_5 + poseidon2_params_C_61_1; + const auto poseidon2_perm_ARK_61_2 = new_term.poseidon2_perm_T_60_7 + poseidon2_params_C_61_2; + const auto poseidon2_perm_ARK_61_3 = new_term.poseidon2_perm_T_60_4 + poseidon2_params_C_61_3; + const auto poseidon2_perm_A_61_0 = poseidon2_perm_ARK_61_0 * poseidon2_perm_ARK_61_0 * poseidon2_perm_ARK_61_0 * + poseidon2_perm_ARK_61_0 * poseidon2_perm_ARK_61_0; + const auto poseidon2_perm_A_61_1 = poseidon2_perm_ARK_61_1 * poseidon2_perm_ARK_61_1 * poseidon2_perm_ARK_61_1 * + poseidon2_perm_ARK_61_1 * poseidon2_perm_ARK_61_1; + const auto poseidon2_perm_A_61_2 = poseidon2_perm_ARK_61_2 * poseidon2_perm_ARK_61_2 * poseidon2_perm_ARK_61_2 * + poseidon2_perm_ARK_61_2 * poseidon2_perm_ARK_61_2; + const auto poseidon2_perm_A_61_3 = poseidon2_perm_ARK_61_3 * poseidon2_perm_ARK_61_3 * poseidon2_perm_ARK_61_3 * + poseidon2_perm_ARK_61_3 * poseidon2_perm_ARK_61_3; + const auto poseidon2_perm_T_61_0 = poseidon2_perm_A_61_0 + poseidon2_perm_A_61_1; + const auto poseidon2_perm_T_61_1 = poseidon2_perm_A_61_2 + poseidon2_perm_A_61_3; + const auto poseidon2_perm_T_61_2 = FF(2) * poseidon2_perm_A_61_1 + poseidon2_perm_T_61_1; + const auto poseidon2_perm_T_61_3 = FF(2) * poseidon2_perm_A_61_3 + poseidon2_perm_T_61_0; + const auto poseidon2_perm_ARK_62_0 = new_term.poseidon2_perm_T_61_6 + poseidon2_params_C_62_0; + const auto poseidon2_perm_ARK_62_1 = new_term.poseidon2_perm_T_61_5 + poseidon2_params_C_62_1; + const auto poseidon2_perm_ARK_62_2 = new_term.poseidon2_perm_T_61_7 + poseidon2_params_C_62_2; + const auto poseidon2_perm_ARK_62_3 = new_term.poseidon2_perm_T_61_4 + poseidon2_params_C_62_3; + const auto poseidon2_perm_A_62_0 = poseidon2_perm_ARK_62_0 * poseidon2_perm_ARK_62_0 * poseidon2_perm_ARK_62_0 * + poseidon2_perm_ARK_62_0 * poseidon2_perm_ARK_62_0; + const auto poseidon2_perm_A_62_1 = poseidon2_perm_ARK_62_1 * poseidon2_perm_ARK_62_1 * poseidon2_perm_ARK_62_1 * + poseidon2_perm_ARK_62_1 * poseidon2_perm_ARK_62_1; + const auto poseidon2_perm_A_62_2 = poseidon2_perm_ARK_62_2 * poseidon2_perm_ARK_62_2 * poseidon2_perm_ARK_62_2 * + poseidon2_perm_ARK_62_2 * poseidon2_perm_ARK_62_2; + const auto poseidon2_perm_A_62_3 = poseidon2_perm_ARK_62_3 * poseidon2_perm_ARK_62_3 * poseidon2_perm_ARK_62_3 * + poseidon2_perm_ARK_62_3 * poseidon2_perm_ARK_62_3; + const auto poseidon2_perm_T_62_0 = poseidon2_perm_A_62_0 + poseidon2_perm_A_62_1; + const auto poseidon2_perm_T_62_1 = poseidon2_perm_A_62_2 + poseidon2_perm_A_62_3; + const auto poseidon2_perm_T_62_2 = FF(2) * poseidon2_perm_A_62_1 + poseidon2_perm_T_62_1; + const auto poseidon2_perm_T_62_3 = FF(2) * poseidon2_perm_A_62_3 + poseidon2_perm_T_62_0; + const auto poseidon2_perm_ARK_63_0 = new_term.poseidon2_perm_T_62_6 + poseidon2_params_C_63_0; + const auto poseidon2_perm_ARK_63_1 = new_term.poseidon2_perm_T_62_5 + poseidon2_params_C_63_1; + const auto poseidon2_perm_ARK_63_2 = new_term.poseidon2_perm_T_62_7 + poseidon2_params_C_63_2; + const auto poseidon2_perm_ARK_63_3 = new_term.poseidon2_perm_T_62_4 + poseidon2_params_C_63_3; + const auto poseidon2_perm_A_63_0 = poseidon2_perm_ARK_63_0 * poseidon2_perm_ARK_63_0 * poseidon2_perm_ARK_63_0 * + poseidon2_perm_ARK_63_0 * poseidon2_perm_ARK_63_0; + const auto poseidon2_perm_A_63_1 = poseidon2_perm_ARK_63_1 * poseidon2_perm_ARK_63_1 * poseidon2_perm_ARK_63_1 * + poseidon2_perm_ARK_63_1 * poseidon2_perm_ARK_63_1; + const auto poseidon2_perm_A_63_2 = poseidon2_perm_ARK_63_2 * poseidon2_perm_ARK_63_2 * poseidon2_perm_ARK_63_2 * + poseidon2_perm_ARK_63_2 * poseidon2_perm_ARK_63_2; + const auto poseidon2_perm_A_63_3 = poseidon2_perm_ARK_63_3 * poseidon2_perm_ARK_63_3 * poseidon2_perm_ARK_63_3 * + poseidon2_perm_ARK_63_3 * poseidon2_perm_ARK_63_3; + const auto poseidon2_perm_T_63_0 = poseidon2_perm_A_63_0 + poseidon2_perm_A_63_1; + const auto poseidon2_perm_T_63_1 = poseidon2_perm_A_63_2 + poseidon2_perm_A_63_3; + const auto poseidon2_perm_T_63_2 = FF(2) * poseidon2_perm_A_63_1 + poseidon2_perm_T_63_1; + const auto poseidon2_perm_T_63_3 = FF(2) * poseidon2_perm_A_63_3 + poseidon2_perm_T_63_0; + + { + using Accumulator = typename std::tuple_element_t<0, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * (FF(1) - new_term.poseidon2_perm_sel); + tmp *= scaling_factor; + std::get<0>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<1, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_EXT_LAYER_4 - + (FF(4) * poseidon2_perm_EXT_LAYER_1 + poseidon2_perm_EXT_LAYER_3)); + tmp *= scaling_factor; + std::get<1>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<2, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_EXT_LAYER_5 - + (FF(4) * poseidon2_perm_EXT_LAYER_0 + poseidon2_perm_EXT_LAYER_2)); + tmp *= scaling_factor; + std::get<2>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<3, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_EXT_LAYER_6 - + (poseidon2_perm_EXT_LAYER_3 + new_term.poseidon2_perm_EXT_LAYER_5)); + tmp *= scaling_factor; + std::get<3>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<4, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_EXT_LAYER_7 - + (poseidon2_perm_EXT_LAYER_2 + new_term.poseidon2_perm_EXT_LAYER_4)); + tmp *= scaling_factor; + std::get<4>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<5, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_T_0_4 - (FF(4) * poseidon2_perm_T_0_1 + poseidon2_perm_T_0_3)); + tmp *= scaling_factor; + std::get<5>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<6, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_T_0_5 - (FF(4) * poseidon2_perm_T_0_0 + poseidon2_perm_T_0_2)); + tmp *= scaling_factor; + std::get<6>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<7, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_T_0_6 - (poseidon2_perm_T_0_3 + new_term.poseidon2_perm_T_0_5)); + tmp *= scaling_factor; + std::get<7>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<8, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_T_0_7 - (poseidon2_perm_T_0_2 + new_term.poseidon2_perm_T_0_4)); + tmp *= scaling_factor; + std::get<8>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<9, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_T_1_4 - (FF(4) * poseidon2_perm_T_1_1 + poseidon2_perm_T_1_3)); + tmp *= scaling_factor; + std::get<9>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<10, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_T_1_5 - (FF(4) * poseidon2_perm_T_1_0 + poseidon2_perm_T_1_2)); + tmp *= scaling_factor; + std::get<10>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<11, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_T_1_6 - (poseidon2_perm_T_1_3 + new_term.poseidon2_perm_T_1_5)); + tmp *= scaling_factor; + std::get<11>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<12, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_T_1_7 - (poseidon2_perm_T_1_2 + new_term.poseidon2_perm_T_1_4)); + tmp *= scaling_factor; + std::get<12>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<13, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_T_2_4 - (FF(4) * poseidon2_perm_T_2_1 + poseidon2_perm_T_2_3)); + tmp *= scaling_factor; + std::get<13>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<14, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_T_2_5 - (FF(4) * poseidon2_perm_T_2_0 + poseidon2_perm_T_2_2)); + tmp *= scaling_factor; + std::get<14>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<15, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_T_2_6 - (poseidon2_perm_T_2_3 + new_term.poseidon2_perm_T_2_5)); + tmp *= scaling_factor; + std::get<15>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<16, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_T_2_7 - (poseidon2_perm_T_2_2 + new_term.poseidon2_perm_T_2_4)); + tmp *= scaling_factor; + std::get<16>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<17, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_T_3_4 - (FF(4) * poseidon2_perm_T_3_1 + poseidon2_perm_T_3_3)); + tmp *= scaling_factor; + std::get<17>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<18, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_T_3_5 - (FF(4) * poseidon2_perm_T_3_0 + poseidon2_perm_T_3_2)); + tmp *= scaling_factor; + std::get<18>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<19, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_T_3_6 - (poseidon2_perm_T_3_3 + new_term.poseidon2_perm_T_3_5)); + tmp *= scaling_factor; + std::get<19>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<20, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_T_3_7 - (poseidon2_perm_T_3_2 + new_term.poseidon2_perm_T_3_4)); + tmp *= scaling_factor; + std::get<20>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<21, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_B_4_0 - (poseidon2_params_MU_0 * poseidon2_perm_A_4_0 + poseidon2_perm_SUM_4)); + tmp *= scaling_factor; + std::get<21>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<22, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_B_4_1 - (poseidon2_params_MU_1 * poseidon2_perm_A_4_1 + poseidon2_perm_SUM_4)); + tmp *= scaling_factor; + std::get<22>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<23, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_B_4_2 - (poseidon2_params_MU_2 * poseidon2_perm_A_4_2 + poseidon2_perm_SUM_4)); + tmp *= scaling_factor; + std::get<23>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<24, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_B_4_3 - (poseidon2_params_MU_3 * poseidon2_perm_A_4_3 + poseidon2_perm_SUM_4)); + tmp *= scaling_factor; + std::get<24>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<25, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_B_5_0 - (poseidon2_params_MU_0 * poseidon2_perm_A_5_0 + poseidon2_perm_SUM_5)); + tmp *= scaling_factor; + std::get<25>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<26, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_B_5_1 - (poseidon2_params_MU_1 * poseidon2_perm_A_5_1 + poseidon2_perm_SUM_5)); + tmp *= scaling_factor; + std::get<26>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<27, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_B_5_2 - (poseidon2_params_MU_2 * poseidon2_perm_A_5_2 + poseidon2_perm_SUM_5)); + tmp *= scaling_factor; + std::get<27>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<28, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_B_5_3 - (poseidon2_params_MU_3 * poseidon2_perm_A_5_3 + poseidon2_perm_SUM_5)); + tmp *= scaling_factor; + std::get<28>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<29, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_B_6_0 - (poseidon2_params_MU_0 * poseidon2_perm_A_6_0 + poseidon2_perm_SUM_6)); + tmp *= scaling_factor; + std::get<29>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<30, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_B_6_1 - (poseidon2_params_MU_1 * poseidon2_perm_A_6_1 + poseidon2_perm_SUM_6)); + tmp *= scaling_factor; + std::get<30>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<31, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_B_6_2 - (poseidon2_params_MU_2 * poseidon2_perm_A_6_2 + poseidon2_perm_SUM_6)); + tmp *= scaling_factor; + std::get<31>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<32, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_B_6_3 - (poseidon2_params_MU_3 * poseidon2_perm_A_6_3 + poseidon2_perm_SUM_6)); + tmp *= scaling_factor; + std::get<32>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<33, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_B_7_0 - (poseidon2_params_MU_0 * poseidon2_perm_A_7_0 + poseidon2_perm_SUM_7)); + tmp *= scaling_factor; + std::get<33>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<34, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_B_7_1 - (poseidon2_params_MU_1 * poseidon2_perm_A_7_1 + poseidon2_perm_SUM_7)); + tmp *= scaling_factor; + std::get<34>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<35, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_B_7_2 - (poseidon2_params_MU_2 * poseidon2_perm_A_7_2 + poseidon2_perm_SUM_7)); + tmp *= scaling_factor; + std::get<35>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<36, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_B_7_3 - (poseidon2_params_MU_3 * poseidon2_perm_A_7_3 + poseidon2_perm_SUM_7)); + tmp *= scaling_factor; + std::get<36>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<37, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_B_8_0 - (poseidon2_params_MU_0 * poseidon2_perm_A_8_0 + poseidon2_perm_SUM_8)); + tmp *= scaling_factor; + std::get<37>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<38, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_B_8_1 - (poseidon2_params_MU_1 * poseidon2_perm_A_8_1 + poseidon2_perm_SUM_8)); + tmp *= scaling_factor; + std::get<38>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<39, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_B_8_2 - (poseidon2_params_MU_2 * poseidon2_perm_A_8_2 + poseidon2_perm_SUM_8)); + tmp *= scaling_factor; + std::get<39>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<40, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_B_8_3 - (poseidon2_params_MU_3 * poseidon2_perm_A_8_3 + poseidon2_perm_SUM_8)); + tmp *= scaling_factor; + std::get<40>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<41, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_B_9_0 - (poseidon2_params_MU_0 * poseidon2_perm_A_9_0 + poseidon2_perm_SUM_9)); + tmp *= scaling_factor; + std::get<41>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<42, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_B_9_1 - (poseidon2_params_MU_1 * poseidon2_perm_A_9_1 + poseidon2_perm_SUM_9)); + tmp *= scaling_factor; + std::get<42>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<43, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_B_9_2 - (poseidon2_params_MU_2 * poseidon2_perm_A_9_2 + poseidon2_perm_SUM_9)); + tmp *= scaling_factor; + std::get<43>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<44, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_B_9_3 - (poseidon2_params_MU_3 * poseidon2_perm_A_9_3 + poseidon2_perm_SUM_9)); + tmp *= scaling_factor; + std::get<44>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<45, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_10_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_10_0 + poseidon2_perm_SUM_10)); + tmp *= scaling_factor; + std::get<45>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<46, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_10_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_10_1 + poseidon2_perm_SUM_10)); + tmp *= scaling_factor; + std::get<46>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<47, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_10_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_10_2 + poseidon2_perm_SUM_10)); + tmp *= scaling_factor; + std::get<47>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<48, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_10_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_10_3 + poseidon2_perm_SUM_10)); + tmp *= scaling_factor; + std::get<48>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<49, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_11_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_11_0 + poseidon2_perm_SUM_11)); + tmp *= scaling_factor; + std::get<49>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<50, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_11_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_11_1 + poseidon2_perm_SUM_11)); + tmp *= scaling_factor; + std::get<50>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<51, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_11_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_11_2 + poseidon2_perm_SUM_11)); + tmp *= scaling_factor; + std::get<51>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<52, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_11_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_11_3 + poseidon2_perm_SUM_11)); + tmp *= scaling_factor; + std::get<52>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<53, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_12_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_12_0 + poseidon2_perm_SUM_12)); + tmp *= scaling_factor; + std::get<53>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<54, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_12_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_12_1 + poseidon2_perm_SUM_12)); + tmp *= scaling_factor; + std::get<54>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<55, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_12_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_12_2 + poseidon2_perm_SUM_12)); + tmp *= scaling_factor; + std::get<55>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<56, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_12_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_12_3 + poseidon2_perm_SUM_12)); + tmp *= scaling_factor; + std::get<56>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<57, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_13_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_13_0 + poseidon2_perm_SUM_13)); + tmp *= scaling_factor; + std::get<57>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<58, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_13_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_13_1 + poseidon2_perm_SUM_13)); + tmp *= scaling_factor; + std::get<58>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<59, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_13_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_13_2 + poseidon2_perm_SUM_13)); + tmp *= scaling_factor; + std::get<59>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<60, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_13_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_13_3 + poseidon2_perm_SUM_13)); + tmp *= scaling_factor; + std::get<60>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<61, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_14_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_14_0 + poseidon2_perm_SUM_14)); + tmp *= scaling_factor; + std::get<61>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<62, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_14_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_14_1 + poseidon2_perm_SUM_14)); + tmp *= scaling_factor; + std::get<62>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<63, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_14_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_14_2 + poseidon2_perm_SUM_14)); + tmp *= scaling_factor; + std::get<63>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<64, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_14_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_14_3 + poseidon2_perm_SUM_14)); + tmp *= scaling_factor; + std::get<64>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<65, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_15_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_15_0 + poseidon2_perm_SUM_15)); + tmp *= scaling_factor; + std::get<65>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<66, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_15_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_15_1 + poseidon2_perm_SUM_15)); + tmp *= scaling_factor; + std::get<66>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<67, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_15_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_15_2 + poseidon2_perm_SUM_15)); + tmp *= scaling_factor; + std::get<67>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<68, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_15_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_15_3 + poseidon2_perm_SUM_15)); + tmp *= scaling_factor; + std::get<68>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<69, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_16_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_16_0 + poseidon2_perm_SUM_16)); + tmp *= scaling_factor; + std::get<69>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<70, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_16_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_16_1 + poseidon2_perm_SUM_16)); + tmp *= scaling_factor; + std::get<70>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<71, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_16_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_16_2 + poseidon2_perm_SUM_16)); + tmp *= scaling_factor; + std::get<71>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<72, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_16_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_16_3 + poseidon2_perm_SUM_16)); + tmp *= scaling_factor; + std::get<72>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<73, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_17_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_17_0 + poseidon2_perm_SUM_17)); + tmp *= scaling_factor; + std::get<73>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<74, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_17_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_17_1 + poseidon2_perm_SUM_17)); + tmp *= scaling_factor; + std::get<74>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<75, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_17_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_17_2 + poseidon2_perm_SUM_17)); + tmp *= scaling_factor; + std::get<75>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<76, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_17_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_17_3 + poseidon2_perm_SUM_17)); + tmp *= scaling_factor; + std::get<76>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<77, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_18_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_18_0 + poseidon2_perm_SUM_18)); + tmp *= scaling_factor; + std::get<77>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<78, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_18_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_18_1 + poseidon2_perm_SUM_18)); + tmp *= scaling_factor; + std::get<78>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<79, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_18_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_18_2 + poseidon2_perm_SUM_18)); + tmp *= scaling_factor; + std::get<79>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<80, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_18_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_18_3 + poseidon2_perm_SUM_18)); + tmp *= scaling_factor; + std::get<80>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<81, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_19_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_19_0 + poseidon2_perm_SUM_19)); + tmp *= scaling_factor; + std::get<81>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<82, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_19_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_19_1 + poseidon2_perm_SUM_19)); + tmp *= scaling_factor; + std::get<82>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<83, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_19_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_19_2 + poseidon2_perm_SUM_19)); + tmp *= scaling_factor; + std::get<83>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<84, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_19_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_19_3 + poseidon2_perm_SUM_19)); + tmp *= scaling_factor; + std::get<84>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<85, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_20_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_20_0 + poseidon2_perm_SUM_20)); + tmp *= scaling_factor; + std::get<85>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<86, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_20_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_20_1 + poseidon2_perm_SUM_20)); + tmp *= scaling_factor; + std::get<86>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<87, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_20_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_20_2 + poseidon2_perm_SUM_20)); + tmp *= scaling_factor; + std::get<87>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<88, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_20_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_20_3 + poseidon2_perm_SUM_20)); + tmp *= scaling_factor; + std::get<88>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<89, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_21_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_21_0 + poseidon2_perm_SUM_21)); + tmp *= scaling_factor; + std::get<89>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<90, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_21_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_21_1 + poseidon2_perm_SUM_21)); + tmp *= scaling_factor; + std::get<90>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<91, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_21_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_21_2 + poseidon2_perm_SUM_21)); + tmp *= scaling_factor; + std::get<91>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<92, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_21_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_21_3 + poseidon2_perm_SUM_21)); + tmp *= scaling_factor; + std::get<92>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<93, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_22_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_22_0 + poseidon2_perm_SUM_22)); + tmp *= scaling_factor; + std::get<93>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<94, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_22_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_22_1 + poseidon2_perm_SUM_22)); + tmp *= scaling_factor; + std::get<94>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<95, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_22_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_22_2 + poseidon2_perm_SUM_22)); + tmp *= scaling_factor; + std::get<95>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<96, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_22_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_22_3 + poseidon2_perm_SUM_22)); + tmp *= scaling_factor; + std::get<96>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<97, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_23_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_23_0 + poseidon2_perm_SUM_23)); + tmp *= scaling_factor; + std::get<97>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<98, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_23_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_23_1 + poseidon2_perm_SUM_23)); + tmp *= scaling_factor; + std::get<98>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<99, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_23_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_23_2 + poseidon2_perm_SUM_23)); + tmp *= scaling_factor; + std::get<99>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<100, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_23_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_23_3 + poseidon2_perm_SUM_23)); + tmp *= scaling_factor; + std::get<100>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<101, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_24_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_24_0 + poseidon2_perm_SUM_24)); + tmp *= scaling_factor; + std::get<101>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<102, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_24_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_24_1 + poseidon2_perm_SUM_24)); + tmp *= scaling_factor; + std::get<102>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<103, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_24_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_24_2 + poseidon2_perm_SUM_24)); + tmp *= scaling_factor; + std::get<103>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<104, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_24_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_24_3 + poseidon2_perm_SUM_24)); + tmp *= scaling_factor; + std::get<104>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<105, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_25_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_25_0 + poseidon2_perm_SUM_25)); + tmp *= scaling_factor; + std::get<105>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<106, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_25_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_25_1 + poseidon2_perm_SUM_25)); + tmp *= scaling_factor; + std::get<106>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<107, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_25_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_25_2 + poseidon2_perm_SUM_25)); + tmp *= scaling_factor; + std::get<107>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<108, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_25_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_25_3 + poseidon2_perm_SUM_25)); + tmp *= scaling_factor; + std::get<108>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<109, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_26_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_26_0 + poseidon2_perm_SUM_26)); + tmp *= scaling_factor; + std::get<109>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<110, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_26_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_26_1 + poseidon2_perm_SUM_26)); + tmp *= scaling_factor; + std::get<110>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<111, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_26_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_26_2 + poseidon2_perm_SUM_26)); + tmp *= scaling_factor; + std::get<111>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<112, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_26_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_26_3 + poseidon2_perm_SUM_26)); + tmp *= scaling_factor; + std::get<112>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<113, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_27_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_27_0 + poseidon2_perm_SUM_27)); + tmp *= scaling_factor; + std::get<113>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<114, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_27_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_27_1 + poseidon2_perm_SUM_27)); + tmp *= scaling_factor; + std::get<114>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<115, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_27_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_27_2 + poseidon2_perm_SUM_27)); + tmp *= scaling_factor; + std::get<115>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<116, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_27_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_27_3 + poseidon2_perm_SUM_27)); + tmp *= scaling_factor; + std::get<116>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<117, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_28_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_28_0 + poseidon2_perm_SUM_28)); + tmp *= scaling_factor; + std::get<117>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<118, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_28_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_28_1 + poseidon2_perm_SUM_28)); + tmp *= scaling_factor; + std::get<118>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<119, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_28_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_28_2 + poseidon2_perm_SUM_28)); + tmp *= scaling_factor; + std::get<119>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<120, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_28_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_28_3 + poseidon2_perm_SUM_28)); + tmp *= scaling_factor; + std::get<120>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<121, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_29_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_29_0 + poseidon2_perm_SUM_29)); + tmp *= scaling_factor; + std::get<121>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<122, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_29_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_29_1 + poseidon2_perm_SUM_29)); + tmp *= scaling_factor; + std::get<122>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<123, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_29_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_29_2 + poseidon2_perm_SUM_29)); + tmp *= scaling_factor; + std::get<123>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<124, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_29_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_29_3 + poseidon2_perm_SUM_29)); + tmp *= scaling_factor; + std::get<124>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<125, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_30_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_30_0 + poseidon2_perm_SUM_30)); + tmp *= scaling_factor; + std::get<125>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<126, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_30_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_30_1 + poseidon2_perm_SUM_30)); + tmp *= scaling_factor; + std::get<126>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<127, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_30_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_30_2 + poseidon2_perm_SUM_30)); + tmp *= scaling_factor; + std::get<127>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<128, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_30_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_30_3 + poseidon2_perm_SUM_30)); + tmp *= scaling_factor; + std::get<128>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<129, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_31_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_31_0 + poseidon2_perm_SUM_31)); + tmp *= scaling_factor; + std::get<129>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<130, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_31_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_31_1 + poseidon2_perm_SUM_31)); + tmp *= scaling_factor; + std::get<130>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<131, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_31_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_31_2 + poseidon2_perm_SUM_31)); + tmp *= scaling_factor; + std::get<131>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<132, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_31_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_31_3 + poseidon2_perm_SUM_31)); + tmp *= scaling_factor; + std::get<132>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<133, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_32_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_32_0 + poseidon2_perm_SUM_32)); + tmp *= scaling_factor; + std::get<133>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<134, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_32_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_32_1 + poseidon2_perm_SUM_32)); + tmp *= scaling_factor; + std::get<134>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<135, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_32_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_32_2 + poseidon2_perm_SUM_32)); + tmp *= scaling_factor; + std::get<135>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<136, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_32_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_32_3 + poseidon2_perm_SUM_32)); + tmp *= scaling_factor; + std::get<136>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<137, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_33_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_33_0 + poseidon2_perm_SUM_33)); + tmp *= scaling_factor; + std::get<137>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<138, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_33_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_33_1 + poseidon2_perm_SUM_33)); + tmp *= scaling_factor; + std::get<138>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<139, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_33_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_33_2 + poseidon2_perm_SUM_33)); + tmp *= scaling_factor; + std::get<139>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<140, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_33_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_33_3 + poseidon2_perm_SUM_33)); + tmp *= scaling_factor; + std::get<140>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<141, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_34_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_34_0 + poseidon2_perm_SUM_34)); + tmp *= scaling_factor; + std::get<141>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<142, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_34_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_34_1 + poseidon2_perm_SUM_34)); + tmp *= scaling_factor; + std::get<142>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<143, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_34_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_34_2 + poseidon2_perm_SUM_34)); + tmp *= scaling_factor; + std::get<143>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<144, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_34_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_34_3 + poseidon2_perm_SUM_34)); + tmp *= scaling_factor; + std::get<144>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<145, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_35_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_35_0 + poseidon2_perm_SUM_35)); + tmp *= scaling_factor; + std::get<145>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<146, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_35_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_35_1 + poseidon2_perm_SUM_35)); + tmp *= scaling_factor; + std::get<146>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<147, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_35_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_35_2 + poseidon2_perm_SUM_35)); + tmp *= scaling_factor; + std::get<147>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<148, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_35_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_35_3 + poseidon2_perm_SUM_35)); + tmp *= scaling_factor; + std::get<148>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<149, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_36_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_36_0 + poseidon2_perm_SUM_36)); + tmp *= scaling_factor; + std::get<149>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<150, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_36_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_36_1 + poseidon2_perm_SUM_36)); + tmp *= scaling_factor; + std::get<150>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<151, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_36_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_36_2 + poseidon2_perm_SUM_36)); + tmp *= scaling_factor; + std::get<151>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<152, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_36_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_36_3 + poseidon2_perm_SUM_36)); + tmp *= scaling_factor; + std::get<152>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<153, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_37_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_37_0 + poseidon2_perm_SUM_37)); + tmp *= scaling_factor; + std::get<153>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<154, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_37_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_37_1 + poseidon2_perm_SUM_37)); + tmp *= scaling_factor; + std::get<154>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<155, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_37_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_37_2 + poseidon2_perm_SUM_37)); + tmp *= scaling_factor; + std::get<155>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<156, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_37_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_37_3 + poseidon2_perm_SUM_37)); + tmp *= scaling_factor; + std::get<156>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<157, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_38_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_38_0 + poseidon2_perm_SUM_38)); + tmp *= scaling_factor; + std::get<157>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<158, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_38_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_38_1 + poseidon2_perm_SUM_38)); + tmp *= scaling_factor; + std::get<158>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<159, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_38_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_38_2 + poseidon2_perm_SUM_38)); + tmp *= scaling_factor; + std::get<159>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<160, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_38_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_38_3 + poseidon2_perm_SUM_38)); + tmp *= scaling_factor; + std::get<160>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<161, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_39_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_39_0 + poseidon2_perm_SUM_39)); + tmp *= scaling_factor; + std::get<161>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<162, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_39_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_39_1 + poseidon2_perm_SUM_39)); + tmp *= scaling_factor; + std::get<162>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<163, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_39_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_39_2 + poseidon2_perm_SUM_39)); + tmp *= scaling_factor; + std::get<163>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<164, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_39_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_39_3 + poseidon2_perm_SUM_39)); + tmp *= scaling_factor; + std::get<164>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<165, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_40_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_40_0 + poseidon2_perm_SUM_40)); + tmp *= scaling_factor; + std::get<165>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<166, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_40_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_40_1 + poseidon2_perm_SUM_40)); + tmp *= scaling_factor; + std::get<166>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<167, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_40_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_40_2 + poseidon2_perm_SUM_40)); + tmp *= scaling_factor; + std::get<167>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<168, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_40_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_40_3 + poseidon2_perm_SUM_40)); + tmp *= scaling_factor; + std::get<168>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<169, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_41_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_41_0 + poseidon2_perm_SUM_41)); + tmp *= scaling_factor; + std::get<169>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<170, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_41_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_41_1 + poseidon2_perm_SUM_41)); + tmp *= scaling_factor; + std::get<170>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<171, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_41_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_41_2 + poseidon2_perm_SUM_41)); + tmp *= scaling_factor; + std::get<171>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<172, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_41_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_41_3 + poseidon2_perm_SUM_41)); + tmp *= scaling_factor; + std::get<172>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<173, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_42_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_42_0 + poseidon2_perm_SUM_42)); + tmp *= scaling_factor; + std::get<173>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<174, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_42_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_42_1 + poseidon2_perm_SUM_42)); + tmp *= scaling_factor; + std::get<174>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<175, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_42_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_42_2 + poseidon2_perm_SUM_42)); + tmp *= scaling_factor; + std::get<175>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<176, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_42_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_42_3 + poseidon2_perm_SUM_42)); + tmp *= scaling_factor; + std::get<176>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<177, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_43_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_43_0 + poseidon2_perm_SUM_43)); + tmp *= scaling_factor; + std::get<177>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<178, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_43_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_43_1 + poseidon2_perm_SUM_43)); + tmp *= scaling_factor; + std::get<178>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<179, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_43_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_43_2 + poseidon2_perm_SUM_43)); + tmp *= scaling_factor; + std::get<179>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<180, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_43_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_43_3 + poseidon2_perm_SUM_43)); + tmp *= scaling_factor; + std::get<180>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<181, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_44_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_44_0 + poseidon2_perm_SUM_44)); + tmp *= scaling_factor; + std::get<181>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<182, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_44_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_44_1 + poseidon2_perm_SUM_44)); + tmp *= scaling_factor; + std::get<182>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<183, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_44_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_44_2 + poseidon2_perm_SUM_44)); + tmp *= scaling_factor; + std::get<183>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<184, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_44_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_44_3 + poseidon2_perm_SUM_44)); + tmp *= scaling_factor; + std::get<184>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<185, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_45_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_45_0 + poseidon2_perm_SUM_45)); + tmp *= scaling_factor; + std::get<185>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<186, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_45_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_45_1 + poseidon2_perm_SUM_45)); + tmp *= scaling_factor; + std::get<186>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<187, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_45_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_45_2 + poseidon2_perm_SUM_45)); + tmp *= scaling_factor; + std::get<187>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<188, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_45_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_45_3 + poseidon2_perm_SUM_45)); + tmp *= scaling_factor; + std::get<188>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<189, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_46_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_46_0 + poseidon2_perm_SUM_46)); + tmp *= scaling_factor; + std::get<189>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<190, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_46_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_46_1 + poseidon2_perm_SUM_46)); + tmp *= scaling_factor; + std::get<190>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<191, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_46_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_46_2 + poseidon2_perm_SUM_46)); + tmp *= scaling_factor; + std::get<191>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<192, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_46_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_46_3 + poseidon2_perm_SUM_46)); + tmp *= scaling_factor; + std::get<192>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<193, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_47_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_47_0 + poseidon2_perm_SUM_47)); + tmp *= scaling_factor; + std::get<193>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<194, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_47_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_47_1 + poseidon2_perm_SUM_47)); + tmp *= scaling_factor; + std::get<194>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<195, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_47_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_47_2 + poseidon2_perm_SUM_47)); + tmp *= scaling_factor; + std::get<195>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<196, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_47_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_47_3 + poseidon2_perm_SUM_47)); + tmp *= scaling_factor; + std::get<196>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<197, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_48_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_48_0 + poseidon2_perm_SUM_48)); + tmp *= scaling_factor; + std::get<197>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<198, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_48_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_48_1 + poseidon2_perm_SUM_48)); + tmp *= scaling_factor; + std::get<198>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<199, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_48_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_48_2 + poseidon2_perm_SUM_48)); + tmp *= scaling_factor; + std::get<199>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<200, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_48_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_48_3 + poseidon2_perm_SUM_48)); + tmp *= scaling_factor; + std::get<200>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<201, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_49_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_49_0 + poseidon2_perm_SUM_49)); + tmp *= scaling_factor; + std::get<201>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<202, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_49_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_49_1 + poseidon2_perm_SUM_49)); + tmp *= scaling_factor; + std::get<202>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<203, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_49_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_49_2 + poseidon2_perm_SUM_49)); + tmp *= scaling_factor; + std::get<203>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<204, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_49_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_49_3 + poseidon2_perm_SUM_49)); + tmp *= scaling_factor; + std::get<204>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<205, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_50_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_50_0 + poseidon2_perm_SUM_50)); + tmp *= scaling_factor; + std::get<205>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<206, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_50_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_50_1 + poseidon2_perm_SUM_50)); + tmp *= scaling_factor; + std::get<206>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<207, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_50_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_50_2 + poseidon2_perm_SUM_50)); + tmp *= scaling_factor; + std::get<207>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<208, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_50_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_50_3 + poseidon2_perm_SUM_50)); + tmp *= scaling_factor; + std::get<208>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<209, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_51_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_51_0 + poseidon2_perm_SUM_51)); + tmp *= scaling_factor; + std::get<209>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<210, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_51_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_51_1 + poseidon2_perm_SUM_51)); + tmp *= scaling_factor; + std::get<210>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<211, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_51_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_51_2 + poseidon2_perm_SUM_51)); + tmp *= scaling_factor; + std::get<211>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<212, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_51_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_51_3 + poseidon2_perm_SUM_51)); + tmp *= scaling_factor; + std::get<212>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<213, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_52_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_52_0 + poseidon2_perm_SUM_52)); + tmp *= scaling_factor; + std::get<213>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<214, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_52_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_52_1 + poseidon2_perm_SUM_52)); + tmp *= scaling_factor; + std::get<214>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<215, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_52_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_52_2 + poseidon2_perm_SUM_52)); + tmp *= scaling_factor; + std::get<215>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<216, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_52_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_52_3 + poseidon2_perm_SUM_52)); + tmp *= scaling_factor; + std::get<216>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<217, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_53_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_53_0 + poseidon2_perm_SUM_53)); + tmp *= scaling_factor; + std::get<217>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<218, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_53_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_53_1 + poseidon2_perm_SUM_53)); + tmp *= scaling_factor; + std::get<218>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<219, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_53_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_53_2 + poseidon2_perm_SUM_53)); + tmp *= scaling_factor; + std::get<219>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<220, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_53_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_53_3 + poseidon2_perm_SUM_53)); + tmp *= scaling_factor; + std::get<220>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<221, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_54_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_54_0 + poseidon2_perm_SUM_54)); + tmp *= scaling_factor; + std::get<221>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<222, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_54_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_54_1 + poseidon2_perm_SUM_54)); + tmp *= scaling_factor; + std::get<222>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<223, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_54_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_54_2 + poseidon2_perm_SUM_54)); + tmp *= scaling_factor; + std::get<223>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<224, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_54_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_54_3 + poseidon2_perm_SUM_54)); + tmp *= scaling_factor; + std::get<224>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<225, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_55_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_55_0 + poseidon2_perm_SUM_55)); + tmp *= scaling_factor; + std::get<225>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<226, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_55_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_55_1 + poseidon2_perm_SUM_55)); + tmp *= scaling_factor; + std::get<226>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<227, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_55_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_55_2 + poseidon2_perm_SUM_55)); + tmp *= scaling_factor; + std::get<227>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<228, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_55_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_55_3 + poseidon2_perm_SUM_55)); + tmp *= scaling_factor; + std::get<228>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<229, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_56_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_56_0 + poseidon2_perm_SUM_56)); + tmp *= scaling_factor; + std::get<229>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<230, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_56_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_56_1 + poseidon2_perm_SUM_56)); + tmp *= scaling_factor; + std::get<230>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<231, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_56_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_56_2 + poseidon2_perm_SUM_56)); + tmp *= scaling_factor; + std::get<231>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<232, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_56_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_56_3 + poseidon2_perm_SUM_56)); + tmp *= scaling_factor; + std::get<232>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<233, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_57_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_57_0 + poseidon2_perm_SUM_57)); + tmp *= scaling_factor; + std::get<233>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<234, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_57_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_57_1 + poseidon2_perm_SUM_57)); + tmp *= scaling_factor; + std::get<234>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<235, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_57_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_57_2 + poseidon2_perm_SUM_57)); + tmp *= scaling_factor; + std::get<235>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<236, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_57_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_57_3 + poseidon2_perm_SUM_57)); + tmp *= scaling_factor; + std::get<236>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<237, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_58_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_58_0 + poseidon2_perm_SUM_58)); + tmp *= scaling_factor; + std::get<237>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<238, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_58_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_58_1 + poseidon2_perm_SUM_58)); + tmp *= scaling_factor; + std::get<238>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<239, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_58_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_58_2 + poseidon2_perm_SUM_58)); + tmp *= scaling_factor; + std::get<239>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<240, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_58_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_58_3 + poseidon2_perm_SUM_58)); + tmp *= scaling_factor; + std::get<240>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<241, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_59_0 - + (poseidon2_params_MU_0 * poseidon2_perm_A_59_0 + poseidon2_perm_SUM_59)); + tmp *= scaling_factor; + std::get<241>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<242, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_59_1 - + (poseidon2_params_MU_1 * poseidon2_perm_A_59_1 + poseidon2_perm_SUM_59)); + tmp *= scaling_factor; + std::get<242>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<243, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_59_2 - + (poseidon2_params_MU_2 * poseidon2_perm_A_59_2 + poseidon2_perm_SUM_59)); + tmp *= scaling_factor; + std::get<243>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<244, ContainerOverSubrelations>; + auto tmp = + new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_B_59_3 - + (poseidon2_params_MU_3 * poseidon2_perm_A_59_3 + poseidon2_perm_SUM_59)); + tmp *= scaling_factor; + std::get<244>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<245, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_T_60_4 - (FF(4) * poseidon2_perm_T_60_1 + poseidon2_perm_T_60_3)); + tmp *= scaling_factor; + std::get<245>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<246, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_T_60_5 - (FF(4) * poseidon2_perm_T_60_0 + poseidon2_perm_T_60_2)); + tmp *= scaling_factor; + std::get<246>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<247, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_T_60_6 - (poseidon2_perm_T_60_3 + new_term.poseidon2_perm_T_60_5)); + tmp *= scaling_factor; + std::get<247>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<248, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_T_60_7 - (poseidon2_perm_T_60_2 + new_term.poseidon2_perm_T_60_4)); + tmp *= scaling_factor; + std::get<248>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<249, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_T_61_4 - (FF(4) * poseidon2_perm_T_61_1 + poseidon2_perm_T_61_3)); + tmp *= scaling_factor; + std::get<249>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<250, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_T_61_5 - (FF(4) * poseidon2_perm_T_61_0 + poseidon2_perm_T_61_2)); + tmp *= scaling_factor; + std::get<250>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<251, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_T_61_6 - (poseidon2_perm_T_61_3 + new_term.poseidon2_perm_T_61_5)); + tmp *= scaling_factor; + std::get<251>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<252, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_T_61_7 - (poseidon2_perm_T_61_2 + new_term.poseidon2_perm_T_61_4)); + tmp *= scaling_factor; + std::get<252>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<253, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_T_62_4 - (FF(4) * poseidon2_perm_T_62_1 + poseidon2_perm_T_62_3)); + tmp *= scaling_factor; + std::get<253>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<254, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_T_62_5 - (FF(4) * poseidon2_perm_T_62_0 + poseidon2_perm_T_62_2)); + tmp *= scaling_factor; + std::get<254>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<255, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_T_62_6 - (poseidon2_perm_T_62_3 + new_term.poseidon2_perm_T_62_5)); + tmp *= scaling_factor; + std::get<255>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<256, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_T_62_7 - (poseidon2_perm_T_62_2 + new_term.poseidon2_perm_T_62_4)); + tmp *= scaling_factor; + std::get<256>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<257, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_T_63_4 - (FF(4) * poseidon2_perm_T_63_1 + poseidon2_perm_T_63_3)); + tmp *= scaling_factor; + std::get<257>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<258, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_T_63_5 - (FF(4) * poseidon2_perm_T_63_0 + poseidon2_perm_T_63_2)); + tmp *= scaling_factor; + std::get<258>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<259, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_T_63_6 - (poseidon2_perm_T_63_3 + new_term.poseidon2_perm_T_63_5)); + tmp *= scaling_factor; + std::get<259>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<260, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * + (new_term.poseidon2_perm_T_63_7 - (poseidon2_perm_T_63_2 + new_term.poseidon2_perm_T_63_4)); + tmp *= scaling_factor; + std::get<260>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<261, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_b_0 - new_term.poseidon2_perm_T_63_6); + tmp *= scaling_factor; + std::get<261>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<262, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_b_1 - new_term.poseidon2_perm_T_63_5); + tmp *= scaling_factor; + std::get<262>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<263, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_b_2 - new_term.poseidon2_perm_T_63_7); + tmp *= scaling_factor; + std::get<263>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<264, ContainerOverSubrelations>; + auto tmp = new_term.poseidon2_perm_sel * (new_term.poseidon2_perm_b_3 - new_term.poseidon2_perm_T_63_4); + tmp *= scaling_factor; + std::get<264>(evals) += typename Accumulator::View(tmp); + } + } +}; + +template class poseidon2_perm : public Relation> { + public: + static constexpr const std::string_view NAME = "poseidon2_perm"; + + static std::string get_subrelation_label(size_t index) + { + switch (index) {} + return std::to_string(index); + } +}; + +} // namespace bb::avm2 \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/events/events_container.hpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/events/events_container.hpp index f1585b274fc..b228dc9f491 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/events/events_container.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/events/events_container.hpp @@ -10,6 +10,7 @@ #include "barretenberg/vm2/simulation/events/event_emitter.hpp" #include "barretenberg/vm2/simulation/events/execution_event.hpp" #include "barretenberg/vm2/simulation/events/memory_event.hpp" +#include "barretenberg/vm2/simulation/events/poseidon2_event.hpp" #include "barretenberg/vm2/simulation/events/sha256_event.hpp" #include "barretenberg/vm2/simulation/events/siloing_event.hpp" @@ -30,6 +31,8 @@ struct EventsContainer { EventEmitterInterface::Container siloing; EventEmitterInterface::Container sha256_compression; EventEmitterInterface::Container ecc_add; + EventEmitterInterface::Container poseidon2_hash; + EventEmitterInterface::Container poseidon2_permutation; }; } // namespace bb::avm2::simulation diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/events/poseidon2_event.hpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/events/poseidon2_event.hpp new file mode 100644 index 00000000000..ee354dc8cb9 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/events/poseidon2_event.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include +#include + +#include "barretenberg/vm2/common/memory_types.hpp" +#include "barretenberg/vm2/common/opcodes.hpp" + +namespace bb::avm2::simulation { + +struct Poseidon2HashEvent { + std::vector inputs; // This input is padded to a multiple of 3 + std::vector> intermediate_states; + FF output; +}; + +struct Poseidon2PermutationEvent { + std::array input; + std::array output; +}; + +} // namespace bb::avm2::simulation diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/poseidon2.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/poseidon2.cpp new file mode 100644 index 00000000000..83aeddfc865 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/poseidon2.cpp @@ -0,0 +1,57 @@ +#include "barretenberg/vm2/simulation/poseidon2.hpp" + +#include +#include + +#include "barretenberg/crypto/poseidon2/poseidon2.hpp" +#include "barretenberg/crypto/poseidon2/poseidon2_permutation.hpp" + +using bb::crypto::Poseidon2Bn254ScalarFieldParams; +using bb::crypto::Poseidon2Permutation; + +namespace bb::avm2::simulation { + +FF Poseidon2::hash(const std::vector& input) +{ + size_t input_size = input.size(); + // The number of permutation events required to process the input + auto num_perm_events = (input_size / 3) + static_cast(input_size % 3 != 0); + std::vector> intermediate_states; + // We reserve space for the intermediate permutation states and 1 additional space for the initial state + intermediate_states.reserve(num_perm_events + 1); + + // The unpadded length of the input is set as the IV + // The initial permutation state is seeded with the iv at the last input index + const uint256_t iv = static_cast(input_size) << 64; + std::array perm_state = { 0, 0, 0, iv }; + intermediate_states.push_back(perm_state); + + // Also referred to as cache but is the inputs that will be passed to the permutation function + std::vector> perm_inputs; + + for (size_t i = 0; i < num_perm_events; i++) { + // We can at most absorb a chunk of 3 elements + size_t chunk_size = std::min(input_size, static_cast(3)); + // Mix the input chunk into the previous permutation output state + for (size_t j = 0; j < chunk_size; j++) { + perm_state[j] += input[(i * 3) + j]; + } + perm_state = permutation(perm_state); + intermediate_states.push_back(perm_state); + + input_size -= chunk_size; + } + + hash_events.emit( + { .inputs = input, .intermediate_states = std::move(intermediate_states), .output = perm_state[0] }); + return perm_state[0]; +} + +std::array Poseidon2::permutation(const std::array& input) +{ + std::array output = Poseidon2Permutation::permutation(input); + perm_events.emit({ .input = input, .output = output }); + return output; +} + +} // namespace bb::avm2::simulation diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/poseidon2.hpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/poseidon2.hpp new file mode 100644 index 00000000000..bc09ea308eb --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/poseidon2.hpp @@ -0,0 +1,35 @@ +#pragma once + +#include +#include +#include + +#include "barretenberg/vm2/simulation/events/event_emitter.hpp" +#include "barretenberg/vm2/simulation/events/poseidon2_event.hpp" + +namespace bb::avm2::simulation { + +class Poseidon2Interface { + public: + virtual ~Poseidon2Interface() = default; + virtual FF hash(const std::vector& input) = 0; + virtual std::array permutation(const std::array& input) = 0; +}; + +class Poseidon2 : public Poseidon2Interface { + public: + Poseidon2(EventEmitterInterface& hash_emitter, + EventEmitterInterface& perm_emitter) + : hash_events(hash_emitter) + , perm_events(perm_emitter) + {} + + FF hash(const std::vector& input) override; + std::array permutation(const std::array& input) override; + + private: + EventEmitterInterface& hash_events; + EventEmitterInterface& perm_events; +}; + +} // namespace bb::avm2::simulation diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/poseidon2.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/poseidon2.test.cpp new file mode 100644 index 00000000000..e3c92221d8a --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/poseidon2.test.cpp @@ -0,0 +1,94 @@ +#include "barretenberg/vm2/simulation/poseidon2.hpp" + +#include +#include + +#include "barretenberg/crypto/poseidon2/poseidon2.hpp" +#include "barretenberg/vm2/simulation/events/event_emitter.hpp" + +namespace bb::avm2::simulation { +namespace { + +using ::testing::_; +using ::testing::ElementsAre; +using ::testing::ElementsAreArray; +using ::testing::Field; + +TEST(AvmSimulationPoseidon2Test, Hash) +{ + EventEmitter hash_event_emitter; + EventEmitter perm_event_emitter; + Poseidon2 poseidon2(hash_event_emitter, perm_event_emitter); + + // Taken From barretenberg/crypto/poseidon2/poseidon2.test.cpp + FF a("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789"); + FF b("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789"); + FF c("0x9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789"); + FF d("0x9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789"); + + std::vector input = { a, b, c, d }; + + FF result = poseidon2.hash(input); + FF expected("0x2f43a0f83b51a6f5fc839dea0ecec74947637802a579fa9841930a25a0bcec11"); + EXPECT_EQ(result, expected); + + std::vector event_result = hash_event_emitter.dump_events(); + + EXPECT_THAT(event_result, + ElementsAre(testing::AllOf(Field(&Poseidon2HashEvent::inputs, ElementsAreArray(input)), + Field(&Poseidon2HashEvent::intermediate_states, _), + Field(&Poseidon2HashEvent::output, expected)))); +} + +TEST(AvmSimulationPoseidon2Test, Permutation) +{ + EventEmitter hash_event_emitter; + EventEmitter perm_event_emitter; + Poseidon2 poseidon2(hash_event_emitter, perm_event_emitter); + + // Taken From barretenberg/crypto/poseidon2/poseidon2.test.cpp + FF a("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789"); + FF b("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789"); + FF c("0x9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789"); + FF d("0x9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789"); + + std::array input = { a, b, c, d }; + auto result = poseidon2.permutation(input); + + std::array expected = { + FF("0x2bf1eaf87f7d27e8dc4056e9af975985bccc89077a21891d6c7b6ccce0631f95"), + FF("0x0c01fa1b8d0748becafbe452c0cb0231c38224ea824554c9362518eebdd5701f"), + FF("0x018555a8eb50cf07f64b019ebaf3af3c925c93e631f3ecd455db07bbb52bbdd3"), + FF("0x0cbea457c91c22c6c31fd89afd2541efc2edf31736b9f721e823b2165c90fd41"), + }; + EXPECT_THAT(result, ElementsAreArray(expected)); + + std::vector event_results = perm_event_emitter.dump_events(); + + EXPECT_THAT(event_results, + ElementsAre(AllOf(Field(&Poseidon2PermutationEvent::input, ElementsAreArray(input)), + Field(&Poseidon2PermutationEvent::output, ElementsAreArray(expected))))); +} + +// This test may seem redundant, but since we kind of re-implement the Poseidon2 sponge function, it's good to have it. +TEST(AvmSimulationPoseidon2Test, RandomHash) +{ + EventEmitter hash_event_emitter; + EventEmitter perm_event_emitter; + Poseidon2 poseidon2(hash_event_emitter, perm_event_emitter); + + std::vector input; + input.reserve(14); + + for (int i = 0; i < 14; i++) { + input.push_back(FF::random_element()); + } + + FF result = poseidon2.hash(input); + FF bb_result = crypto::Poseidon2::hash(input); + + EXPECT_EQ(result, bb_result); +} + +} // namespace +} // namespace bb::avm2::simulation diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/testing/mock_poseidon2.hpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/testing/mock_poseidon2.hpp new file mode 100644 index 00000000000..ee6e5ba9d76 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/testing/mock_poseidon2.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include +#include + +#include "barretenberg/vm2/simulation/poseidon2.hpp" + +namespace bb::avm2::simulation { + +class MockPoseidon2 : public Poseidon2Interface { + public: + MockPoseidon2(); + ~MockPoseidon2() override; + + MOCK_METHOD(FF, hash, (const std::vector& input), (override)); + MOCK_METHOD((std::array), permutation, ((const std::array)&input), (override)); +}; + +} // namespace bb::avm2::simulation diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/testing/mock_poseidon2.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/testing/mock_poseidon2.test.cpp new file mode 100644 index 00000000000..891325ef44a --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/testing/mock_poseidon2.test.cpp @@ -0,0 +1,9 @@ +// This is not a test file but we need to use .test.cpp so that it is not included in non-test builds. +#include "barretenberg/vm2/simulation/testing/mock_poseidon2.hpp" + +namespace bb::avm2::simulation { + +MockPoseidon2::MockPoseidon2() = default; +MockPoseidon2::~MockPoseidon2() = default; + +} // namespace bb::avm2::simulation diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation_helper.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation_helper.cpp index 654a0a911bb..8eac6544a44 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation_helper.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation_helper.cpp @@ -25,6 +25,7 @@ #include "barretenberg/vm2/simulation/execution.hpp" #include "barretenberg/vm2/simulation/lib/instruction_info.hpp" #include "barretenberg/vm2/simulation/lib/raw_data_db.hpp" +#include "barretenberg/vm2/simulation/poseidon2.hpp" #include "barretenberg/vm2/simulation/sha256.hpp" #include "barretenberg/vm2/simulation/siloing.hpp" #include "barretenberg/vm2/simulation/tx_execution.hpp" @@ -63,6 +64,8 @@ template EventsContainer AvmSimulationHelper::simulate_with_setting typename S::template DefaultEventEmitter siloing_emitter; typename S::template DefaultEventEmitter sha256_compression_emitter; typename S::template DefaultEventEmitter ecc_add_emitter; + typename S::template DefaultEventEmitter poseidon2_hash_emitter; + typename S::template DefaultEventEmitter poseidon2_perm_emitter; HintedRawDataDB db(inputs.hints); AddressDerivation address_derivation(address_derivation_emitter); @@ -87,6 +90,7 @@ template EventsContainer AvmSimulationHelper::simulate_with_setting TxExecution tx_execution(execution); Sha256 sha256(sha256_compression_emitter); Ecc ecc_add(ecc_add_emitter); + Poseidon2 poseidon2(poseidon2_hash_emitter, poseidon2_perm_emitter); tx_execution.simulate({ .enqueued_calls = inputs.enqueuedCalls }); @@ -103,7 +107,9 @@ template EventsContainer AvmSimulationHelper::simulate_with_setting class_id_derivation_emitter.dump_events(), siloing_emitter.dump_events(), sha256_compression_emitter.dump_events(), - ecc_add_emitter.dump_events() }; + ecc_add_emitter.dump_events(), + poseidon2_hash_emitter.dump_events(), + poseidon2_perm_emitter.dump_events() }; } EventsContainer AvmSimulationHelper::simulate() diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/lookup_builder.hpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/lookup_builder.hpp index 5e221f5b58d..ab093588866 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/lookup_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/lookup_builder.hpp @@ -22,6 +22,8 @@ template class BaseLookupTraceBuilder : public Intera { init(trace); + SetDummyInverses(trace); + // Let "src_sel {c1, c2, ...} in dst_sel {d1, d2, ...}" be a lookup, // For each row that has a 1 in the src_sel, we take the values of {c1, c2, ...}, // find a row dst_row in the target columns {d1, d2, ...} where the values match. @@ -35,8 +37,6 @@ template class BaseLookupTraceBuilder : public Intera uint32_t dst_row = find_in_dst(src_values); // Assumes an efficient implementation. trace.set(LookupSettings::COUNTS, dst_row, trace.get(LookupSettings::COUNTS, dst_row) + 1); }); - - SetDummyInverses(trace); } protected: @@ -104,6 +104,8 @@ template class LookupIntoDynamicTableSequential : publ uint32_t dst_row = 0; uint32_t max_dst_row = trace.get_column_rows(LookupSettings::DST_SELECTOR); + SetDummyInverses(trace); + trace.visit_column(LookupSettings::SRC_SELECTOR, [&](uint32_t row, const FF& src_sel_value) { assert(src_sel_value == 1); (void)src_sel_value; // Avoid GCC complaining of unused parameter when asserts are disabled. @@ -125,8 +127,6 @@ template class LookupIntoDynamicTableSequential : publ throw std::runtime_error("Failed computing counts for " + std::string(LookupSettings::NAME) + ". Could not find tuple in destination."); }); - - SetDummyInverses(trace); } }; @@ -143,4 +143,4 @@ template struct std::hash> { } return hash; } -}; \ No newline at end of file +}; diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/poseidon2_trace.cpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/poseidon2_trace.cpp new file mode 100644 index 00000000000..9b198484447 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/poseidon2_trace.cpp @@ -0,0 +1,429 @@ +#include "barretenberg/vm2/tracegen/poseidon2_trace.hpp" + +#include + +#include "barretenberg/crypto/poseidon2/poseidon2_permutation.hpp" +#include "barretenberg/ecc/fields/field_declarations.hpp" +#include "barretenberg/vm2/simulation/events/event_emitter.hpp" +#include "barretenberg/vm2/simulation/events/poseidon2_event.hpp" + +using Poseidon2Perm = bb::crypto::Poseidon2Permutation; + +namespace bb::avm2::tracegen { + +namespace { + +using StateCols = std::array; +// This absolute monstrosity is a mapping of the intermediate round columns (round & state) to the "flattened" columns +// in the trace. +constexpr std::array intermediate_round_cols = { { + // Full rounds + { Column::poseidon2_perm_T_0_6, + Column::poseidon2_perm_T_0_5, + Column::poseidon2_perm_T_0_7, + Column::poseidon2_perm_T_0_4 }, + { Column::poseidon2_perm_T_1_6, + Column::poseidon2_perm_T_1_5, + Column::poseidon2_perm_T_1_7, + Column::poseidon2_perm_T_1_4 }, + { Column::poseidon2_perm_T_2_6, + Column::poseidon2_perm_T_2_5, + Column::poseidon2_perm_T_2_7, + Column::poseidon2_perm_T_2_4 }, + { Column::poseidon2_perm_T_3_6, + Column::poseidon2_perm_T_3_5, + Column::poseidon2_perm_T_3_7, + Column::poseidon2_perm_T_3_4 }, + // Partial rounds + { Column::poseidon2_perm_B_4_0, + Column::poseidon2_perm_B_4_1, + Column::poseidon2_perm_B_4_2, + Column::poseidon2_perm_B_4_3 }, + { Column::poseidon2_perm_B_5_0, + Column::poseidon2_perm_B_5_1, + Column::poseidon2_perm_B_5_2, + Column::poseidon2_perm_B_5_3 }, + { Column::poseidon2_perm_B_6_0, + Column::poseidon2_perm_B_6_1, + Column::poseidon2_perm_B_6_2, + Column::poseidon2_perm_B_6_3 }, + { Column::poseidon2_perm_B_7_0, + Column::poseidon2_perm_B_7_1, + Column::poseidon2_perm_B_7_2, + Column::poseidon2_perm_B_7_3 }, + { Column::poseidon2_perm_B_8_0, + Column::poseidon2_perm_B_8_1, + Column::poseidon2_perm_B_8_2, + Column::poseidon2_perm_B_8_3 }, + { Column::poseidon2_perm_B_9_0, + Column::poseidon2_perm_B_9_1, + Column::poseidon2_perm_B_9_2, + Column::poseidon2_perm_B_9_3 }, + { Column::poseidon2_perm_B_10_0, + Column::poseidon2_perm_B_10_1, + Column::poseidon2_perm_B_10_2, + Column::poseidon2_perm_B_10_3 }, + { Column::poseidon2_perm_B_11_0, + Column::poseidon2_perm_B_11_1, + Column::poseidon2_perm_B_11_2, + Column::poseidon2_perm_B_11_3 }, + { Column::poseidon2_perm_B_12_0, + Column::poseidon2_perm_B_12_1, + Column::poseidon2_perm_B_12_2, + Column::poseidon2_perm_B_12_3 }, + { Column::poseidon2_perm_B_13_0, + Column::poseidon2_perm_B_13_1, + Column::poseidon2_perm_B_13_2, + Column::poseidon2_perm_B_13_3 }, + { Column::poseidon2_perm_B_14_0, + Column::poseidon2_perm_B_14_1, + Column::poseidon2_perm_B_14_2, + Column::poseidon2_perm_B_14_3 }, + { Column::poseidon2_perm_B_15_0, + Column::poseidon2_perm_B_15_1, + Column::poseidon2_perm_B_15_2, + Column::poseidon2_perm_B_15_3 }, + { Column::poseidon2_perm_B_16_0, + Column::poseidon2_perm_B_16_1, + Column::poseidon2_perm_B_16_2, + Column::poseidon2_perm_B_16_3 }, + { Column::poseidon2_perm_B_17_0, + Column::poseidon2_perm_B_17_1, + Column::poseidon2_perm_B_17_2, + Column::poseidon2_perm_B_17_3 }, + { Column::poseidon2_perm_B_18_0, + Column::poseidon2_perm_B_18_1, + Column::poseidon2_perm_B_18_2, + Column::poseidon2_perm_B_18_3 }, + { Column::poseidon2_perm_B_19_0, + Column::poseidon2_perm_B_19_1, + Column::poseidon2_perm_B_19_2, + Column::poseidon2_perm_B_19_3 }, + { Column::poseidon2_perm_B_20_0, + Column::poseidon2_perm_B_20_1, + Column::poseidon2_perm_B_20_2, + Column::poseidon2_perm_B_20_3 }, + { Column::poseidon2_perm_B_21_0, + Column::poseidon2_perm_B_21_1, + Column::poseidon2_perm_B_21_2, + Column::poseidon2_perm_B_21_3 }, + { Column::poseidon2_perm_B_22_0, + Column::poseidon2_perm_B_22_1, + Column::poseidon2_perm_B_22_2, + Column::poseidon2_perm_B_22_3 }, + { Column::poseidon2_perm_B_23_0, + Column::poseidon2_perm_B_23_1, + Column::poseidon2_perm_B_23_2, + Column::poseidon2_perm_B_23_3 }, + { Column::poseidon2_perm_B_24_0, + Column::poseidon2_perm_B_24_1, + Column::poseidon2_perm_B_24_2, + Column::poseidon2_perm_B_24_3 }, + { Column::poseidon2_perm_B_25_0, + Column::poseidon2_perm_B_25_1, + Column::poseidon2_perm_B_25_2, + Column::poseidon2_perm_B_25_3 }, + { Column::poseidon2_perm_B_26_0, + Column::poseidon2_perm_B_26_1, + Column::poseidon2_perm_B_26_2, + Column::poseidon2_perm_B_26_3 }, + { Column::poseidon2_perm_B_27_0, + Column::poseidon2_perm_B_27_1, + Column::poseidon2_perm_B_27_2, + Column::poseidon2_perm_B_27_3 }, + { Column::poseidon2_perm_B_28_0, + Column::poseidon2_perm_B_28_1, + Column::poseidon2_perm_B_28_2, + Column::poseidon2_perm_B_28_3 }, + { Column::poseidon2_perm_B_29_0, + Column::poseidon2_perm_B_29_1, + Column::poseidon2_perm_B_29_2, + Column::poseidon2_perm_B_29_3 }, + { Column::poseidon2_perm_B_30_0, + Column::poseidon2_perm_B_30_1, + Column::poseidon2_perm_B_30_2, + Column::poseidon2_perm_B_30_3 }, + { Column::poseidon2_perm_B_31_0, + Column::poseidon2_perm_B_31_1, + Column::poseidon2_perm_B_31_2, + Column::poseidon2_perm_B_31_3 }, + { Column::poseidon2_perm_B_32_0, + Column::poseidon2_perm_B_32_1, + Column::poseidon2_perm_B_32_2, + Column::poseidon2_perm_B_32_3 }, + { Column::poseidon2_perm_B_33_0, + Column::poseidon2_perm_B_33_1, + Column::poseidon2_perm_B_33_2, + Column::poseidon2_perm_B_33_3 }, + { Column::poseidon2_perm_B_34_0, + Column::poseidon2_perm_B_34_1, + Column::poseidon2_perm_B_34_2, + Column::poseidon2_perm_B_34_3 }, + { Column::poseidon2_perm_B_35_0, + Column::poseidon2_perm_B_35_1, + Column::poseidon2_perm_B_35_2, + Column::poseidon2_perm_B_35_3 }, + { Column::poseidon2_perm_B_36_0, + Column::poseidon2_perm_B_36_1, + Column::poseidon2_perm_B_36_2, + Column::poseidon2_perm_B_36_3 }, + { Column::poseidon2_perm_B_37_0, + Column::poseidon2_perm_B_37_1, + Column::poseidon2_perm_B_37_2, + Column::poseidon2_perm_B_37_3 }, + { Column::poseidon2_perm_B_38_0, + Column::poseidon2_perm_B_38_1, + Column::poseidon2_perm_B_38_2, + Column::poseidon2_perm_B_38_3 }, + { Column::poseidon2_perm_B_39_0, + Column::poseidon2_perm_B_39_1, + Column::poseidon2_perm_B_39_2, + Column::poseidon2_perm_B_39_3 }, + { Column::poseidon2_perm_B_40_0, + Column::poseidon2_perm_B_40_1, + Column::poseidon2_perm_B_40_2, + Column::poseidon2_perm_B_40_3 }, + { Column::poseidon2_perm_B_41_0, + Column::poseidon2_perm_B_41_1, + Column::poseidon2_perm_B_41_2, + Column::poseidon2_perm_B_41_3 }, + { Column::poseidon2_perm_B_42_0, + Column::poseidon2_perm_B_42_1, + Column::poseidon2_perm_B_42_2, + Column::poseidon2_perm_B_42_3 }, + { Column::poseidon2_perm_B_43_0, + Column::poseidon2_perm_B_43_1, + Column::poseidon2_perm_B_43_2, + Column::poseidon2_perm_B_43_3 }, + { Column::poseidon2_perm_B_44_0, + Column::poseidon2_perm_B_44_1, + Column::poseidon2_perm_B_44_2, + Column::poseidon2_perm_B_44_3 }, + { Column::poseidon2_perm_B_45_0, + Column::poseidon2_perm_B_45_1, + Column::poseidon2_perm_B_45_2, + Column::poseidon2_perm_B_45_3 }, + { Column::poseidon2_perm_B_46_0, + Column::poseidon2_perm_B_46_1, + Column::poseidon2_perm_B_46_2, + Column::poseidon2_perm_B_46_3 }, + { Column::poseidon2_perm_B_47_0, + Column::poseidon2_perm_B_47_1, + Column::poseidon2_perm_B_47_2, + Column::poseidon2_perm_B_47_3 }, + { Column::poseidon2_perm_B_48_0, + Column::poseidon2_perm_B_48_1, + Column::poseidon2_perm_B_48_2, + Column::poseidon2_perm_B_48_3 }, + { Column::poseidon2_perm_B_49_0, + Column::poseidon2_perm_B_49_1, + Column::poseidon2_perm_B_49_2, + Column::poseidon2_perm_B_49_3 }, + { Column::poseidon2_perm_B_50_0, + Column::poseidon2_perm_B_50_1, + Column::poseidon2_perm_B_50_2, + Column::poseidon2_perm_B_50_3 }, + { Column::poseidon2_perm_B_51_0, + Column::poseidon2_perm_B_51_1, + Column::poseidon2_perm_B_51_2, + Column::poseidon2_perm_B_51_3 }, + { Column::poseidon2_perm_B_52_0, + Column::poseidon2_perm_B_52_1, + Column::poseidon2_perm_B_52_2, + Column::poseidon2_perm_B_52_3 }, + { Column::poseidon2_perm_B_53_0, + Column::poseidon2_perm_B_53_1, + Column::poseidon2_perm_B_53_2, + Column::poseidon2_perm_B_53_3 }, + { Column::poseidon2_perm_B_54_0, + Column::poseidon2_perm_B_54_1, + Column::poseidon2_perm_B_54_2, + Column::poseidon2_perm_B_54_3 }, + { Column::poseidon2_perm_B_55_0, + Column::poseidon2_perm_B_55_1, + Column::poseidon2_perm_B_55_2, + Column::poseidon2_perm_B_55_3 }, + { Column::poseidon2_perm_B_56_0, + Column::poseidon2_perm_B_56_1, + Column::poseidon2_perm_B_56_2, + Column::poseidon2_perm_B_56_3 }, + { Column::poseidon2_perm_B_57_0, + Column::poseidon2_perm_B_57_1, + Column::poseidon2_perm_B_57_2, + Column::poseidon2_perm_B_57_3 }, + { Column::poseidon2_perm_B_58_0, + Column::poseidon2_perm_B_58_1, + Column::poseidon2_perm_B_58_2, + Column::poseidon2_perm_B_58_3 }, + { Column::poseidon2_perm_B_59_0, + Column::poseidon2_perm_B_59_1, + Column::poseidon2_perm_B_59_2, + Column::poseidon2_perm_B_59_3 }, + // Full Rounds + { Column::poseidon2_perm_T_60_6, + Column::poseidon2_perm_T_60_5, + Column::poseidon2_perm_T_60_7, + Column::poseidon2_perm_T_60_4 }, + { Column::poseidon2_perm_T_61_6, + Column::poseidon2_perm_T_61_5, + Column::poseidon2_perm_T_61_7, + Column::poseidon2_perm_T_61_4 }, + { Column::poseidon2_perm_T_62_6, + Column::poseidon2_perm_T_62_5, + Column::poseidon2_perm_T_62_7, + Column::poseidon2_perm_T_62_4 }, + { Column::poseidon2_perm_T_63_6, + Column::poseidon2_perm_T_63_5, + Column::poseidon2_perm_T_63_7, + Column::poseidon2_perm_T_63_4 }, +} }; + +} // namespace + +void Poseidon2TraceBuilder::process_hash( + const simulation::EventEmitterInterface::Container& hash_events, + TraceContainer& trace) +{ + using C = Column; + uint32_t row = 1; // We start from row 1 because this trace contains shifted columns. + for (const auto& event : hash_events) { + auto input_size = event.inputs.size(); + auto num_perm_events = (input_size / 3) + static_cast(input_size % 3 != 0); + auto padded_size = 3 * ((event.inputs.size() + 2) / 3); + + std::array perm_input = { 0, 0, 0 }; + for (size_t i = 0; i < num_perm_events; i++) { + auto perm_state = event.intermediate_states[i]; + auto perm_output = event.intermediate_states[i + 1]; + size_t chunk_size = std::min(input_size, static_cast(3)); + // Mix the input chunk into the previous permutation output state + for (size_t j = 0; j < chunk_size; j++) { + // Build up the input for the permutation + perm_input[j] = event.inputs[(i * 3) + j]; + // Mix the input chunk into the previous permutation output state + perm_state[j] += perm_input[j]; + } + trace.set(row, + { { + { C::poseidon2_hash_sel, 1 }, + { C::poseidon2_hash_start, i == 0 }, + { C::poseidon2_hash_execute_perm, i != num_perm_events - 1 }, + { C::poseidon2_hash_end, (num_perm_events - 1) == i }, + { C::poseidon2_hash_input_len, event.inputs.size() }, + { C::poseidon2_hash_padding, padded_size - event.inputs.size() }, + { C::poseidon2_hash_input_0, perm_input[0] }, + { C::poseidon2_hash_input_1, perm_input[1] }, + { C::poseidon2_hash_input_2, perm_input[2] }, + + { C::poseidon2_hash_num_perm_rounds_rem, num_perm_events - i - 1 }, + { C::poseidon2_hash_num_perm_rounds_rem_inv, + num_perm_events - i - 1 == 0 ? 0 : FF(num_perm_events - i - 1).invert() }, + + { C::poseidon2_hash_a_0, perm_state[0] }, + { C::poseidon2_hash_a_1, perm_state[1] }, + { C::poseidon2_hash_a_2, perm_state[2] }, + { C::poseidon2_hash_a_3, perm_state[3] }, + + { C::poseidon2_hash_b_0, perm_output[0] }, + { C::poseidon2_hash_b_1, perm_output[1] }, + { C::poseidon2_hash_b_2, perm_output[2] }, + { C::poseidon2_hash_b_3, perm_output[3] }, + { C::poseidon2_hash_output, event.output }, + } }); + input_size -= chunk_size; + row++; + } + } +} + +void Poseidon2TraceBuilder::process_permutation( + const simulation::EventEmitterInterface::Container& perm_events, + TraceContainer& trace) +{ + using C = Column; + // Our current state + std::array current_state; + // These are where we will store the intermediate values of current_state in the trace. + std::array round_state_cols; + + uint32_t row = 0; + + for (const auto& event : perm_events) { + // The bulk of this code is a copy of the Poseidon2Permutation::permute function from bb + // Note that the functions mutate current_state in place. + current_state = event.input; + + // Apply 1st linear layer + Poseidon2Perm::matrix_multiplication_external(current_state); + trace.set(row, + { { + { C::poseidon2_perm_sel, 1 }, + { C::poseidon2_perm_a_0, event.input[0] }, + { C::poseidon2_perm_a_1, event.input[1] }, + { C::poseidon2_perm_a_2, event.input[2] }, + { C::poseidon2_perm_a_3, event.input[3] }, + + { C::poseidon2_perm_EXT_LAYER_6, current_state[0] }, + { C::poseidon2_perm_EXT_LAYER_5, current_state[1] }, + { C::poseidon2_perm_EXT_LAYER_7, current_state[2] }, + { C::poseidon2_perm_EXT_LAYER_4, current_state[3] }, + + } }); + + // Perform rounds of the permutation algorithm + // Initial external (full) rounds + constexpr size_t rounds_f_beginning = Poseidon2Perm::rounds_f / 2; + for (size_t i = 0; i < rounds_f_beginning; ++i) { + Poseidon2Perm::add_round_constants(current_state, Poseidon2Perm::round_constants[i]); + Poseidon2Perm::apply_sbox(current_state); + Poseidon2Perm::matrix_multiplication_external(current_state); + // Store end of round state + round_state_cols = intermediate_round_cols[i]; + trace.set(row, + { { { round_state_cols[0], current_state[0] }, + { round_state_cols[1], current_state[1] }, + { round_state_cols[2], current_state[2] }, + { round_state_cols[3], current_state[3] } } }); + } + + // Internal (partial) rounds + const size_t p_end = rounds_f_beginning + Poseidon2Perm::rounds_p; + for (size_t i = rounds_f_beginning; i < p_end; ++i) { + current_state[0] += Poseidon2Perm::round_constants[i][0]; + Poseidon2Perm::apply_single_sbox(current_state[0]); + Poseidon2Perm::matrix_multiplication_internal(current_state); + // Store end of round state + round_state_cols = intermediate_round_cols[i]; + trace.set(row, + { { { round_state_cols[0], current_state[0] }, + { round_state_cols[1], current_state[1] }, + { round_state_cols[2], current_state[2] }, + { round_state_cols[3], current_state[3] } } }); + } + + // Remaining external (full) rounds + for (size_t i = p_end; i < Poseidon2Perm::NUM_ROUNDS; ++i) { + Poseidon2Perm::add_round_constants(current_state, Poseidon2Perm::round_constants[i]); + Poseidon2Perm::apply_sbox(current_state); + Poseidon2Perm::matrix_multiplication_external(current_state); + round_state_cols = intermediate_round_cols[i]; + trace.set(row, + { { { round_state_cols[0], current_state[0] }, + { round_state_cols[1], current_state[1] }, + { round_state_cols[2], current_state[2] }, + { round_state_cols[3], current_state[3] } } }); + } + // Set the output + trace.set(row, + { { + { C::poseidon2_perm_b_0, current_state[0] }, + { C::poseidon2_perm_b_1, current_state[1] }, + { C::poseidon2_perm_b_2, current_state[2] }, + { C::poseidon2_perm_b_3, current_state[3] }, + + } }); + row++; + } +} + +} // namespace bb::avm2::tracegen diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/poseidon2_trace.hpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/poseidon2_trace.hpp new file mode 100644 index 00000000000..dfc9ca14f85 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/poseidon2_trace.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include "barretenberg/vm2/generated/columns.hpp" +#include "barretenberg/vm2/simulation/events/event_emitter.hpp" +#include "barretenberg/vm2/simulation/events/poseidon2_event.hpp" +#include "barretenberg/vm2/tracegen/trace_container.hpp" + +namespace bb::avm2::tracegen { + +class Poseidon2TraceBuilder final { + public: + void process_hash(const simulation::EventEmitterInterface::Container& hash_events, + TraceContainer& trace); + void process_permutation( + const simulation::EventEmitterInterface::Container& perm_events, + TraceContainer& trace); +}; + +} // namespace bb::avm2::tracegen diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen_helper.cpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen_helper.cpp index 0402379b472..e614cb77f66 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen_helper.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen_helper.cpp @@ -17,6 +17,7 @@ #include "barretenberg/vm2/generated/relations/lookups_bc_decomposition.hpp" #include "barretenberg/vm2/generated/relations/lookups_bitwise.hpp" #include "barretenberg/vm2/generated/relations/lookups_execution.hpp" +#include "barretenberg/vm2/generated/relations/lookups_poseidon2_hash.hpp" #include "barretenberg/vm2/generated/relations/lookups_range_check.hpp" #include "barretenberg/vm2/generated/relations/lookups_sha256.hpp" #include "barretenberg/vm2/generated/relations/perms_execution.hpp" @@ -29,6 +30,7 @@ #include "barretenberg/vm2/tracegen/lib/lookup_into_bitwise.hpp" #include "barretenberg/vm2/tracegen/lib/lookup_into_indexed_by_clk.hpp" #include "barretenberg/vm2/tracegen/lib/permutation_builder.hpp" +#include "barretenberg/vm2/tracegen/poseidon2_trace.hpp" #include "barretenberg/vm2/tracegen/precomputed_trace.hpp" #include "barretenberg/vm2/tracegen/sha256_trace.hpp" #include "barretenberg/vm2/tracegen/trace_container.hpp" @@ -198,6 +200,18 @@ TraceContainer AvmTraceGenHelper::generate_trace(EventsContainer&& events) EccTraceBuilder ecc_builder; AVM_TRACK_TIME("tracegen/ecc_add", ecc_builder.process(events.ecc_add, trace)); clear_events(events.ecc_add); + }, + [&]() { + Poseidon2TraceBuilder poseidon2_builder; + AVM_TRACK_TIME("tracegen/poseidon2_hash", + poseidon2_builder.process_hash(events.poseidon2_hash, trace)); + clear_events(events.poseidon2_hash); + }, + [&]() { + Poseidon2TraceBuilder poseidon2_builder; + AVM_TRACK_TIME("tracegen/poseidon2_permutation", + poseidon2_builder.process_permutation(events.poseidon2_permutation, trace)); + clear_events(events.poseidon2_permutation); } }); AVM_TRACK_TIME("tracegen/traces", execute_jobs(jobs)); } @@ -207,6 +221,7 @@ TraceContainer AvmTraceGenHelper::generate_trace(EventsContainer&& events) auto jobs_interactions = make_jobs>( std::make_unique>(), std::make_unique>(), + std::make_unique>(), std::make_unique>(), std::make_unique>(), std::make_unique>(),