From 86c151aa43ba990a0e900995064a88fc2ae6637d Mon Sep 17 00:00:00 2001 From: Michael J Klein Date: Mon, 26 Aug 2024 17:25:11 -0400 Subject: [PATCH] chore: crypto blackbox tests (#5614) # Description ## Problem\* Resolves https://github.com/noir-lang/noir/issues/5427 ## Summary\* Unit test our blackbox crypto instructions. Preferable to merge after: - https://github.com/noir-lang/noir/pull/5559 - https://github.com/noir-lang/noir/pull/5484 (Because of overlapping helper functions) ## Additional Context While most of our crypto function implementations are from external crates, `poseidon2_permutation` is implemented internally. I'm using the [`zkhash` crate](https://docs.rs/zkhash/0.2.0/zkhash/poseidon2/) to test our implementation. ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- Cargo.lock | 220 +++++++- acvm-repo/acvm/Cargo.toml | 3 + .../acvm/tests/solver.proptest-regressions | 6 + acvm-repo/acvm/tests/solver.rs | 504 +++++++++++++++++- acvm-repo/bn254_blackbox_solver/src/lib.rs | 2 +- .../bn254_blackbox_solver/src/poseidon2.rs | 20 +- cspell.json | 4 +- 7 files changed, 725 insertions(+), 34 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e1159c71201..f78fbfede27 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -45,6 +45,8 @@ dependencies = [ "acir", "acvm_blackbox_solver", "ark-bls12-381", + "ark-bn254", + "bn254_blackbox_solver", "brillig_vm", "indexmap 1.9.3", "num-bigint", @@ -52,6 +54,7 @@ dependencies = [ "serde", "thiserror", "tracing", + "zkhash", ] [[package]] @@ -539,6 +542,18 @@ dependencies = [ "typenum", ] +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "blake2" version = "0.10.6" @@ -548,6 +563,17 @@ dependencies = [ "digest", ] +[[package]] +name = "blake2b_simd" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23285ad32269793932e830392f2fe2f83e26488fd3ec778883a93c8323735780" +dependencies = [ + "arrayref", + "arrayvec", + "constant_time_eq", +] + [[package]] name = "blake3" version = "1.5.0" @@ -570,6 +596,19 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bls12_381" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3c196a77437e7cc2fb515ce413a6401291578b5afc8ecb29a3c7ab957f05941" +dependencies = [ + "ff 0.12.1", + "group 0.12.1", + "pairing", + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "bn254_blackbox_solver" version = "0.49.0" @@ -1360,9 +1399,9 @@ dependencies = [ "crypto-bigint", "der", "digest", - "ff", + "ff 0.12.1", "generic-array", - "group", + "group 0.12.1", "pkcs8", "rand_core 0.6.4", "sec1", @@ -1465,6 +1504,18 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" dependencies = [ + "bitvec", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "bitvec", "rand_core 0.6.4", "subtle", ] @@ -1569,6 +1620,12 @@ dependencies = [ "libc", ] +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + [[package]] name = "futures" version = "0.1.31" @@ -1764,7 +1821,19 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" dependencies = [ - "ff", + "ff 0.12.1", + "memuse", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff 0.13.0", "rand_core 0.6.4", "subtle", ] @@ -1775,6 +1844,29 @@ version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" +[[package]] +name = "halo2" +version = "0.1.0-beta.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a23c779b38253fe1538102da44ad5bd5378495a61d2c4ee18d64eaa61ae5995" +dependencies = [ + "halo2_proofs", +] + +[[package]] +name = "halo2_proofs" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e925780549adee8364c7f2b685c753f6f3df23bde520c67416e93bf615933760" +dependencies = [ + "blake2b_simd", + "ff 0.12.1", + "group 0.12.1", + "pasta_curves 0.4.1", + "rand_core 0.6.4", + "rayon", +] + [[package]] name = "hashbrown" version = "0.11.2" @@ -2252,6 +2344,20 @@ dependencies = [ "unicase", ] +[[package]] +name = "jubjub" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a575df5f985fe1cd5b2b05664ff6accfc46559032b954529fd225a2168d27b0f" +dependencies = [ + "bitvec", + "bls12_381", + "ff 0.12.1", + "group 0.12.1", + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "k256" version = "0.11.6" @@ -2329,6 +2435,9 @@ name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin", +] [[package]] name = "libaes" @@ -2464,6 +2573,12 @@ dependencies = [ "autocfg", ] +[[package]] +name = "memuse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2145869435ace5ea6ea3d35f59be559317ec9a0d04e1812d5f185a87b6d36f1a" + [[package]] name = "miniz_oxide" version = "0.7.1" @@ -3100,6 +3215,15 @@ dependencies = [ "sha2", ] +[[package]] +name = "pairing" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "135590d8bdba2b31346f9cd1fb2a912329f5135e832a4f422942eb6ead8b6b3b" +dependencies = [ + "group 0.12.1", +] + [[package]] name = "parking_lot" version = "0.11.2" @@ -3148,6 +3272,36 @@ dependencies = [ "windows-targets 0.48.1", ] +[[package]] +name = "pasta_curves" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc65faf8e7313b4b1fbaa9f7ca917a0eed499a9663be71477f87993604341d8" +dependencies = [ + "blake2b_simd", + "ff 0.12.1", + "group 0.12.1", + "lazy_static", + "rand 0.8.5", + "static_assertions", + "subtle", +] + +[[package]] +name = "pasta_curves" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e57598f73cc7e1b2ac63c79c517b31a0877cd7c402cdcaa311b5208de7a095" +dependencies = [ + "blake2b_simd", + "ff 0.13.0", + "group 0.13.0", + "lazy_static", + "rand 0.8.5", + "static_assertions", + "subtle", +] + [[package]] name = "paste" version = "1.0.14" @@ -3473,6 +3627,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + [[package]] name = "radix_trie" version = "0.2.1" @@ -4193,6 +4353,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + [[package]] name = "spki" version = "0.6.0" @@ -4209,6 +4375,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "str-buf" version = "1.0.6" @@ -4310,6 +4482,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + [[package]] name = "tempfile" version = "3.8.0" @@ -5178,6 +5356,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + [[package]] name = "zerocopy" version = "0.7.32" @@ -5217,3 +5404,30 @@ dependencies = [ "quote", "syn 2.0.64", ] + +[[package]] +name = "zkhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4352d1081da6922701401cdd4cbf29a2723feb4cfabb5771f6fee8e9276da1c7" +dependencies = [ + "ark-ff", + "ark-std", + "bitvec", + "blake2", + "bls12_381", + "byteorder", + "cfg-if 1.0.0", + "group 0.12.1", + "group 0.13.0", + "halo2", + "hex", + "jubjub", + "lazy_static", + "pasta_curves 0.5.1", + "rand 0.8.5", + "serde", + "sha2", + "sha3", + "subtle", +] diff --git a/acvm-repo/acvm/Cargo.toml b/acvm-repo/acvm/Cargo.toml index f6df4bb5b0e..ea80dbeedbb 100644 --- a/acvm-repo/acvm/Cargo.toml +++ b/acvm-repo/acvm/Cargo.toml @@ -39,4 +39,7 @@ bls12_381 = [ [dev-dependencies] ark-bls12-381 = { version = "^0.4.0", default-features = false, features = ["curve"] } +ark-bn254.workspace = true +bn254_blackbox_solver.workspace = true proptest.workspace = true +zkhash = { version = "^0.2.0", default-features = false } diff --git a/acvm-repo/acvm/tests/solver.proptest-regressions b/acvm-repo/acvm/tests/solver.proptest-regressions index 35627c1fbae..d5b09c8c009 100644 --- a/acvm-repo/acvm/tests/solver.proptest-regressions +++ b/acvm-repo/acvm/tests/solver.proptest-regressions @@ -4,6 +4,7 @@ # # It is recommended to check this file in to source control so that # everyone who runs the test benefits from these saved cases. +cc 960460afabe9cd5f293b310d0aa3cc55f79163d4445fb4fd24f148c0c70ef421 # shrinks to inputs = [(7006800039331019243688393824145158009389575060470190384886350246083750305789, false), (2¹⁶×69288181877743077422831840787272084000814053518824660036579689151244970, false), (300437348917483825612039528102296693334006129135490594023152856084953868810, false), (4823492773360499854802554302585328525608528551020562050189864554765904117770, false), (4824670368033820130439612125278697378018346703067216363823090518963541115050, false), (4541974568008122685711264049174891850838557765495784399449231366824048721930, false), (300437350040540685984720241501165014133014058360545849645894867666537650617, true), (163192779580560125232076252958207681919, true), (-2542062050439421159413867956702051849160671674920746658341296409298182239337, true), (175503121977504223703263610086399928344, true), (260495679943662138441041500775727067764, true), (256267345976523334436046522042864460684, false), (-3293060738351338103745720847983311414454700585429643550776950744744641792278, true), (-2738558284890938529700946417088255944936801663233427893951742481234449937863, true), (-9408903287898353981993159772236368632269873213738312580426228276387594806467, false), (-4094435362802425278873069427818373025789998862201415928058861770747528163349, false), (112103815807797910215405155129290739992, true), (652959048122537987900699228406811595117461985442100769568930484681117184927, true), (25648069884835098934129943086492583018, true), (182381658164976581567218989771782914043, true), (276027589667111318145641746681175535935, true), (228979537701935045218138086489994361738, true), (-7189629140037494234317011123662291175105203248014412116387794444668331938972, true), (2⁴×21045079095550098765213744333690206045, true), (2⁴×272957279228827760019939917744285068022450150396463247147001692315953383164, true), (278169782777797975865517348961398261204, true), (-9350891260062047521505428797610570271715889226434172923277698254137606657637, true), (31753891497170711449574490616043022555, true), (5826530521679896062199745042089932193960338071930275815357730199930663038971, false), (6333148601890872882199727702821458893692619379008420418245130578951125712813, true), (11591994241860040248819868426028245994970593822060591090353134114607771350840, false), (285019902865519749239467179980780356895, true), (-1841690738801312317622577110475383143336981923160464720298620703157843518801, false), (5677035692440022901187907185898133134673347474144834237621131124787028412481, false), (3817657503746267247293557834223189311, false), (3524986425011502884950940801392664786470720156074841155252661063475974853061, true), (3804027911019145431046523949797604749769206523757137367319384533460898442710, false), (66232570440565238307407257297826182007, true), (10950346695884721979708694328592923581621839140812284359518482850256345903994, true), (-2555270735135738372913055831827559435131548066765611995534606037449334265987, false), (254175244691305364094581273598120793718, true), (290269702902160220362408941750532374247, false), (123377132611149223348638391192338552487, true), (11181151842165891780257230406582701746739259352010643125205313477915192331122, true), (-2⁴×409367997994623731443501907254201822154034077116501532446678462812476345374, true), (2⁴×544614809509366338085123708986493598, false), (2⁴×17078170458432298388079487507615195387, true), (149630116761755329336202584260592884865, false), (2⁴×10091764197139943452626559964081430454, true), (2534364375519095349027150248721158492583764392404691624469146116049080450061, true), (603871911530068460120598744369974193816624318623555065050680487659787773114, true), (160084452435578937990759565211574469929, false), (218093312507148512669194680815491642329, true), (300736043265743439077982281106014100410, true), (18523147759780982956728003842757122081, true), (306248530673006182475517947158145534649, true), (102222390890150910453739963495986974375, false), (257196139219119037476292875587496141911, true), (331081228043791906616479284936784004527, false), (3016805042897548992579828613322067728372560923112623438800394966350526781639, false), (-572714658027596419754534645583807426372197275429130874987048126395899381912, true), (-729547819819366432764794677355722188538208598242889613088699865869727118200, true), (821714036325498522863927403152236109, false), (4787751092911790208417000875909331970360784454334971842120679656099485179967, false), (1782142348917496268507120173995265725105472252018261170186756542207304517779, true), (12386003977677513084491398210232899807, false), (-2⁴×618559586542445675091456136080909891843100214761559602644497715652929490680, true), (4825546553395317448131256122977630559401382302668933235792589235215581675013, true), (140081105962524159719688476469460050188, true), (10859915619506763272622767997975661267764177865434405229649588030297621763336, false), (5224965182422450783905844900991128046, false), (71305303954419714098999884166539099370, false), (1774498925999897022672533369155675274519638992774354242677460742588824167893, true), (7303027640230419310139844673790234369436236422573534223908300465886393464159, false), (-6886271862152701865078616271612468719595307788386883226924940208040368361967, false), (10731912210227615778772646231985571152124249989191718989152918741848181957943, true), (198890466402904980166209748345696486119, true), (-5302367762468092462990244835112194335091450476355385352485920702032880189295, true), (2⁸×10099407372054304360516381277909507981224443414132090997901220204171639546, false), (168440361528147182399972323599534901404, true), (-6814422589767867668898643051011344807889685848964308955561956885501315175751, false), (316318615743355850862007524903255359480, true), (2712091589809687549346821393688518190583490946219058843320554352096717761470, true), (271066251172692433277334139422005324431, true), (5518750645785029524081697870015943313782873802072211951410725469084236770902, true), (1598180654131654153665855630440993899751870982081743673174495880400279439835, true), (11087487398111971618312866830968963281800717504531211030365913622073456199882, true), (111117995977996342335283103148096717294, true), (-1295976581376625868027817481511298593289394037483836095148092178778026996567, true), (83596219152712990240747906837305397145, true), (1228889622953345470420372628777807948517612731014485410422479520987606375826, true), (-8913468232804310348258666527777442833035058410912856005485334678693975514181, false), (-2⁴×278169562875273203973590188765589611858625386111898684152446666758264013985, true), (119076628552542975308949066183764445758, false), (2⁴×14050391655614718300501271078314774634, false), (194148774408232082873511641818616649590, false), (8194443279687593339348520601136879720103397639149864695196588804167374140678, false), (-354687261929126904957780450034290767854037900960107070732201978247851494917, false), (-4179720645035540348033514199762031592916784883648049359344050592582034531797, false), (252905126534820884873153821542654918918, false), (1623505226178950044083922559187169870608127387658796034641797863725138722258, false), (4666866662074690176801634318736786643725641691879698870430777699162065406876, true), (2⁸×435424843840757189423437488726199338, true), (-4965389845430595378911449436549917702549453083792442397843742095714939156996, true), (14382174601370788118680121014383071020, true), (18435597849872688842745199082065115774, true), (62402934393754095161223999760955177676, true), (3342319610924388381676805660071709048562626908839360397545889815909430346935, false), (320934966917535193944554370897413442767, false), (-7042080042894669842698869952298956796788859350146750227466425877912934318731, false), (730331371245847611804891620969657153593889954959738225897355098167792980949, false), (4302619576720736253790944194743764744133983784456893791762467136654139077499, true), (8873437849856151332967264853182096823478282147593198413978830303785491549165, true), (90112803136689598890112508644364307477, false), (5515586277356922699974022986439856116085865722104320017169902845027519269630, true), (193123430947542232681959839788943833622, false), (313518414676988815146392681741405591399, false), (1744503198465993468536485478138286257957976156358242481202409192902804688819, true), (232270086930796904432134012473980400372, false), (54252678944965710450270323121364517361, false), (227966767610810610640465794393680628548, true), (195275454883093736141594026466958950870, false), (41489184570808717515029072032722768645, false), (-1376299006702054572367600313792943879784167154440024183554470146184948865317, false), (-4342520612104393712790888025887841267334261124780864718056663459023881749401, false), (-2195492958636161600210780697531407029867553813415393642723791298864497552233, true), (332196823653718041971704314790182081950, true), (6692397022125437472229833939879677974689961856437724474341917567424805187801, true), (-2383455130457463032029147766306601662937360882870225696738568438241981024563, true), (6717167117084866258340101046663161160224757566359450082951177418440696737772, true), (-1642389908034348896239060205015333283837806723968213066158348166269363356454, true), (6906326300271352814414395025112363945375522026620021146077167231059213695969, false), (62420300707619024606657497955183365269, false), (310840635777201053115164797040466639857, true)] cc e4dd0e141df173f5dfdfb186bba4154247ec284b71d8f294fa3282da953a0e92 # shrinks to x = 0, y = 1 cc 419ed6fdf1bf1f2513889c42ec86c665c9d0500ceb075cbbd07f72444dbd78c6 # shrinks to x = 266672725 cc 0810fc9e126b56cf0a0ddb25e0dc498fa3b2f1980951550403479fc01c209833 # shrinks to modulus = [71, 253, 124, 216, 22, 140, 32, 60, 141, 202, 113, 104, 145, 106, 129, 151, 93, 88, 129, 129, 182, 69, 80, 184, 41, 160, 49, 225, 114, 78, 100, 48], zero_or_ones_constant = false, use_constant = false @@ -11,3 +12,8 @@ cc 735ee9beb1a1dbb82ded6f30e544d7dfde149957e5d45a8c96fc65a690b6b71c # shrinks to cc ca81bc11114a2a2b34021f44ecc1e10cb018e35021ef4d728e07a6791dad38d6 # shrinks to (xs, modulus) = ([(0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (49, false)], [71, 253, 124, 216, 22, 140, 32, 60, 141, 202, 113, 104, 145, 106, 129, 151, 93, 88, 129, 129, 182, 69, 80, 184, 41, 160, 49, 225, 114, 78, 100, 48]) cc 6c1d571a0111e6b4c244dc16da122ebab361e77b71db7770d638076ab21a717b # shrinks to (xs, modulus) = ([(0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (49, false)], [71, 253, 124, 216, 22, 140, 32, 60, 141, 202, 113, 104, 145, 106, 129, 151, 93, 88, 129, 129, 182, 69, 80, 184, 41, 160, 49, 225, 114, 78, 100, 48]) cc ccb7061ab6b85e2554d00bf03d74204977ed7a4109d7e2d5c6b5aaa2179cfaf9 # shrinks to (xs, modulus) = ([(0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (0, false), (49, false)], [71, 253, 124, 216, 22, 140, 32, 60, 141, 202, 113, 104, 145, 106, 129, 151, 93, 88, 129, 129, 182, 69, 80, 184, 41, 160, 49, 225, 114, 78, 100, 48]) +cc 853d774f6d69809a63e3121ccdbbb780db42acb861cb6cada63247446932a321 # shrinks to inputs_distinct_inputs = ([(0, false)], [(9374390252263900826, false)]) +cc 4fc0bd347d9f4967801e2e30c746d2f6c012882911f72e7e816d350a742ced28 # shrinks to inputs_distinct_inputs = ([(2⁸×61916068613087029720904767285796661, false)], [(2⁸×220343640628484768581538005104492351, false)]) +cc 04d8571793600c2023d7aba2d1dd8f0e2c82b6010130d95a193df02b07977712 # shrinks to inputs_distinct_inputs = ([], [(0, true)]) +cc dbc57772b9450371db70f8aa06d10502bb1aef030448c6df467465937bc8916a # shrinks to inputs_distinct_inputs = ([(295, false), (0, false), (0, false), (0, false), (0, false), (0, false)], [(295, false), (0, false), (328, false), (237, true), (484, true), (69, false)]) +cc ef68d2dc6f0d366dd69edf8eec02a7b9cd7d6888983cea45496516b6effca813 # shrinks to inputs_distinct_inputs = ([(40, false), (471, false), (56, false), (35, false), (104, false), (232, false), (252, false), (131, false), (437, true), (354, false), (235, false), (316, true), (364, true), (242, false), (436, true), (298, true), (360, true), (174, true), (295, false), (250, true), (178, true), (426, false), (78, false), (217, true), (296, true), (371, false), (349, true), (445, false), (221, false), (409, false), (59, false), (511, true), (482, false)], [(136, true), (228, true), (193, true), (190, true), (15, false), (399, false), (54, false), (195, true), (258, true), (99, false), (83, false), (383, true), (456, true), (409, true), (347, false), (183, false), (371, true), (410, true), (439, true), (175, true), (445, false), (165, false), (70, false), (2⁴×22, true), (339, true), (161, true), (313, false), (2⁴×23, true), (275, true), (278, true), (294, true), (284, true), (262, false)]) diff --git a/acvm-repo/acvm/tests/solver.rs b/acvm-repo/acvm/tests/solver.rs index 0500514578f..2a06e07f092 100644 --- a/acvm-repo/acvm/tests/solver.rs +++ b/acvm-repo/acvm/tests/solver.rs @@ -1,4 +1,5 @@ use std::collections::{BTreeMap, HashSet}; +use std::sync::Arc; use acir::{ acir_field::GenericFieldElement, @@ -14,12 +15,14 @@ use acir::{ use acvm::pwg::{ACVMStatus, ErrorLocation, ForeignCallWaitInfo, OpcodeResolutionError, ACVM}; use acvm_blackbox_solver::StubbedBlackBoxSolver; +use bn254_blackbox_solver::{field_from_hex, Bn254BlackBoxSolver, POSEIDON2_CONFIG}; use brillig_vm::brillig::HeapValueType; use proptest::arbitrary::any; use proptest::prelude::*; use proptest::result::maybe_ok; use proptest::sample::select; +use zkhash::poseidon2::poseidon2_params::Poseidon2Params; #[test] fn bls12_381_circuit() { @@ -769,31 +772,32 @@ type ConstantOrWitness = (FieldElement, bool); // - If use_constant, then convert to a FunctionInput::constant // - Otherwise, convert to FunctionInput::witness // + With the Witness index as (input_index + offset) -// -// Both use FieldElement::max_num_bits as the number of bits. fn constant_or_witness_to_function_inputs( - inputs: Vec, + xs: Vec, offset: usize, + num_bits: Option, ) -> Vec> { - inputs - .into_iter() + let num_bits = num_bits.unwrap_or(FieldElement::max_num_bits()); + xs.into_iter() .enumerate() - .map(|(index, (input, use_constant))| { + .map(|(i, (x, use_constant))| { if use_constant { - FunctionInput::constant(input, FieldElement::max_num_bits()) + FunctionInput::constant(x, num_bits) } else { - FunctionInput::witness( - Witness((index + offset) as u32), - FieldElement::max_num_bits(), - ) + FunctionInput::witness(Witness((i + offset) as u32), num_bits) } }) .collect() } // Convert ConstantOrWitness's back to FieldElement's by dropping the bool's -fn drop_use_constant(inputs: &[ConstantOrWitness]) -> Vec { - inputs.iter().map(|input| input.0).collect() +fn drop_use_constant(input: &[ConstantOrWitness]) -> Vec { + input.iter().map(|x| x.0).collect() +} + +// equivalent values (ignoring use_constant) +fn drop_use_constant_eq(x: &[ConstantOrWitness], y: &[ConstantOrWitness]) -> bool { + drop_use_constant(x) == drop_use_constant(y) } // Convert FieldElement's to ConstantOrWitness's by making all of them witnesses @@ -801,6 +805,38 @@ fn use_witnesses(inputs: Vec) -> Vec { inputs.into_iter().map(|input| (input, false)).collect() } +fn solve_array_input_blackbox_call( + inputs: Vec, + num_outputs: usize, + num_bits: Option, + f: F, +) -> Vec +where + F: FnOnce((Vec>, Vec)) -> BlackBoxFuncCall, +{ + let initial_witness_vec: Vec<_> = + inputs.iter().enumerate().map(|(i, (x, _))| (Witness(i as u32), *x)).collect(); + let outputs: Vec<_> = (0..num_outputs) + .map(|i| Witness((i + inputs.len()) as u32)) // offset past the indices of inputs + .collect(); + let initial_witness = WitnessMap::from(BTreeMap::from_iter(initial_witness_vec)); + + let inputs = constant_or_witness_to_function_inputs(inputs, 0, num_bits); + let op = Opcode::BlackBoxFuncCall(f((inputs.clone(), outputs.clone()))); + let opcodes = vec![op]; + let unconstrained_functions = vec![]; + let mut acvm = + ACVM::new(&Bn254BlackBoxSolver, &opcodes, initial_witness, &unconstrained_functions, &[]); + let solver_status = acvm.solve(); + assert_eq!(solver_status, ACVMStatus::Solved); + let witness_map = acvm.finalize(); + + outputs + .iter() + .map(|witness| *witness_map.get(witness).expect("all witnesses to be set")) + .collect() +} + prop_compose! { fn bigint_with_modulus()(modulus in select(allowed_bigint_moduli())) (inputs in proptest::collection::vec(any::<(u8, bool)>(), modulus.len()), modulus in Just(modulus)) @@ -898,8 +934,8 @@ fn bigint_solve_binary_op_opt( .collect(); let initial_witness = WitnessMap::from(BTreeMap::from_iter(initial_witness_vec)); - let lhs = constant_or_witness_to_function_inputs(lhs, 0); - let rhs = constant_or_witness_to_function_inputs(rhs, lhs.len()); + let lhs = constant_or_witness_to_function_inputs(lhs, 0, None); + let rhs = constant_or_witness_to_function_inputs(rhs, lhs.len(), None); let to_op_input = if middle_op.is_some() { 2 } else { 0 }; @@ -930,7 +966,6 @@ fn bigint_solve_binary_op_opt( let solver_status = acvm.solve(); assert_eq!(solver_status, ACVMStatus::Solved); let witness_map = acvm.finalize(); - output_witnesses .iter() .map(|witness| *witness_map.get(witness).expect("all witnesses to be set")) @@ -975,6 +1010,178 @@ fn solve_blackbox_func_call( witness_map[&Witness(3)] } +// N inputs +// 32 outputs +fn sha256_op( + function_inputs_and_outputs: (Vec>, Vec), +) -> BlackBoxFuncCall { + let (function_inputs, outputs) = function_inputs_and_outputs; + BlackBoxFuncCall::SHA256 { + inputs: function_inputs, + outputs: outputs.try_into().expect("SHA256 returns 32 outputs"), + } +} + +// N inputs +// 32 outputs +fn blake2s_op( + function_inputs_and_outputs: (Vec>, Vec), +) -> BlackBoxFuncCall { + let (function_inputs, outputs) = function_inputs_and_outputs; + BlackBoxFuncCall::Blake2s { + inputs: function_inputs, + outputs: outputs.try_into().expect("Blake2s returns 32 outputs"), + } +} + +// N inputs +// 32 outputs +fn blake3_op( + function_inputs_and_outputs: (Vec>, Vec), +) -> BlackBoxFuncCall { + let (function_inputs, outputs) = function_inputs_and_outputs; + BlackBoxFuncCall::Blake3 { + inputs: function_inputs, + outputs: outputs.try_into().expect("Blake3 returns 32 outputs"), + } +} + +// variable inputs +// 32 outputs +fn keccak256_op( + function_inputs_and_outputs: (Vec>, Vec), +) -> BlackBoxFuncCall { + let (function_inputs, outputs) = function_inputs_and_outputs; + let function_inputs_len = function_inputs.len(); + BlackBoxFuncCall::Keccak256 { + inputs: function_inputs, + var_message_size: FunctionInput::constant( + function_inputs_len.into(), + FieldElement::max_num_bits(), + ), + outputs: outputs.try_into().expect("Keccak256 returns 32 outputs"), + } +} + +// var_message_size is the number of bytes to take +// from the input. Note: if `var_message_size` +// is more than the number of bytes in the input, +// then an error is returned. +// +// variable inputs +// 32 outputs +fn keccak256_invalid_message_size_op( + function_inputs_and_outputs: (Vec>, Vec), +) -> BlackBoxFuncCall { + let (function_inputs, outputs) = function_inputs_and_outputs; + let function_inputs_len = function_inputs.len(); + BlackBoxFuncCall::Keccak256 { + inputs: function_inputs, + var_message_size: FunctionInput::constant( + (function_inputs_len - 1).into(), + FieldElement::max_num_bits(), + ), + outputs: outputs.try_into().expect("Keccak256 returns 32 outputs"), + } +} + +// 25 inputs +// 25 outputs +fn keccakf1600_op( + function_inputs_and_outputs: (Vec>, Vec), +) -> BlackBoxFuncCall { + let (function_inputs, outputs) = function_inputs_and_outputs; + BlackBoxFuncCall::Keccakf1600 { + inputs: function_inputs.try_into().expect("Keccakf1600 expects 25 inputs"), + outputs: outputs.try_into().expect("Keccakf1600 returns 25 outputs"), + } +} + +// N inputs +// N outputs +fn poseidon2_permutation_op( + function_inputs_and_outputs: (Vec>, Vec), +) -> BlackBoxFuncCall { + let (inputs, outputs) = function_inputs_and_outputs; + let len = inputs.len() as u32; + BlackBoxFuncCall::Poseidon2Permutation { inputs, outputs, len } +} + +// N inputs +// N outputs +fn poseidon2_permutation_invalid_len_op( + function_inputs_and_outputs: (Vec>, Vec), +) -> BlackBoxFuncCall { + let (inputs, outputs) = function_inputs_and_outputs; + let len = (inputs.len() as u32) + 1; + BlackBoxFuncCall::Poseidon2Permutation { inputs, outputs, len } +} + +// 24 inputs (16 + 8) +// 8 outputs +fn sha256_compression_op( + function_inputs_and_outputs: (Vec>, Vec), +) -> BlackBoxFuncCall { + let (function_inputs, outputs) = function_inputs_and_outputs; + let mut function_inputs = function_inputs.into_iter(); + let inputs = core::array::from_fn(|_| function_inputs.next().unwrap()); + let hash_values = core::array::from_fn(|_| function_inputs.next().unwrap()); + BlackBoxFuncCall::Sha256Compression { + inputs: Box::new(inputs), + hash_values: Box::new(hash_values), + outputs: outputs.try_into().unwrap(), + } +} + +fn into_repr_vec(fields: T) -> Vec +where + T: IntoIterator, +{ + fields.into_iter().map(|field| field.into_repr()).collect() +} + +fn into_repr_mat(fields: T) -> Vec> +where + T: IntoIterator, + U: IntoIterator, +{ + fields.into_iter().map(|field| into_repr_vec(field)).collect() +} + +fn run_both_poseidon2_permutations( + inputs: Vec, +) -> (Vec, Vec) { + let result = solve_array_input_blackbox_call( + inputs.clone(), + inputs.len(), + None, + poseidon2_permutation_op, + ); + + let poseidon2_t = POSEIDON2_CONFIG.t as usize; + let poseidon2_d = 5; + let rounds_f = POSEIDON2_CONFIG.rounds_f as usize; + let rounds_p = POSEIDON2_CONFIG.rounds_p as usize; + let mat_internal_diag_m_1 = into_repr_vec(POSEIDON2_CONFIG.internal_matrix_diagonal); + let mat_internal = vec![]; + let round_constants = into_repr_mat(POSEIDON2_CONFIG.round_constant); + + let external_poseidon2 = + zkhash::poseidon2::poseidon2::Poseidon2::new(&Arc::new(Poseidon2Params::new( + poseidon2_t, + poseidon2_d, + rounds_f, + rounds_p, + &mat_internal_diag_m_1, + &mat_internal, + &round_constants, + ))); + + let expected_result = + external_poseidon2.permutation(&into_repr_vec(drop_use_constant(&inputs))); + (into_repr_vec(result), expected_result) +} + // Using the given BigInt modulus, solve the following circuit: // - Convert xs, ys to BigInt's with ID's 0, 1, resp. // - Run the middle_op: @@ -1064,6 +1271,33 @@ fn prop_assert_zero_l( (solve_blackbox_func_call(op, op_zero, x), FieldElement::zero()) } +// Test that varying one of the inputs produces a different result +// +// (is the op injective for the given inputs?, failure string) +fn prop_assert_injective( + inputs: Vec, + distinct_inputs: Vec, + num_outputs: usize, + num_bits: Option, + op: F, +) -> (bool, String) +where + F: FnOnce((Vec>, Vec)) -> BlackBoxFuncCall + + Clone, +{ + let equal_inputs = drop_use_constant_eq(&inputs, &distinct_inputs); + let message = format!("not injective:\n{:?}\n{:?}", &inputs, &distinct_inputs); + let outputs_not_equal = + solve_array_input_blackbox_call(inputs, num_outputs, num_bits, op.clone()) + != solve_array_input_blackbox_call(distinct_inputs, num_outputs, num_bits, op); + (equal_inputs || outputs_not_equal, message) +} + +fn field_element_ones() -> FieldElement { + let exponent: FieldElement = (253_u128).into(); + FieldElement::from(2u128).pow(&exponent) - FieldElement::one() +} + prop_compose! { // Use both `u128` and hex proptest strategies fn field_element() @@ -1078,9 +1312,169 @@ prop_compose! { } } -fn field_element_ones() -> FieldElement { - let exponent: FieldElement = (253_u128).into(); - FieldElement::from(2u128).pow(&exponent) - FieldElement::one() +prop_compose! { + fn any_distinct_inputs(max_input_bits: Option, min_size: usize, max_size: usize) + (size_and_patch in any::<(usize, usize, usize)>()) // NOTE: macro ambiguity when using (x: T) + (inputs_distinct_inputs in + (proptest::collection::vec(any::<(u128, bool)>(), std::cmp::max(min_size, size_and_patch.0 % max_size)), + proptest::collection::vec(any::<(u128, bool)>(), std::cmp::max(min_size, size_and_patch.0 % max_size))), + size_and_patch in Just(size_and_patch)) + -> (Vec, Vec) { + let (_size, patch_location, patch_value) = size_and_patch; + let (inputs, distinct_inputs) = inputs_distinct_inputs; + let to_input = |(x, use_constant)| { + let modulus = if let Some(max_input_bits) = max_input_bits { + 2u128 << max_input_bits + } else { + 1 + }; + (FieldElement::from(x % modulus), use_constant) + }; + let inputs: Vec<_> = inputs.into_iter().map(to_input).collect(); + let mut distinct_inputs: Vec<_> = distinct_inputs.into_iter().map(to_input).collect(); + + // if equivalent w/o use_constant, patch with the patch_value + if drop_use_constant_eq(&inputs, &distinct_inputs) { + let distinct_inputs_len = distinct_inputs.len(); + let positive_patch_value = std::cmp::max(patch_value, 1); + if distinct_inputs_len != 0 { + distinct_inputs[patch_location % distinct_inputs_len].0 += FieldElement::from(positive_patch_value) + } else { + distinct_inputs.push((FieldElement::zero(), true)) + } + } + + (inputs, distinct_inputs) + } +} + +#[test] +fn poseidon2_permutation_zeroes() { + let use_constants: [bool; 4] = [false; 4]; + let inputs: Vec<_> = [FieldElement::zero(); 4].into_iter().zip(use_constants).collect(); + let (result, expected_result) = run_both_poseidon2_permutations(inputs); + + let internal_expected_result = vec![ + field_from_hex("18DFB8DC9B82229CFF974EFEFC8DF78B1CE96D9D844236B496785C698BC6732E"), + field_from_hex("095C230D1D37A246E8D2D5A63B165FE0FADE040D442F61E25F0590E5FB76F839"), + field_from_hex("0BB9545846E1AFA4FA3C97414A60A20FC4949F537A68CCECA34C5CE71E28AA59"), + field_from_hex("18A4F34C9C6F99335FF7638B82AEED9018026618358873C982BBDDE265B2ED6D"), + ]; + + assert_eq!(expected_result, into_repr_vec(internal_expected_result)); + assert_eq!(result, expected_result); +} + +#[test] +fn sha256_zeros() { + let results = solve_array_input_blackbox_call(vec![], 32, None, sha256_op); + let expected_results: Vec<_> = vec![ + 227, 176, 196, 66, 152, 252, 28, 20, 154, 251, 244, 200, 153, 111, 185, 36, 39, 174, 65, + 228, 100, 155, 147, 76, 164, 149, 153, 27, 120, 82, 184, 85, + ] + .into_iter() + .map(|x: u128| FieldElement::from(x)) + .collect(); + assert_eq!(results, expected_results); +} + +#[test] +fn sha256_compression_zeros() { + let results = solve_array_input_blackbox_call( + [(FieldElement::zero(), false); 24].try_into().unwrap(), + 8, + None, + sha256_compression_op, + ); + let expected_results: Vec<_> = vec![ + 2091193876, 1113340840, 3461668143, 3254913767, 3068490961, 2551409935, 2927503052, + 3205228454, + ] + .into_iter() + .map(|x: u128| FieldElement::from(x)) + .collect(); + assert_eq!(results, expected_results); +} + +#[test] +fn blake2s_zeros() { + let results = solve_array_input_blackbox_call(vec![], 32, None, blake2s_op); + let expected_results: Vec<_> = vec![ + 105, 33, 122, 48, 121, 144, 128, 148, 225, 17, 33, 208, 66, 53, 74, 124, 31, 85, 182, 72, + 44, 161, 165, 30, 27, 37, 13, 253, 30, 208, 238, 249, + ] + .into_iter() + .map(|x: u128| FieldElement::from(x)) + .collect(); + assert_eq!(results, expected_results); +} + +#[test] +fn blake3_zeros() { + let results = solve_array_input_blackbox_call(vec![], 32, None, blake3_op); + let expected_results: Vec<_> = vec![ + 175, 19, 73, 185, 245, 249, 161, 166, 160, 64, 77, 234, 54, 220, 201, 73, 155, 203, 37, + 201, 173, 193, 18, 183, 204, 154, 147, 202, 228, 31, 50, 98, + ] + .into_iter() + .map(|x: u128| FieldElement::from(x)) + .collect(); + assert_eq!(results, expected_results); +} + +#[test] +fn keccak256_zeros() { + let results = solve_array_input_blackbox_call(vec![], 32, None, keccak256_op); + let expected_results: Vec<_> = vec![ + 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, + 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112, + ] + .into_iter() + .map(|x: u128| FieldElement::from(x)) + .collect(); + assert_eq!(results, expected_results); +} + +#[test] +fn keccakf1600_zeros() { + let results = solve_array_input_blackbox_call( + [(FieldElement::zero(), false); 25].into(), + 25, + Some(64), + keccakf1600_op, + ); + let expected_results: Vec<_> = vec![ + 17376452488221285863, + 9571781953733019530, + 15391093639620504046, + 13624874521033984333, + 10027350355371872343, + 18417369716475457492, + 10448040663659726788, + 10113917136857017974, + 12479658147685402012, + 3500241080921619556, + 16959053435453822517, + 12224711289652453635, + 9342009439668884831, + 4879704952849025062, + 140226327413610143, + 424854978622500449, + 7259519967065370866, + 7004910057750291985, + 13293599522548616907, + 10105770293752443592, + 10668034807192757780, + 1747952066141424100, + 1654286879329379778, + 8500057116360352059, + 16929593379567477321, + ] + .into_iter() + .map(|x: u128| FieldElement::from(x)) + .collect(); + + assert_eq!(results, expected_results); } // NOTE: an "average" bigint is large, so consider increasing the number of proptest shrinking @@ -1151,6 +1545,78 @@ proptest! { prop_assert_eq!(lhs, rhs); } + #[test] + fn poseidon2_permutation_matches_external_impl(inputs in proptest::collection::vec(field_element(), 4)) { + let (result, expected_result) = run_both_poseidon2_permutations(inputs); + prop_assert_eq!(result, expected_result) + } + + #[test] + fn sha256_injective(inputs_distinct_inputs in any_distinct_inputs(None, 0, 32)) { + let (inputs, distinct_inputs) = inputs_distinct_inputs; + let (result, message) = prop_assert_injective(inputs, distinct_inputs, 32, None, sha256_op); + prop_assert!(result, "{}", message); + } + + #[test] + fn sha256_compression_injective(inputs_distinct_inputs in any_distinct_inputs(None, 24, 24)) { + let (inputs, distinct_inputs) = inputs_distinct_inputs; + if inputs.len() == 24 && distinct_inputs.len() == 24 { + let (result, message) = prop_assert_injective(inputs, distinct_inputs, 8, None, sha256_compression_op); + prop_assert!(result, "{}", message); + } + } + + #[test] + fn blake2s_injective(inputs_distinct_inputs in any_distinct_inputs(None, 0, 32)) { + let (inputs, distinct_inputs) = inputs_distinct_inputs; + let (result, message) = prop_assert_injective(inputs, distinct_inputs, 32, None, blake2s_op); + prop_assert!(result, "{}", message); + } + + #[test] + fn blake3_injective(inputs_distinct_inputs in any_distinct_inputs(None, 0, 32)) { + let (inputs, distinct_inputs) = inputs_distinct_inputs; + let (result, message) = prop_assert_injective(inputs, distinct_inputs, 32, None, blake3_op); + prop_assert!(result, "{}", message); + } + + #[test] + fn keccak256_injective(inputs_distinct_inputs in any_distinct_inputs(Some(8), 0, 32)) { + let (inputs, distinct_inputs) = inputs_distinct_inputs; + let (result, message) = prop_assert_injective(inputs, distinct_inputs, 32, Some(32), keccak256_op); + prop_assert!(result, "{}", message); + } + + // TODO(https://github.com/noir-lang/noir/issues/5689): doesn't fail with a user error + // The test failing with "not injective" demonstrates that it returns constant output instead + // of failing with a user error. + #[test] + #[should_panic(expected = "Test failed: not injective")] + fn keccak256_invalid_message_size_fails(inputs_distinct_inputs in any_distinct_inputs(Some(8), 0, 32)) { + let (inputs, distinct_inputs) = inputs_distinct_inputs; + let (result, message) = prop_assert_injective(inputs, distinct_inputs, 32, Some(8), keccak256_invalid_message_size_op); + prop_assert!(result, "{}", message); + } + + #[test] + fn keccakf1600_injective(inputs_distinct_inputs in any_distinct_inputs(Some(8), 25, 25)) { + let (inputs, distinct_inputs) = inputs_distinct_inputs; + assert_eq!(inputs.len(), 25); + assert_eq!(distinct_inputs.len(), 25); + let (result, message) = prop_assert_injective(inputs, distinct_inputs, 25, Some(64), keccakf1600_op); + prop_assert!(result, "{}", message); + } + + // TODO(https://github.com/noir-lang/noir/issues/5699): wrong failure message + #[test] + #[should_panic(expected = "Failure(BlackBoxFunctionFailed(Poseidon2Permutation, \"the number of inputs does not match specified length. 6 != 7\"))")] + fn poseidon2_permutation_invalid_size_fails(inputs_distinct_inputs in any_distinct_inputs(None, 6, 6)) { + let (inputs, distinct_inputs) = inputs_distinct_inputs; + let (result, message) = prop_assert_injective(inputs, distinct_inputs, 1, None, poseidon2_permutation_invalid_len_op); + prop_assert!(result, "{}", message); + } + #[test] fn bigint_from_to_le_bytes_zero_one(modulus in select(allowed_bigint_moduli()), zero_or_ones_constant: bool, use_constant: bool) { let zero_function_input = if zero_or_ones_constant { diff --git a/acvm-repo/bn254_blackbox_solver/src/lib.rs b/acvm-repo/bn254_blackbox_solver/src/lib.rs index 6897116e90e..43ee6a9ddd2 100644 --- a/acvm-repo/bn254_blackbox_solver/src/lib.rs +++ b/acvm-repo/bn254_blackbox_solver/src/lib.rs @@ -13,7 +13,7 @@ mod schnorr; use ark_ec::AffineRepr; pub use embedded_curve_ops::{embedded_curve_add, multi_scalar_mul}; pub use generator::generators::derive_generators; -pub use poseidon2::poseidon2_permutation; +pub use poseidon2::{field_from_hex, poseidon2_permutation, Poseidon2Config, POSEIDON2_CONFIG}; // Temporary hack, this ensure that we always use a bn254 field here // without polluting the feature flags of the `acir_field` crate. diff --git a/acvm-repo/bn254_blackbox_solver/src/poseidon2.rs b/acvm-repo/bn254_blackbox_solver/src/poseidon2.rs index 18ed0b1d8ab..dd3e8b725c2 100644 --- a/acvm-repo/bn254_blackbox_solver/src/poseidon2.rs +++ b/acvm-repo/bn254_blackbox_solver/src/poseidon2.rs @@ -16,26 +16,26 @@ pub(crate) struct Poseidon2<'a> { config: &'a Poseidon2Config, } -struct Poseidon2Config { - t: u32, - rounds_f: u32, - rounds_p: u32, - internal_matrix_diagonal: [FieldElement; 4], - round_constant: [[FieldElement; 4]; 64], +pub struct Poseidon2Config { + pub t: u32, + pub rounds_f: u32, + pub rounds_p: u32, + pub internal_matrix_diagonal: [FieldElement; 4], + pub round_constant: [[FieldElement; 4]; 64], } -fn field_from_hex(hex: &str) -> FieldElement { +pub fn field_from_hex(hex: &str) -> FieldElement { FieldElement::from_be_bytes_reduce(&hex::decode(hex).expect("Should be passed only valid hex")) } lazy_static! { - static ref INTERNAL_MATRIX_DIAGONAL: [FieldElement; 4] = [ + pub static ref INTERNAL_MATRIX_DIAGONAL: [FieldElement; 4] = [ field_from_hex("10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e7"), field_from_hex("0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b"), field_from_hex("00544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac15"), field_from_hex("222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b"), ]; - static ref ROUND_CONSTANT: [[FieldElement; 4]; 64] = [ + pub static ref ROUND_CONSTANT: [[FieldElement; 4]; 64] = [ [ field_from_hex("19b849f69450b06848da1d39bd5e4a4302bb86744edc26238b0878e269ed23e5"), field_from_hex("265ddfe127dd51bd7239347b758f0a1320eb2cc7450acc1dad47f80c8dcf34d6"), @@ -421,7 +421,7 @@ lazy_static! { field_from_hex("176563472456aaa746b694c60e1823611ef39039b2edc7ff391e6f2293d2c404"), ], ]; - static ref POSEIDON2_CONFIG: Poseidon2Config = Poseidon2Config { + pub static ref POSEIDON2_CONFIG: Poseidon2Config = Poseidon2Config { t: 4, rounds_f: 8, rounds_p: 56, diff --git a/cspell.json b/cspell.json index b7d344c6507..c34d14b6153 100644 --- a/cspell.json +++ b/cspell.json @@ -222,7 +222,9 @@ "wasi", "wasmer", "Weierstraß", - "zshell" + "zkhash", + "zshell", + "Linea" ], "ignorePaths": [ "./**/node_modules/**",