From 86d6822dc72dce28cbdf7f76fb67c32cd710ec6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Salvador=20Mag=C3=A1n=20Valero?= Date: Mon, 26 Feb 2024 19:05:25 +0100 Subject: [PATCH 1/8] feat: conversions --- conversion/index.js | 53 +++++++++++++++++ conversion/package.json | 13 +++++ conversion/proof.json | 28 +++++++++ conversion/verification_key.json | 99 ++++++++++++++++++++++++++++++++ 4 files changed, 193 insertions(+) create mode 100644 conversion/index.js create mode 100644 conversion/package.json create mode 100644 conversion/proof.json create mode 100644 conversion/verification_key.json diff --git a/conversion/index.js b/conversion/index.js new file mode 100644 index 0000000..05c543b --- /dev/null +++ b/conversion/index.js @@ -0,0 +1,53 @@ +const fs = require("fs"); + +const proof = JSON.parse(fs.readFileSync("proof.json", "utf-8")); +const verificationKey = JSON.parse(fs.readFileSync("verification_key.json", "utf-8")); + +console.log("Proof", JSON.stringify(proof)); + +function uncompressedFq(number) { + const buffer = Buffer.alloc(48); + buffer.write(BigInt(number).toString(16), 0, 48, "hex"); + return buffer.toString("hex"); +} + +function uncompressedG1(point) { + const x = uncompressedFq(point[0]); + const y = uncompressedFq(point[1]); + return x + y; +} + +function uncompressedG2(point) { + const x = uncompressedFq(point[0][0]) + uncompressedFq(point[0][1]); + const y = uncompressedFq(point[1][0]) + uncompressedFq(point[1][1]); + return x + y; +} + +function convertProofToUncompressed(proof) { + + const uncompressedProof = { + "pi_a": uncompressedG1(proof.pi_a), + "pi_b": uncompressedG2(proof.pi_b), + "pi_c": uncompressedG1(proof.pi_c), + } + + return uncompressedProof; +} + + +function convertVerificationKeyToUncompressed(verificationKey) { + const uncompressedVerificationKey = { + "vk_alpha_1": uncompressedG1(verificationKey.vk_alpha_1), + "vk_beta_2": uncompressedG2(verificationKey.vk_beta_2), + "vk_gamma_2": uncompressedG2(verificationKey.vk_gamma_2), + "vk_delta_2": uncompressedG2(verificationKey.vk_delta_2), + "IC": verificationKey.IC.map((item) => uncompressedG1(item)), + } + + return uncompressedVerificationKey; +} + +console.log("Uncompressed proof", JSON.stringify(convertProofToUncompressed(proof))); + +console.log("\n\nUncompressed verification key", JSON.stringify(convertVerificationKeyToUncompressed(verificationKey))); + diff --git a/conversion/package.json b/conversion/package.json new file mode 100644 index 0000000..ab68083 --- /dev/null +++ b/conversion/package.json @@ -0,0 +1,13 @@ +{ + "name": "conversion", + "version": "1.0.0", + "description": "", + "type": "commonjs", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC" +} diff --git a/conversion/proof.json b/conversion/proof.json new file mode 100644 index 0000000..bd1b6e0 --- /dev/null +++ b/conversion/proof.json @@ -0,0 +1,28 @@ +{ + "pi_a": [ + "2855044796369946382827590498028074399954178188404052044460392173044055949963055520226458797341961615378727946048206", + "3607648035569852498712601197821672930980634267835166890422819022801738069852659753344138199712325573228301683310722", + "1" + ], + "pi_b": [ + [ + "2216529660448908459446533763529433361366105288599360068340479797481300540437545794646354474692017045121551582868515", + "3867914260234198041425601044308116127196057132281581166005254303219906875747339103782814281378360746808337469178926" + ], + [ + "1959291290564527252319212910819685638672433971337410545600749187884388402471099470819029490531580085761840095948690", + "2011071151816425671679220330755640211651471450664831295838757345432821939838685402356499133954205160730680575168228" + ], + [ + "1", + "0" + ] + ], + "pi_c": [ + "1295247664883995735684917166146384745983218062371398982813013851011964236053567050995264999819727337215745868836854", + "425196572825763797251425507115701065909002365213946325141666886779730764869850382851002816252507146444245309603107", + "1" + ], + "protocol": "groth16", + "curve": "bls12381" +} \ No newline at end of file diff --git a/conversion/verification_key.json b/conversion/verification_key.json new file mode 100644 index 0000000..0042bbc --- /dev/null +++ b/conversion/verification_key.json @@ -0,0 +1,99 @@ +{ + "protocol": "groth16", + "curve": "bls12381", + "nPublic": 2, + "vk_alpha_1": [ + "2191843459987598773590024133079527616758118088671934301945762281620908967162581012712567405019815572665712872623796", + "1664035774849863503646003048494213577015151537859184157765549528966387776772789207030433777101994828854739585442222", + "1" + ], + "vk_beta_2": [ + [ + "3764231095688882375546394077913791289729500066732987589069835200735210168251677834789785070698671518741236262863583", + "1975956737674144585508789155185883489602647165720568470078042365709562638839124474451400468748578229290756203131924" + ], + [ + "2664149391785363356913750779411127000638406920365075800895742802208799038187313640182620725503804085435506720148070", + "491716795312779218659130638886776306404649091170844785976521584811326619381572211056932234374432526609285865390398" + ], + [ + "1", + "0" + ] + ], + "vk_gamma_2": [ + [ + "352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160", + "3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758" + ], + [ + "1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905", + "927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582" + ], + [ + "1", + "0" + ] + ], + "vk_delta_2": [ + [ + "413154724199753058200524769130480539747847790863923642234877877680592088694363992783042398840429407626050743066789", + "3002644543443356676160163060928218871865410081831733983743342774940778555956806189822098470475670237779542851415944" + ], + [ + "2438985653642956949171527495262358641872663641541030192914572463146908921129516216779501221673275997233817960176712", + "1153945107219418639093484597929798696693867386162471902015435074259666973369548699571341876110098845066777294832589" + ], + [ + "1", + "0" + ] + ], + "vk_alphabeta_12": [ + [ + [ + "1119614312890782083309600999057785795397603170170631015257396745570323316457963535074630855686990494673778448196147", + "742038601496863801453526417229271542806078110469177730792585776439827530482489842329316749055341641464553626528152" + ], + [ + "1088390838327808008035210883448228493907177201542653184182090904196651559543951664333111649677783977078506847884041", + "2837214357972618712140457906768388362286637294555761672630024210522781142923797999255029248557137948544249112648333" + ], + [ + "3877433249608326965639214147645932794884649572211492101458714681451992481281490963848814775798303784975033778565476", + "597955767106016876429201374986914550795954983229979662231585633284625712368958497140704039770602231110571127993019" + ] + ], + [ + [ + "2662556007646867761078073839158787132584127608421740379641502416597911492081507983862867550569692646879338719901980", + "1728784185468663874776440121711147809386195240021570349495245715254841355674231060337884553346596272099905654906277" + ], + [ + "3783046564574746437870408327888798832808904026618842104076700319916198573571995197610592169664700148018523815708027", + "1650953322183301436255680254214000225128094685097878264284712810475465218613191405608582106951277280117676043243386" + ], + [ + "661282582370783830377759997030246421465048985306548778665276485713752568765509911394270899905744300097503830686188", + "554462205254579485033981033913994147758083815475117093767616549931962491805668145901814272592450333224914413991514" + ] + ] + ], + "IC": [ + [ + "3309896332232763728332884765232343789621967757514439814841772750001004110163769133520530042440224977308143690966538", + "2729872703560414785705863386228322151240301147292791955557293720514020028816188672981305414934902446634648161893597", + "1" + ], + [ + "631322038111762990511918330017151125033987672955885718113870795938008485779609080354246784064816111921692130342156", + "2237991347874379964013843270729116257803284877394816325928044453833709035829235921538541619664979249135195864580089", + "1" + ], + [ + "2156395363321496459977006673790312524899213752348596549626151845365363536870686406447459761442071948022650812037505", + "859509658696984707388484840799535446245965210460962278516264652307712352123089491042788915533211361883018851645942", + "1" + ] + ] +} \ No newline at end of file From 316a61071782b5dabfd34928fd306dbd7d80c60d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Salvador=20Mag=C3=A1n=20Valero?= Date: Mon, 26 Feb 2024 19:27:02 +0100 Subject: [PATCH 2/8] feat: conversions --- conversion/index.js | 6 ++--- lib/ak-381/groth16.ak | 63 ++++++++++++++++++++++++------------------- 2 files changed, 37 insertions(+), 32 deletions(-) diff --git a/conversion/index.js b/conversion/index.js index 05c543b..35aae24 100644 --- a/conversion/index.js +++ b/conversion/index.js @@ -13,14 +13,12 @@ function uncompressedFq(number) { function uncompressedG1(point) { const x = uncompressedFq(point[0]); - const y = uncompressedFq(point[1]); - return x + y; + return x; } function uncompressedG2(point) { const x = uncompressedFq(point[0][0]) + uncompressedFq(point[0][1]); - const y = uncompressedFq(point[1][0]) + uncompressedFq(point[1][1]); - return x + y; + return x; } function convertProofToUncompressed(proof) { diff --git a/lib/ak-381/groth16.ak b/lib/ak-381/groth16.ak index 77d1b01..c132a9b 100644 --- a/lib/ak-381/groth16.ak +++ b/lib/ak-381/groth16.ak @@ -51,33 +51,40 @@ pub fn groth_verify( // Test (3 Factorial problem) -test groth_verify_1() { - // Template of VK - let vk: SnarkVerificationKey = - SnarkVerificationKey { - nPublic: 8, - vkAlpha: #"97f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb", - vkBeta: #"93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8", - vkGamma: #"93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8", - vkDelta: #"93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8", - vkAlphaBeta: [ - #"93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8", - ], - vkIC: [ - #"97f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb", - ], - } +// test groth_verify_1() { +// // Template of VK +// let vk: SnarkVerificationKey = +// SnarkVerificationKey { +// nPublic: 2, +// vkAlpha: #"e3d9e248feda194cb6fa0a3b64fd2a380cb5e94836bf8148bf97ebcbb5819d9a78f63102f0293c104bcbb2f810d8eb00", +// vkBeta: #"1874ea7bbfcb9872931e115d882c46b90c3dcbcee10062d1c9b9b0a691d7bec7d2735f06495c7f71dea210e55b2782dfcd68a7186a908212680a0234d8210c20328f8fb3ce1d69c9aec9330a5802d6cfaf6d7cf3176133221c19188590cb4100", +// vkGamma: #"24aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb0013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e", +// vkDelta: #"2af2f9f515c65af6a9a6c294c738590104376a0af44731d6699db6a286608774243f7d1dddc4605eb340e65e15060a00138231fcec443fbdeb1079ff126b8f69bd8579ffe82d39923214d4345395beee60200288fa20c97ae50f3212131b6f88", +// vkAlphaBeta: [ +// #"93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8", +// ], +// vkIC: [ +// #"15813c90d3455acb8608fdf66e8601f24ef048f3fdf9384862d77c72cb5cddfde2b307976b1b0319c42ba985f94be60a", +// #"41a0e6370c054be0f9acce08e97f6d5702d9daa9e9a934e8a377f553593baa1c58062adc73d63558653422d54d6f5000", +// #"e02a87c519c3145f984d25fdf769f74fbc36626c385d4554fb4bc1d7a12cbf669d40f257023b8b3c9a31e631aa8f9800", +// ], +// } - // Template of Proof - let pk: Proof = - Proof { - piA: #"97f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb", - piB: #"93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8", - piC: #"97f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb", - } - // Template of public values - let public_values: List = - [562, 3] +// // Template of Proof +// let pk: Proof = +// Proof { +// piA: #"128cb29bc282be68df977b35eb9d8e98b3a0a3fc7c372990bddc50419ca86693e491755338fed4fb42231a7c081252ce", +// piB: #"e66ad6d86c7c76c468a32c9c0080eea0219d0953b44b1c4f5605afb1e5a3193264ff730222e94f55207628235f3b420019215e5bc481ba6552384c89c23d45bd650b69462868248bfbb83aee7060579404dba41c781dec7c2bec5fccec06842e", +// piC: #"86a574105c0da95915c36025637e5b80c7c00c4a264b529b465c273ade3e38f15dc7840498a1aefb44a24a0070a2ff00", +// } +// // Template of public values +// let public_values: List = +// [562, 3] - groth_verify(vk, pk, public_values) -} +// groth_verify(vk, pk, public_values) +// } + +test bls_point_construction() { + let point_1 = #"184bb665c37ff561a89ec2122dd343f20e0f4cbcaec84e3c3052ea81d1834e192c426074b02ed3dca4e7676ce4ce48ba" + True +} \ No newline at end of file From 1812288bbb519da4194dfd034f10ef3ea9955aa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Salvador=20Mag=C3=A1n=20Valero?= Date: Tue, 27 Feb 2024 14:18:15 +0100 Subject: [PATCH 3/8] feat: javascript point compression --- .gitignore | 4 + conversion/index.js | 158 ++++++++++++++++++++++++++++++++++------ conversion/package.json | 6 +- lib/ak-381/groth16.ak | 5 +- 4 files changed, 147 insertions(+), 26 deletions(-) diff --git a/.gitignore b/.gitignore index ff7811b..f87ae2f 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,7 @@ artifacts/ build/ # Aiken's default documentation export docs/ + + +node_modules +conversion/package-lock.json diff --git a/conversion/index.js b/conversion/index.js index 35aae24..8ee2fe8 100644 --- a/conversion/index.js +++ b/conversion/index.js @@ -1,51 +1,161 @@ const fs = require("fs"); +const bb = require("bigint-buffer"); +const ff = require("ffjavascript"); const proof = JSON.parse(fs.readFileSync("proof.json", "utf-8")); const verificationKey = JSON.parse(fs.readFileSync("verification_key.json", "utf-8")); -console.log("Proof", JSON.stringify(proof)); +async function compressedG1(point) { + const curve = await ff.getCurveFromName("bls12381"); -function uncompressedFq(number) { - const buffer = Buffer.alloc(48); - buffer.write(BigInt(number).toString(16), 0, 48, "hex"); - return buffer.toString("hex"); -} + const result = bb.toBufferBE(BigInt(point[0]), 48); + const COMPRESSED = 0b10000000; + const INFINITY = 0b01000000; + const YBIT = 0b00100000; + + result[0] = result[0] | COMPRESSED; + + if (BigInt(point[2]) !== 1n) { + result[0] = result[0] | INFINITY; + } else { + const F = curve.G1.F; + + const x = F.fromObject(BigInt(point[0])); + + const x3b = F.add(F.mul(F.square(x), x), curve.G1.b); + const y1 = F.toObject(F.sqrt(x3b)); + const y2 = F.toObject(F.neg(F.sqrt(x3b))); + + const y = BigInt(point[1]); -function uncompressedG1(point) { - const x = uncompressedFq(point[0]); - return x; + if (y1 > y2 && y > y2) { + result[0] = result[0] | YBIT; + } else if (y1 < y2 && y > y1) { + result[0] = result[0] | YBIT; + } + } + + + return result.toString("hex"); } -function uncompressedG2(point) { - const x = uncompressedFq(point[0][0]) + uncompressedFq(point[0][1]); - return x; +async function compressedG2(point) { + const curve = await ff.getCurveFromName("bls12381"); + + const result = Buffer.concat([bb.toBufferBE(BigInt(point[0][1]), 48), bb.toBufferBE(BigInt(point[0][0]), 48)]); + const COMPRESSED = 0b10000000; + const INFINITY = 0b01000000; + const YBIT = 0b00100000; + + result[0] = result[0] | COMPRESSED; + + if (BigInt(point[2][0]) !== 1n) { + result[0] = result[0] | INFINITY; + } else { + const F = curve.G2.F; + + const x = F.fromObject(point[0].map(item => BigInt(item))); + + // console.log("x", x); + + const x3b = F.add(F.mul(F.square(x), x), curve.G2.b); + const y1 = F.toObject(F.sqrt(x3b)); + const y2 = F.toObject(F.neg(F.sqrt(x3b))); + // console.log("y1", y1); + // console.log("y2", y2); + // console.log("point", point[1]); + + function greaterThan(a, b) { + if (a[1] > b[1]) { + return true + } else if (a[1] === b[1] && a[0] > b[0]) { + return true; + } + return false; + } + + const y = point[1].map(item => BigInt(item)); + + if (greaterThan(y1, y2) && greaterThan(y, y2)) { + result[0] = result[0] | YBIT; + } else if (greaterThan(y2, y1) && greaterThan(y, y1)) { + result[0] = result[0] | YBIT; + } + } + return result.toString("hex"); } -function convertProofToUncompressed(proof) { + +async function convertProofToUncompressed(proof) { const uncompressedProof = { - "pi_a": uncompressedG1(proof.pi_a), - "pi_b": uncompressedG2(proof.pi_b), - "pi_c": uncompressedG1(proof.pi_c), + "pi_a": await compressedG1(proof.pi_a), + "pi_b": await compressedG2(proof.pi_b), + "pi_c": await compressedG1(proof.pi_c), } return uncompressedProof; } -function convertVerificationKeyToUncompressed(verificationKey) { +async function convertVerificationKeyToUncompressed(verificationKey) { const uncompressedVerificationKey = { - "vk_alpha_1": uncompressedG1(verificationKey.vk_alpha_1), - "vk_beta_2": uncompressedG2(verificationKey.vk_beta_2), - "vk_gamma_2": uncompressedG2(verificationKey.vk_gamma_2), - "vk_delta_2": uncompressedG2(verificationKey.vk_delta_2), - "IC": verificationKey.IC.map((item) => uncompressedG1(item)), + "vk_alpha_1": await compressedG1(verificationKey.vk_alpha_1), + "vk_beta_2": await compressedG2(verificationKey.vk_beta_2), + "vk_gamma_2": await compressedG2(verificationKey.vk_gamma_2), + "vk_delta_2": await compressedG2(verificationKey.vk_delta_2), + "IC": verificationKey.IC.map(async (item) => await compressedG1(item)), } return uncompressedVerificationKey; } -console.log("Uncompressed proof", JSON.stringify(convertProofToUncompressed(proof))); +async function printCompressedProof() { + console.log("Compressed proof", JSON.stringify(await convertProofToUncompressed(proof))); +} + +printCompressedProof(); -console.log("\n\nUncompressed verification key", JSON.stringify(convertVerificationKeyToUncompressed(verificationKey))); +async function printCompressedVerificationKey() { + console.log("\n\nUncompressed verification key", JSON.stringify(await convertVerificationKeyToUncompressed(verificationKey))); +} + +printCompressedVerificationKey(); + + +async function ffTest() { + const curve = await ff.getCurveFromName("bls12381"); + + const point = proof.pi_c; + + const xBufferBE = bb.toBufferBE(BigInt(point[0]), 48); + + console.log("Point x buffer BE", new Uint8Array(xBufferBE)); + + const xBufferLE = bb.toBufferLE(BigInt(point[0]), 48); + + console.log("Point x buffer LE", new Uint8Array(xBufferLE)); + + + const g1Element = curve.G1.fromObject(point.map((item) => BigInt(item).toString(16))); + + console.log("G1 element", g1Element); + + console.log("G1 Element is valid", curve.G1.isValid(g1Element)); + + const buff = new Uint8Array(48); + + curve.G1.toRprCompressed(buff, 0, g1Element); + + console.log("G1 element Compressed", buff); + + console.log("MSB", buff[0].toString(2)); + + const g1ElementFromCompressed = curve.G1.fromRprCompressed(buff, 0); + + console.log("G1 from compressed", g1ElementFromCompressed); + + console.log("G1 from compressed is valid", curve.G1.isValid(g1ElementFromCompressed)); +} +// ffTest(); \ No newline at end of file diff --git a/conversion/package.json b/conversion/package.json index ab68083..2043295 100644 --- a/conversion/package.json +++ b/conversion/package.json @@ -9,5 +9,9 @@ }, "keywords": [], "author": "", - "license": "ISC" + "license": "ISC", + "dependencies": { + "bigint-buffer": "^1.1.5", + "ffjavascript": "^0.2.63" + } } diff --git a/lib/ak-381/groth16.ak b/lib/ak-381/groth16.ak index c132a9b..1dc92de 100644 --- a/lib/ak-381/groth16.ak +++ b/lib/ak-381/groth16.ak @@ -85,6 +85,9 @@ pub fn groth_verify( // } test bls_point_construction() { - let point_1 = #"184bb665c37ff561a89ec2122dd343f20e0f4cbcaec84e3c3052ea81d1834e192c426074b02ed3dca4e7676ce4ce48ba" + let point_g1 = #"b28cb29bc282be68df977b35eb9d8e98b3a0a3fc7c372990bddc50419ca86693e491755338fed4fb42231a7c081252ce" + + let point_g2 = #"8cd68a7186a908212680a0234d8210c20328f8fb3ce1d69c9aec9330a5802d6cfaf6d7cf3176133221c19188590cb4141874ea7bbfcb9872931e115d882c46b90c3dcbcee10062d1c9b9b0a691d7bec7d2735f06495c7f71dea210e55b2782df" + True } \ No newline at end of file From 3baa0e19780e2186fad0bed99f4a5c9cadf16fdf Mon Sep 17 00:00:00 2001 From: AgustinBadi Date: Tue, 27 Feb 2024 12:15:34 -0300 Subject: [PATCH 4/8] Fix conversion on IC fields --- conversion/index.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/conversion/index.js b/conversion/index.js index 8ee2fe8..2da6c96 100644 --- a/conversion/index.js +++ b/conversion/index.js @@ -104,7 +104,14 @@ async function convertVerificationKeyToUncompressed(verificationKey) { "vk_beta_2": await compressedG2(verificationKey.vk_beta_2), "vk_gamma_2": await compressedG2(verificationKey.vk_gamma_2), "vk_delta_2": await compressedG2(verificationKey.vk_delta_2), - "IC": verificationKey.IC.map(async (item) => await compressedG1(item)), + "IC": await Promise.all(verificationKey.IC.map(async (item) => { + try { + return await compressedG1(item); + } catch (error) { + console.error('Error processing item:', item, error); + return null; + } + })), } return uncompressedVerificationKey; @@ -158,4 +165,6 @@ async function ffTest() { console.log("G1 from compressed is valid", curve.G1.isValid(g1ElementFromCompressed)); } -// ffTest(); \ No newline at end of file +// ffTest(); + + From db6c429e58b9284550aa0ffe0fb572813eb4741a Mon Sep 17 00:00:00 2001 From: AgustinBadi Date: Tue, 27 Feb 2024 12:16:19 -0300 Subject: [PATCH 5/8] Fix groth verify test --- lib/ak-381/groth16.ak | 68 +++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 38 deletions(-) diff --git a/lib/ak-381/groth16.ak b/lib/ak-381/groth16.ak index 1dc92de..3f00127 100644 --- a/lib/ak-381/groth16.ak +++ b/lib/ak-381/groth16.ak @@ -51,43 +51,35 @@ pub fn groth_verify( // Test (3 Factorial problem) -// test groth_verify_1() { -// // Template of VK -// let vk: SnarkVerificationKey = -// SnarkVerificationKey { -// nPublic: 2, -// vkAlpha: #"e3d9e248feda194cb6fa0a3b64fd2a380cb5e94836bf8148bf97ebcbb5819d9a78f63102f0293c104bcbb2f810d8eb00", -// vkBeta: #"1874ea7bbfcb9872931e115d882c46b90c3dcbcee10062d1c9b9b0a691d7bec7d2735f06495c7f71dea210e55b2782dfcd68a7186a908212680a0234d8210c20328f8fb3ce1d69c9aec9330a5802d6cfaf6d7cf3176133221c19188590cb4100", -// vkGamma: #"24aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb0013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e", -// vkDelta: #"2af2f9f515c65af6a9a6c294c738590104376a0af44731d6699db6a286608774243f7d1dddc4605eb340e65e15060a00138231fcec443fbdeb1079ff126b8f69bd8579ffe82d39923214d4345395beee60200288fa20c97ae50f3212131b6f88", -// vkAlphaBeta: [ -// #"93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8", -// ], -// vkIC: [ -// #"15813c90d3455acb8608fdf66e8601f24ef048f3fdf9384862d77c72cb5cddfde2b307976b1b0319c42ba985f94be60a", -// #"41a0e6370c054be0f9acce08e97f6d5702d9daa9e9a934e8a377f553593baa1c58062adc73d63558653422d54d6f5000", -// #"e02a87c519c3145f984d25fdf769f74fbc36626c385d4554fb4bc1d7a12cbf669d40f257023b8b3c9a31e631aa8f9800", -// ], -// } +test groth_verify_1() { + // Template of VK + let vk: SnarkVerificationKey = + SnarkVerificationKey { + nPublic: 2, + vkAlpha: #"8e3d9e248feda194cb6fa0a3b64fd2a380cb5e94836bf8148bf97ebcbb5819d9a78f63102f0293c104bcbb2f810d8eb4", + vkBeta: #"8cd68a7186a908212680a0234d8210c20328f8fb3ce1d69c9aec9330a5802d6cfaf6d7cf3176133221c19188590cb4141874ea7bbfcb9872931e115d882c46b90c3dcbcee10062d1c9b9b0a691d7bec7d2735f06495c7f71dea210e55b2782df", + vkGamma: #"93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8", + vkDelta: #"938231fcec443fbdeb1079ff126b8f69bd8579ffe82d39923214d4345395beee60200288fa20c97ae50f3212131b6f8802af2f9f515c65af6a9a6c294c738590104376a0af44731d6699db6a286608774243f7d1dddc4605eb340e65e15060a5", + vkAlphaBeta: [ + #"93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8", + ], + vkIC: [ + #"b5813c90d3455acb8608fdf66e8601f24ef048f3fdf9384862d77c72cb5cddfde2b307976b1b0319c42ba985f94be60a", + #"a41a0e6370c054be0f9acce08e97f6d5702d9daa9e9a934e8a377f553593baa1c58062adc73d63558653422d54d6f50c", + #"8e02a87c519c3145f984d25fdf769f74fbc36626c385d4554fb4bc1d7a12cbf669d40f257023b8b3c9a31e631aa8f981", + ], + } -// // Template of Proof -// let pk: Proof = -// Proof { -// piA: #"128cb29bc282be68df977b35eb9d8e98b3a0a3fc7c372990bddc50419ca86693e491755338fed4fb42231a7c081252ce", -// piB: #"e66ad6d86c7c76c468a32c9c0080eea0219d0953b44b1c4f5605afb1e5a3193264ff730222e94f55207628235f3b420019215e5bc481ba6552384c89c23d45bd650b69462868248bfbb83aee7060579404dba41c781dec7c2bec5fccec06842e", -// piC: #"86a574105c0da95915c36025637e5b80c7c00c4a264b529b465c273ade3e38f15dc7840498a1aefb44a24a0070a2ff00", -// } -// // Template of public values -// let public_values: List = -// [562, 3] + // Template of Proof + let pk: Proof = + Proof { + piA: #"b28cb29bc282be68df977b35eb9d8e98b3a0a3fc7c372990bddc50419ca86693e491755338fed4fb42231a7c081252ce", + piB: #"b9215e5bc481ba6552384c89c23d45bd650b69462868248bfbb83aee7060579404dba41c781dec7c2bec5fccec06842e0e66ad6d86c7c76c468a32c9c0080eea0219d0953b44b1c4f5605afb1e5a3193264ff730222e94f55207628235f3b423", + piC: #"886a574105c0da95915c36025637e5b80c7c00c4a264b529b465c273ade3e38f15dc7840498a1aefb44a24a0070a2ff6", + } + // Template of public values + let public_values: List = + [562, 3] -// groth_verify(vk, pk, public_values) -// } - -test bls_point_construction() { - let point_g1 = #"b28cb29bc282be68df977b35eb9d8e98b3a0a3fc7c372990bddc50419ca86693e491755338fed4fb42231a7c081252ce" - - let point_g2 = #"8cd68a7186a908212680a0234d8210c20328f8fb3ce1d69c9aec9330a5802d6cfaf6d7cf3176133221c19188590cb4141874ea7bbfcb9872931e115d882c46b90c3dcbcee10062d1c9b9b0a691d7bec7d2735f06495c7f71dea210e55b2782df" - - True -} \ No newline at end of file + groth_verify(vk, pk, public_values) +} From 171e3da5904127605dd194e99bb4370d1ec92616 Mon Sep 17 00:00:00 2001 From: AgustinBadi Date: Wed, 28 Feb 2024 01:56:49 -0300 Subject: [PATCH 6/8] Fix SnarkVerificationKey & Proof type definition --- lib/ak-381/groth16.ak | 77 ++++++++++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 30 deletions(-) diff --git a/lib/ak-381/groth16.ak b/lib/ak-381/groth16.ak index 3f00127..b2f2b64 100644 --- a/lib/ak-381/groth16.ak +++ b/lib/ak-381/groth16.ak @@ -1,30 +1,43 @@ -use aiken.{G1Element, G2Element} +use aiken.{G1Element} // ,MillerLoopResult use aiken/builtin.{ - bls12_381_final_verify, bls12_381_g1_add, bls12_381_g1_scalar_mul, - bls12_381_g1_uncompress, bls12_381_miller_loop, - bls12_381_mul_miller_loop_result, + bls12_381_final_verify, bls12_381_g1_add, bls12_381_g1_compress, + bls12_381_g1_scalar_mul, bls12_381_g1_uncompress, bls12_381_g2_uncompress, + bls12_381_miller_loop, bls12_381_mul_miller_loop_result, } -use aiken/list.{head, map2, reduce, tail} +use aiken/list.{head, map, map2, reduce, tail} pub type SnarkVerificationKey { nPublic: Int, - vkAlpha: G1Element, - vkBeta: G2Element, - vkGamma: G2Element, - vkDelta: G2Element, - vkAlphaBeta: List, - vkIC: List, + // G1Element + vkAlpha: ByteArray, + // G2Element + vkBeta: ByteArray, + // G2Element + vkGamma: ByteArray, + // G2Element + vkDelta: ByteArray, + // List + vkAlphaBeta: List, + // List + vkIC: List, } +// pub type Proof { - piA: G1Element, - piB: G2Element, - piC: G1Element, + // G1Element + piA: ByteArray, + // G2Element + piB: ByteArray, + // G1Element + piC: ByteArray, } -pub fn pairing(g1: G1Element, g2: G2Element) { - bls12_381_miller_loop(g1, g2) +pub fn pairing(g1: ByteArray, g2: ByteArray) { + bls12_381_miller_loop( + bls12_381_g1_uncompress(g1), + bls12_381_g2_uncompress(g2), + ) } pub fn groth_verify( @@ -37,10 +50,14 @@ pub fn groth_verify( let eAB = pairing(proof.piA, proof.piB) let eAlphaBeta = pairing(vk.vkAlpha, vk.vkBeta) - expect Some(vkICHead) = head(vk.vkIC) - expect Some(vkICTail) = tail(vk.vkIC) + expect Some(vk_ic_head) = head(vk.vkIC) + expect Some(vk_ic_tail) = tail(vk.vkIC) + let vkICHead: G1Element = bls12_381_g1_uncompress(vk_ic_head) + let vkICTail: List = + map(vk_ic_tail, fn(n) { bls12_381_g1_uncompress(n) }) let derived_vkIC = map2(public, vkICTail, bls12_381_g1_scalar_mul) - let vkI = reduce(derived_vkIC, vkICHead, bls12_381_g1_add) + let vkI = + reduce(derived_vkIC, vkICHead, bls12_381_g1_add) |> bls12_381_g1_compress() let eIGamma = pairing(vkI, vk.vkGamma) let eCDelta = pairing(proof.piC, vk.vkDelta) @@ -56,26 +73,26 @@ test groth_verify_1() { let vk: SnarkVerificationKey = SnarkVerificationKey { nPublic: 2, - vkAlpha: #"8e3d9e248feda194cb6fa0a3b64fd2a380cb5e94836bf8148bf97ebcbb5819d9a78f63102f0293c104bcbb2f810d8eb4", - vkBeta: #"8cd68a7186a908212680a0234d8210c20328f8fb3ce1d69c9aec9330a5802d6cfaf6d7cf3176133221c19188590cb4141874ea7bbfcb9872931e115d882c46b90c3dcbcee10062d1c9b9b0a691d7bec7d2735f06495c7f71dea210e55b2782df", - vkGamma: #"93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8", - vkDelta: #"938231fcec443fbdeb1079ff126b8f69bd8579ffe82d39923214d4345395beee60200288fa20c97ae50f3212131b6f8802af2f9f515c65af6a9a6c294c738590104376a0af44731d6699db6a286608774243f7d1dddc4605eb340e65e15060a5", + vkAlpha: #"8e3d9e248feda194cb6fa0a3b64fd2a380cb5e94836bf8148bf97ebcbb5819d9a78f63102f0293c104bcbb2f810d8eb4", + vkBeta: #"8cd68a7186a908212680a0234d8210c20328f8fb3ce1d69c9aec9330a5802d6cfaf6d7cf3176133221c19188590cb4141874ea7bbfcb9872931e115d882c46b90c3dcbcee10062d1c9b9b0a691d7bec7d2735f06495c7f71dea210e55b2782df", + vkGamma: #"93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8", + vkDelta: #"938231fcec443fbdeb1079ff126b8f69bd8579ffe82d39923214d4345395beee60200288fa20c97ae50f3212131b6f8802af2f9f515c65af6a9a6c294c738590104376a0af44731d6699db6a286608774243f7d1dddc4605eb340e65e15060a5", vkAlphaBeta: [ - #"93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8", + #"93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8", ], vkIC: [ - #"b5813c90d3455acb8608fdf66e8601f24ef048f3fdf9384862d77c72cb5cddfde2b307976b1b0319c42ba985f94be60a", - #"a41a0e6370c054be0f9acce08e97f6d5702d9daa9e9a934e8a377f553593baa1c58062adc73d63558653422d54d6f50c", - #"8e02a87c519c3145f984d25fdf769f74fbc36626c385d4554fb4bc1d7a12cbf669d40f257023b8b3c9a31e631aa8f981", + #"b5813c90d3455acb8608fdf66e8601f24ef048f3fdf9384862d77c72cb5cddfde2b307976b1b0319c42ba985f94be60a", + #"a41a0e6370c054be0f9acce08e97f6d5702d9daa9e9a934e8a377f553593baa1c58062adc73d63558653422d54d6f50c", + #"8e02a87c519c3145f984d25fdf769f74fbc36626c385d4554fb4bc1d7a12cbf669d40f257023b8b3c9a31e631aa8f981", ], } // Template of Proof let pk: Proof = Proof { - piA: #"b28cb29bc282be68df977b35eb9d8e98b3a0a3fc7c372990bddc50419ca86693e491755338fed4fb42231a7c081252ce", - piB: #"b9215e5bc481ba6552384c89c23d45bd650b69462868248bfbb83aee7060579404dba41c781dec7c2bec5fccec06842e0e66ad6d86c7c76c468a32c9c0080eea0219d0953b44b1c4f5605afb1e5a3193264ff730222e94f55207628235f3b423", - piC: #"886a574105c0da95915c36025637e5b80c7c00c4a264b529b465c273ade3e38f15dc7840498a1aefb44a24a0070a2ff6", + piA: #"b28cb29bc282be68df977b35eb9d8e98b3a0a3fc7c372990bddc50419ca86693e491755338fed4fb42231a7c081252ce", + piB: #"b9215e5bc481ba6552384c89c23d45bd650b69462868248bfbb83aee7060579404dba41c781dec7c2bec5fccec06842e0e66ad6d86c7c76c468a32c9c0080eea0219d0953b44b1c4f5605afb1e5a3193264ff730222e94f55207628235f3b423", + piC: #"886a574105c0da95915c36025637e5b80c7c00c4a264b529b465c273ade3e38f15dc7840498a1aefb44a24a0070a2ff6", } // Template of public values let public_values: List = From 14540cabc9de2c2c9421b2dc57cdcfd9b422018b Mon Sep 17 00:00:00 2001 From: AgustinBadi Date: Wed, 28 Feb 2024 03:04:02 -0300 Subject: [PATCH 7/8] Fix proof definition & Correct snarkjs .json files --- 3_fac/proof.json | 16 ++++++++-------- 3_fac/public.json | 2 +- conversion/proof.json | 16 ++++++++-------- lib/ak-381/groth16.ak | 9 ++++----- 4 files changed, 21 insertions(+), 22 deletions(-) diff --git a/3_fac/proof.json b/3_fac/proof.json index bd1b6e0..c6b8e1b 100644 --- a/3_fac/proof.json +++ b/3_fac/proof.json @@ -1,17 +1,17 @@ { "pi_a": [ - "2855044796369946382827590498028074399954178188404052044460392173044055949963055520226458797341961615378727946048206", - "3607648035569852498712601197821672930980634267835166890422819022801738069852659753344138199712325573228301683310722", + "1772906745093932579836240209170795378753849961020179699871382829952351871832226492308486069361021314982009562735843", + "1060554534780163267724558467040990415559388672742345068275893102509213372714145003450106197214490777822228922952656", "1" ], "pi_b": [ [ - "2216529660448908459446533763529433361366105288599360068340479797481300540437545794646354474692017045121551582868515", - "3867914260234198041425601044308116127196057132281581166005254303219906875747339103782814281378360746808337469178926" + "1358486866497956789862128624707494045021569151043861378376291931980647848946728667100167175682451312814072710519566", + "2892568549106560709617872008499143468746473249719383613874674515863767425449396997771169971147197463981607825748431" ], [ - "1959291290564527252319212910819685638672433971337410545600749187884388402471099470819029490531580085761840095948690", - "2011071151816425671679220330755640211651471450664831295838757345432821939838685402356499133954205160730680575168228" + "3774155091396786738197845866416007916901023392079351182692381863535299038480178339300724209059839391036807743888327", + "347983957076885655346478330294523987890867898739967665064964046997306980380350203447680726102390180081745831115215" ], [ "1", @@ -19,8 +19,8 @@ ] ], "pi_c": [ - "1295247664883995735684917166146384745983218062371398982813013851011964236053567050995264999819727337215745868836854", - "425196572825763797251425507115701065909002365213946325141666886779730764869850382851002816252507146444245309603107", + "759582637143989971983231319490726934998091227338384192733966680457083122987151635351010473067481154882106265771902", + "3759548828452159746415829615402022741023694117893369552443984303026454864934040458775681494473824000684596598390571", "1" ], "protocol": "groth16", diff --git a/3_fac/public.json b/3_fac/public.json index 9b00893..56cca27 100644 --- a/3_fac/public.json +++ b/3_fac/public.json @@ -1,4 +1,4 @@ [ - "562", + "561", "3" ] \ No newline at end of file diff --git a/conversion/proof.json b/conversion/proof.json index bd1b6e0..c6b8e1b 100644 --- a/conversion/proof.json +++ b/conversion/proof.json @@ -1,17 +1,17 @@ { "pi_a": [ - "2855044796369946382827590498028074399954178188404052044460392173044055949963055520226458797341961615378727946048206", - "3607648035569852498712601197821672930980634267835166890422819022801738069852659753344138199712325573228301683310722", + "1772906745093932579836240209170795378753849961020179699871382829952351871832226492308486069361021314982009562735843", + "1060554534780163267724558467040990415559388672742345068275893102509213372714145003450106197214490777822228922952656", "1" ], "pi_b": [ [ - "2216529660448908459446533763529433361366105288599360068340479797481300540437545794646354474692017045121551582868515", - "3867914260234198041425601044308116127196057132281581166005254303219906875747339103782814281378360746808337469178926" + "1358486866497956789862128624707494045021569151043861378376291931980647848946728667100167175682451312814072710519566", + "2892568549106560709617872008499143468746473249719383613874674515863767425449396997771169971147197463981607825748431" ], [ - "1959291290564527252319212910819685638672433971337410545600749187884388402471099470819029490531580085761840095948690", - "2011071151816425671679220330755640211651471450664831295838757345432821939838685402356499133954205160730680575168228" + "3774155091396786738197845866416007916901023392079351182692381863535299038480178339300724209059839391036807743888327", + "347983957076885655346478330294523987890867898739967665064964046997306980380350203447680726102390180081745831115215" ], [ "1", @@ -19,8 +19,8 @@ ] ], "pi_c": [ - "1295247664883995735684917166146384745983218062371398982813013851011964236053567050995264999819727337215745868836854", - "425196572825763797251425507115701065909002365213946325141666886779730764869850382851002816252507146444245309603107", + "759582637143989971983231319490726934998091227338384192733966680457083122987151635351010473067481154882106265771902", + "3759548828452159746415829615402022741023694117893369552443984303026454864934040458775681494473824000684596598390571", "1" ], "protocol": "groth16", diff --git a/lib/ak-381/groth16.ak b/lib/ak-381/groth16.ak index b2f2b64..0698c11 100644 --- a/lib/ak-381/groth16.ak +++ b/lib/ak-381/groth16.ak @@ -1,5 +1,4 @@ use aiken.{G1Element} -// ,MillerLoopResult use aiken/builtin.{ bls12_381_final_verify, bls12_381_g1_add, bls12_381_g1_compress, bls12_381_g1_scalar_mul, bls12_381_g1_uncompress, bls12_381_g2_uncompress, @@ -90,13 +89,13 @@ test groth_verify_1() { // Template of Proof let pk: Proof = Proof { - piA: #"b28cb29bc282be68df977b35eb9d8e98b3a0a3fc7c372990bddc50419ca86693e491755338fed4fb42231a7c081252ce", - piB: #"b9215e5bc481ba6552384c89c23d45bd650b69462868248bfbb83aee7060579404dba41c781dec7c2bec5fccec06842e0e66ad6d86c7c76c468a32c9c0080eea0219d0953b44b1c4f5605afb1e5a3193264ff730222e94f55207628235f3b423", - piC: #"886a574105c0da95915c36025637e5b80c7c00c4a264b529b465c273ade3e38f15dc7840498a1aefb44a24a0070a2ff6", + piA: #"8b84d092731c653b1accdda79c51e3f5d289bed7311189d927deadef0470e437e6d1d400634726512a79a015867424e3", + piB: #"92cb1c125816e4b522c7f430a5d74a61116b6189de7b2341f040194c02f10d9ef0cf081f4029444a65ea74e69d98b1cf08d3864087d5d2dee2ed6ab102f9b78e65d341f0824341a9fc25d0ea9dacccc5d355b4eddb0057949370a19c47135b0e", + piC: #"a4ef633c858a3ff194db50eacdf715f7296fb3d1202c54b543284e9656b69aa90f33ac0e2572d3ab847b88268dcd1f7e", } // Template of public values let public_values: List = - [562, 3] + [561, 3] groth_verify(vk, pk, public_values) } From c74aecdb774754a745182de6fb210c4ed2aa8640 Mon Sep 17 00:00:00 2001 From: AgustinBadi Date: Thu, 29 Feb 2024 13:32:15 -0300 Subject: [PATCH 8/8] Fix && Test the groth verify function --- lib/ak-381/groth16.ak | 228 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 219 insertions(+), 9 deletions(-) diff --git a/lib/ak-381/groth16.ak b/lib/ak-381/groth16.ak index 0698c11..ba8103e 100644 --- a/lib/ak-381/groth16.ak +++ b/lib/ak-381/groth16.ak @@ -1,10 +1,9 @@ -use aiken.{G1Element} use aiken/builtin.{ bls12_381_final_verify, bls12_381_g1_add, bls12_381_g1_compress, bls12_381_g1_scalar_mul, bls12_381_g1_uncompress, bls12_381_g2_uncompress, bls12_381_miller_loop, bls12_381_mul_miller_loop_result, } -use aiken/list.{head, map, map2, reduce, tail} +use aiken/list.{head, map2, reduce, tail} pub type SnarkVerificationKey { nPublic: Int, @@ -45,29 +44,47 @@ pub fn groth_verify( public: List, ) -> Bool { // let n = vk.nPublic - let eAB = pairing(proof.piA, proof.piB) let eAlphaBeta = pairing(vk.vkAlpha, vk.vkBeta) expect Some(vk_ic_head) = head(vk.vkIC) expect Some(vk_ic_tail) = tail(vk.vkIC) - let vkICHead: G1Element = bls12_381_g1_uncompress(vk_ic_head) - let vkICTail: List = - map(vk_ic_tail, fn(n) { bls12_381_g1_uncompress(n) }) - let derived_vkIC = map2(public, vkICTail, bls12_381_g1_scalar_mul) + //let vkICHead: G1Element = bls12_381_g1_uncompress(vk_ic_head) + //let vkICTail: List = + // map(vk_ic_tail, fn(n) { bls12_381_g1_uncompress(n) }) + let derived_vkIC = + map2( + public, + vk_ic_tail, + fn(a, b) { + bls12_381_g1_uncompress(b) + |> bls12_381_g1_scalar_mul(a, _) + |> bls12_381_g1_compress() + }, + ) + //let derived_vkIC = map2(public, vkICTail, bls12_381_g1_scalar_mul ) let vkI = - reduce(derived_vkIC, vkICHead, bls12_381_g1_add) |> bls12_381_g1_compress() + reduce( + derived_vkIC, + vk_ic_head, + fn(a, b) { + bls12_381_g1_add(bls12_381_g1_uncompress(a), bls12_381_g1_uncompress(b)) + |> bls12_381_g1_compress() + }, + ) let eIGamma = pairing(vkI, vk.vkGamma) let eCDelta = pairing(proof.piC, vk.vkDelta) + // * Miller functions let mlr1 = bls12_381_mul_miller_loop_result(eAlphaBeta, eIGamma) let mlr2 = bls12_381_mul_miller_loop_result(mlr1, eCDelta) + bls12_381_final_verify(eAB, mlr2) } // Test (3 Factorial problem) -test groth_verify_1() { +test groth_verify_pass_1() { // Template of VK let vk: SnarkVerificationKey = SnarkVerificationKey { @@ -99,3 +116,196 @@ test groth_verify_1() { groth_verify(vk, pk, public_values) } + +test groth_verify_fail_1() fail { + // Template of VK + let vk: SnarkVerificationKey = + SnarkVerificationKey { + nPublic: 2, + vkAlpha: #"8e3d9e248feda194cb6fa0a3b64fd2a380cb5e94836bf8148bf97ebcbb5819d9a78f63102f0293c104bcbb2f810d8eb4", + vkBeta: #"8cd68a7186a908212680a0234d8210c20328f8fb3ce1d69c9aec9330a5802d6cfaf6d7cf3176133221c19188590cb4141874ea7bbfcb9872931e115d882c46b90c3dcbcee10062d1c9b9b0a691d7bec7d2735f06495c7f71dea210e55b2782df", + vkGamma: #"93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8", + vkDelta: #"938231fcec443fbdeb1079ff126b8f69bd8579ffe82d39923214d4345395beee60200288fa20c97ae50f3212131b6f8802af2f9f515c65af6a9a6c294c738590104376a0af44731d6699db6a286608774243f7d1dddc4605eb340e65e15060a5", + vkAlphaBeta: [ + #"93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8", + ], + vkIC: [ + #"b5813c90d3455acb8608fdf66e8601f24ef048f3fdf9384862d77c72cb5cddfde2b307976b1b0319c42ba985f94be60a", + #"a41a0e6370c054be0f9acce08e97f6d5702d9daa9e9a934e8a377f553593baa1c58062adc73d63558653422d54d6f50c", + #"8e02a87c519c3145f984d25fdf769f74fbc36626c385d4554fb4bc1d7a12cbf669d40f257023b8b3c9a31e631aa8f981", + ], + } + + // Template of Proof + let pk: Proof = + Proof { + piA: #"a4ef633c858a3ff194db50eacdf715f7296fb3d1202c54b543284e9656b69aa90f33ac0e2572d3ab847b88268dcd1f7e", + piB: #"92cb1c125816e4b522c7f430a5d74a61116b6189de7b2341f040194c02f10d9ef0cf081f4029444a65ea74e69d98b1cf08d3864087d5d2dee2ed6ab102f9b78e65d341f0824341a9fc25d0ea9dacccc5d355b4eddb0057949370a19c47135b0e", + piC: #"8b84d092731c653b1accdda79c51e3f5d289bed7311189d927deadef0470e437e6d1d400634726512a79a015867424e3", + } + // Template of public values + let public_values: List = + [561, 3] + + groth_verify(vk, pk, public_values) +} + +test groth_verify_pass_2() { + // Template of VK + let vk: SnarkVerificationKey = + SnarkVerificationKey { + nPublic: 2, + vkAlpha: #"8e3d9e248feda194cb6fa0a3b64fd2a380cb5e94836bf8148bf97ebcbb5819d9a78f63102f0293c104bcbb2f810d8eb4", + vkBeta: #"8cd68a7186a908212680a0234d8210c20328f8fb3ce1d69c9aec9330a5802d6cfaf6d7cf3176133221c19188590cb4141874ea7bbfcb9872931e115d882c46b90c3dcbcee10062d1c9b9b0a691d7bec7d2735f06495c7f71dea210e55b2782df", + vkGamma: #"93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8", + vkDelta: #"938231fcec443fbdeb1079ff126b8f69bd8579ffe82d39923214d4345395beee60200288fa20c97ae50f3212131b6f8802af2f9f515c65af6a9a6c294c738590104376a0af44731d6699db6a286608774243f7d1dddc4605eb340e65e15060a5", + vkAlphaBeta: [ + #"93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8", + ], + vkIC: [ + #"b5813c90d3455acb8608fdf66e8601f24ef048f3fdf9384862d77c72cb5cddfde2b307976b1b0319c42ba985f94be60a", + #"a41a0e6370c054be0f9acce08e97f6d5702d9daa9e9a934e8a377f553593baa1c58062adc73d63558653422d54d6f50c", + #"8e02a87c519c3145f984d25fdf769f74fbc36626c385d4554fb4bc1d7a12cbf669d40f257023b8b3c9a31e631aa8f981", + ], + } + + // Template of Proof + let pk: Proof = + Proof { + piA: #"98ca847cc04a6f67ac85a628521450323d7aa5335d4c2c48e9780b659cf7ea8ece2d0b305c9ff9dcfb3e548d61bbaebe", + piB: #"a8e6ba4dbce6aa84de8ca1cd39d42353fcac89fe8cb800e728ada3ca4ae3b07baa68f76b9e4fa73eebf78cc609fa85d6166a3b69cd08cc59f2ff36e52dfdf231540a4212fdd4a142504c76066bddea342dd0183b2b11ed62cfc1497189a4db52", + piC: #"8bc8cc3f11483138cc55d5f0389e67231f9e8465e5cb4a5a668e6e298d5c4febb2a18e86881c84dd03c5d33db65af272", + } + // Template of public values + let public_values: List = + [8827, 7] + + groth_verify(vk, pk, public_values) +} + +test groth_verify_fail_2() fail { + // Template of VK + let vk: SnarkVerificationKey = + SnarkVerificationKey { + nPublic: 2, + vkAlpha: #"8e3d9e248feda194cb6fa0a3b64fd2a380cb5e94836bf8148bf97ebcbb5819d9a78f63102f0293c104bcbb2f810d8eb4", + vkBeta: #"8cd68a7186a908212680a0234d8210c20328f8fb3ce1d69c9aec9330a5802d6cfaf6d7cf3176133221c19188590cb4141874ea7bbfcb9872931e115d882c46b90c3dcbcee10062d1c9b9b0a691d7bec7d2735f06495c7f71dea210e55b2782df", + vkGamma: #"93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8", + vkDelta: #"938231fcec443fbdeb1079ff126b8f69bd8579ffe82d39923214d4345395beee60200288fa20c97ae50f3212131b6f8802af2f9f515c65af6a9a6c294c738590104376a0af44731d6699db6a286608774243f7d1dddc4605eb340e65e15060a5", + vkAlphaBeta: [ + #"93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8", + ], + vkIC: [ + #"b5813c90d3455acb8608fdf66e8601f24ef048f3fdf9384862d77c72cb5cddfde2b307976b1b0319c42ba985f94be60a", + #"a41a0e6370c054be0f9acce08e97f6d5702d9daa9e9a934e8a377f553593baa1c58062adc73d63558653422d54d6f50c", + #"8e02a87c519c3145f984d25fdf769f74fbc36626c385d4554fb4bc1d7a12cbf669d40f257023b8b3c9a31e631aa8f981", + ], + } + + // Template of Proof + let pk: Proof = + Proof { + piA: #"8bc8cc3f11483138cc55d5f0389e67231f9e8465e5cb4a5a668e6e298d5c4febb2a18e86881c84dd03c5d33db65af272", + piB: #"a8e6ba4dbce6aa84de8ca1cd39d42353fcac89fe8cb800e728ada3ca4ae3b07baa68f76b9e4fa73eebf78cc609fa85d6166a3b69cd08cc59f2ff36e52dfdf231540a4212fdd4a142504c76066bddea342dd0183b2b11ed62cfc1497189a4db52", + piC: #"8e02a87c519c3145f984d25fdf769f74fbc36626c385d4554fb4bc1d7a12cbf669d40f257023b8b3c9a31e631aa8f981", + } + // Template of public values + let public_values: List = + [8827, 7] + + groth_verify(vk, pk, public_values) +} + +test groth_verify_pass_3() { + // Template of VK + let vk: SnarkVerificationKey = + SnarkVerificationKey { + nPublic: 2, + vkAlpha: #"8e3d9e248feda194cb6fa0a3b64fd2a380cb5e94836bf8148bf97ebcbb5819d9a78f63102f0293c104bcbb2f810d8eb4", + vkBeta: #"8cd68a7186a908212680a0234d8210c20328f8fb3ce1d69c9aec9330a5802d6cfaf6d7cf3176133221c19188590cb4141874ea7bbfcb9872931e115d882c46b90c3dcbcee10062d1c9b9b0a691d7bec7d2735f06495c7f71dea210e55b2782df", + vkGamma: #"93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8", + vkDelta: #"938231fcec443fbdeb1079ff126b8f69bd8579ffe82d39923214d4345395beee60200288fa20c97ae50f3212131b6f8802af2f9f515c65af6a9a6c294c738590104376a0af44731d6699db6a286608774243f7d1dddc4605eb340e65e15060a5", + vkAlphaBeta: [ + #"93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8", + ], + vkIC: [ + #"b5813c90d3455acb8608fdf66e8601f24ef048f3fdf9384862d77c72cb5cddfde2b307976b1b0319c42ba985f94be60a", + #"a41a0e6370c054be0f9acce08e97f6d5702d9daa9e9a934e8a377f553593baa1c58062adc73d63558653422d54d6f50c", + #"8e02a87c519c3145f984d25fdf769f74fbc36626c385d4554fb4bc1d7a12cbf669d40f257023b8b3c9a31e631aa8f981", + ], + } + + // Template of Proof + let pk: Proof = + Proof { + piA: #"83c61ffc279768e4dfbab85ccfbe3a18522bb1cd9b2ebf2719be0a016c3a5ca16f39f14c5207920afc458e2018c57804", + piB: #"87a4af184495e4bdb45b690fa7b02efc65ac4684bac0913ed4c9735f5148a8b8223c3150476c2abadd940cfef24f1d27130eeae2791ca46cb6afe49c49b030bd1fc391d06e02c773b216e080a68d2ac55e6afc59468ff3dceb46cf6ea7b2b3f2", + piC: #"920d63da640fc265b6cd49dc2c4b18cf5d809872e9b7252575047a1473b228ff50390f6420343e861e2c007b59d15205", + } + // Template of public values + let public_values: List = + [16393, 13] + + groth_verify(vk, pk, public_values) +} + +test groth_verify_fail_3() fail { + // Template of VK + let vk: SnarkVerificationKey = + SnarkVerificationKey { + nPublic: 2, + vkAlpha: #"8e3d9e248feda194cb6fa0a3b64fd2a380cb5e94836bf8148bf97ebcbb5819d9a78f63102f0293c104bcbb2f810d8eb4", + vkBeta: #"8cd68a7186a908212680a0234d8210c20328f8fb3ce1d69c9aec9330a5802d6cfaf6d7cf3176133221c19188590cb4141874ea7bbfcb9872931e115d882c46b90c3dcbcee10062d1c9b9b0a691d7bec7d2735f06495c7f71dea210e55b2782df", + vkGamma: #"93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8", + vkDelta: #"938231fcec443fbdeb1079ff126b8f69bd8579ffe82d39923214d4345395beee60200288fa20c97ae50f3212131b6f8802af2f9f515c65af6a9a6c294c738590104376a0af44731d6699db6a286608774243f7d1dddc4605eb340e65e15060a5", + vkAlphaBeta: [ + #"93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8", + ], + vkIC: [ + #"b5813c90d3455acb8608fdf66e8601f24ef048f3fdf9384862d77c72cb5cddfde2b307976b1b0319c42ba985f94be60a", + #"a41a0e6370c054be0f9acce08e97f6d5702d9daa9e9a934e8a377f553593baa1c58062adc73d63558653422d54d6f50c", + #"8e02a87c519c3145f984d25fdf769f74fbc36626c385d4554fb4bc1d7a12cbf669d40f257023b8b3c9a31e631aa8f981", + ], + } + + // Template of Proof + let pk: Proof = + Proof { + piA: #"83c61ffc279768e4dfbab85ccfbe3a18522bb1cd9b2ebf2719be0a016c3a5ca16f39f14c5207920afc458e2018c57804", + piB: #"87a4af184495e4bdb45b690fa7b02efc65ac4684bac0913ed4c9735f5148a8b8223c3150476c2abadd940cfef24f1d27130eeae2791ca46cb6afe49c49b030bd1fc391d06e02c773b216e080a68d2ac55e6afc59468ff3dceb46cf6ea7b2b3f2", + piC: #"8bc8cc3f11483138cc55d5f0389e67231f9e8465e5cb4a5a668e6e298d5c4febb2a18e86881c84dd03c5d33db65af272", + } + // Template of public values + let public_values: List = + [16393, 13] + + groth_verify(vk, pk, public_values) +} +//test list_g1_equality() { +// [ +// #"8e02a87c519c3145f984d25fdf769f74fbc36626c385d4554fb4bc1d7a12cbf669d40f257023b8b3c9a31e631aa8f981", +// #"a41a0e6370c054be0f9acce08e97f6d5702d9daa9e9a934e8a377f553593baa1c58062adc73d63558653422d54d6f50c", +// #"8e02a87c519c3145f984d25fdf769f74fbc36626c385d4554fb4bc1d7a12cbf669d40f257023b8b3c9a31e631aa8f981", +// ] == [ +// #"8e02a87c519c3145f984d25fdf769f74fbc36626c385d4554fb4bc1d7a12cbf669d40f257023b8b3c9a31e631aa8f981", +// #"a41a0e6370c054be0f9acce08e97f6d5702d9daa9e9a934e8a377f553593baa1c58062adc73d63558653422d54d6f50c", +// #"8e02a87c519c3145f984d25fdf769f74fbc36626c385d4554fb4bc1d7a12cbf669d40f257023b8b3c9a31e631aa8f981", +// ] +//} + +//test map_ic_test() { +// let list_alfa = +// [ +// #"b5813c90d3455acb8608fdf66e8601f24ef048f3fdf9384862d77c72cb5cddfde2b307976b1b0319c42ba985f94be60a", +// ] +// +// let list_beta = +// [ +// #"b5813c90d3455acb8608fdf66e8601f24ef048f3fdf9384862d77c72cb5cddfde2b307976b1b0319c42ba985f94be60a", +// ] +// let map_over_alpha = map(list_alfa, fn(n) { bls12_381_g1_uncompress(n) }) +// map_over_alpha == list_beta +// //let check_lists = +// // map2(map_over_alpha, list_beta, fn(a, b) { bls12_381_g1_equal(a, b) }) +// //check_lists == [True] +//}