Skip to content

Commit

Permalink
fix input size and corresponding files
Browse files Browse the repository at this point in the history
  • Loading branch information
motemotech committed Nov 15, 2023
1 parent eb8817c commit ca3b577
Show file tree
Hide file tree
Showing 10 changed files with 239 additions and 21 deletions.
Empty file.
6 changes: 3 additions & 3 deletions packages/circom-circuit/src/verify-gov-sig.circom
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ template CalculateHash(k) {
}

template VerifyInclusion() {
signal input tbsCert[1586];
signal input tbsCert[1600];
signal input modulus[17];

component num2Bits0[256];
Expand Down Expand Up @@ -65,7 +65,7 @@ template VerifyInclusion() {
}

template HashTbs() {
signal input tbsCert[1586];
signal input tbsCert[1600];
signal output hashedTbsInNum[3];

component num2Bits[1306];
Expand Down Expand Up @@ -113,7 +113,7 @@ template MynaVerifyGovSig(n, k) {
signal input modulus[k]; // rsa public key, verified with smart contract. split up into k parts of n bits each.
signal input govModulus[k];
signal input govSignature[k];
signal input tbsCert[1586];
signal input tbsCert[1600];

var messageLength = (256 + n) \ n;

Expand Down
10 changes: 5 additions & 5 deletions packages/contracts/src/base/ZKMynaWallet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -144,19 +144,19 @@ contract ZKMynaWallet is
// TODO: Check modulus preimage
function validateGovSignature(bytes32[43] memory proof)
public
returns (uint256 validationData)
onlySelf()
{
(uint256[2] memory _pA, uint256[2][2] memory _pB, uint256[2] memory _pC, uint256[SIGNALS_NUM_FOR_GOV_SIG] memory _pubSignals) =
_splitToGovSigProof(proof);

try govSigVerifier.verifyProof(_pA, _pB, _pC, _pubSignals) returns (bool valid) {
if (!valid) {
return 1;
} else {
if (valid) {
_setVerified();
} else {
revert();
}
} catch {
return 1;
revert();
}
}

Expand Down
1 change: 0 additions & 1 deletion packages/contracts/src/base/ZKMynaWalletFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
import "@account-abstraction/contracts/interfaces/IEntryPoint.sol";
import {ZKMynaWallet} from "./ZKMynaWallet.sol";
import { IMynaGovSigVerifier, IMynaUserSigVerifier } from "@interfaces/IMynaWalletVerifier.sol";

/**
* Factory contract for MynaWallet.
*/
Expand Down
8 changes: 4 additions & 4 deletions packages/contracts/src/circom-verifier/govSigVerifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ contract MynaGovSigVerifier {
uint256 constant gammax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781;
uint256 constant gammay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531;
uint256 constant gammay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930;
uint256 constant deltax1 = 18745487737772393836870720416445145076891177703175978585765325077723843873761;
uint256 constant deltax2 = 20915598045433281500794185594698103226112783390757459836770054758722353399857;
uint256 constant deltay1 = 16970825186035861852878242799632852954890426875552238417608877466851853966539;
uint256 constant deltay2 = 2430216772480925566948196712639305250098054570199333681223406250639853344691;
uint256 constant deltax1 = 13852857032342530930605263284505234428798439870600148209788340828000245353516;
uint256 constant deltax2 = 8599542926507262441875995612307797602874511416313171215604391079363790013704;
uint256 constant deltay1 = 4041894675951619254150017120139787509960291060047231188967935357150647832908;
uint256 constant deltay2 = 2375183444257265201186845007594212213218041674327526084247182307321215296492;


uint256 constant IC0x = 7441607095611835814370721145253227673217654661770423448604533840761042303372;
Expand Down
9 changes: 5 additions & 4 deletions packages/script/js/der_to_decimalArray.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ while (outputLen < 1600) {
outputArray.push(0);
outputLen = outputArray.length;
}
console.log(outputArray);

const data = JSON.stringify(outputArray);
fs.writeFile(OUTPUT_PATH, data, (err) => {
if (err) throw err;
});
// const data = JSON.stringify(outputArray);
// fs.writeFile(OUTPUT_PATH, data, (err) => {
// if (err) throw err;
// });
4 changes: 3 additions & 1 deletion packages/script/js/extract_tbs_certificate.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const PATH = join(__dirname, '../../certs/myna_cert.pem')

// Read the PEM file
const pem = readFileSync(PATH, 'utf8')
console.log(typeof(pem));

// Remove the '-----BEGIN CERTIFICATE-----' and '-----END CERTIFICATE-----' lines
const base64String = pem
Expand All @@ -14,6 +15,7 @@ const base64String = pem
.replace(/\n/g, '')

const der = Buffer.from(base64String, 'base64')
console.log(typeof(der));

// certificate consists of
// - tbsCertificate 人によって長さが違う
Expand All @@ -25,4 +27,4 @@ const newSize = der.length - cutSize

// 先頭4バイトは SEQUENCE の長さ
const tbsCertificate = der.slice(4, newSize)
console.log(tbsCertificate.toString('hex'))
// console.log(tbsCertificate.toString('hex'))
26 changes: 26 additions & 0 deletions packages/script/js/generateProof.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const fs = require('fs');
const { join } = require('path');
const snarkjs = require('snarkjs');

const INPUT_PATH = join(__dirname, '../../circom-circuit/gov-sig-setup/input.json');
const input = JSON.parse(fs.readFileSync(INPUT_PATH, 'utf8'));
const WASM_PATH = join(__dirname, "../../circom-circuit/gov-sig-build/verify-gov-sig_js/verify-gov-sig.wasm");
const ZKEY_PATH = join(__dirname, "../../circom-circuit/gov-sig-setup/circuit_final.zkey");

async function main() {
const { proof, publicSignals } = await snarkjs.groth16.fullProve(
input,
WASM_PATH,
ZKEY_PATH);
console.log("publicSignals", publicSignals);
console.log("proof", proof);

console.log("generating calldata");

const calldataBlob = await snarkjs.groth16.exportSolidityCallData(proof, publicSignals);
const calldata = calldataBlob.split(',');

console.log(calldata);

}
main().catch(console.error);
8 changes: 6 additions & 2 deletions packages/script/js/pem_to_der.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

188 changes: 187 additions & 1 deletion packages/script/ts/verify_tbs_cert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,4 +160,190 @@ async function main() {
main().catch(err => {
console.error(err)
process.exit(1)
})
})

// Helper functions
function createInitCode(identityCommitment: Hex, salt: bigint): Hex {
const initCode = concat([
FACTORY_ADDRESS,
encodeFunctionData({
abi: factoryABI,
functionName: 'createAccount',
args: [identityCommitment, salt]
})
])
return initCode
}

async function getAddress(initCode: Hex): Promise<[Address, boolean]> {
const senderAddress = await getSenderAddress(publicClient, {
initCode,
entryPoint: ENTRY_POINT_ADDRESS
})
const code = await publicClient.getBytecode({ address: senderAddress })
return [senderAddress, code === undefined]
}

async function getUserOperationGasPrice(): Promise<GetUserOperationGasPriceReturnType> {
const userOperationGasPrice = await pimlicoBundlerClient.getUserOperationGasPrice()
return userOperationGasPrice
}

async function getNonce(senderAddress: Address) {
const account = getContract({
address: senderAddress,
abi: walletABI,
publicClient
})
const nonce = await account.read.getNonce()
return nonce
}

function generateDummyZKPSignature(): Hex {
return '0x198705050f6c5ec7ce8d0e3beacd67f2143019213cd285db697cb26ce1aff66716c8f21aa09f9dbada9c17d9ec83dd59e484f12c50689a2df48ef41adc9cde6c0e6da20c7b38c80c3f3cc16f8585cca37ddd80d909adcc32a0ae9a524afe195012083fe96e774eedf83bed1d379c40580426c381250d997e7e9dc9222f5e05d504df90947b055418cb10bf5a37eccdb804797dfc9ad53df220bbde205e7ad98006f65c9ff03b25169869a2f65e98f169eb4859c33cbb3f2e86da11572a21d2891f61fa72e55a56acee6cc98bb28be2274ee93e9d0be4d89a4af39ab37e60123b262fcfceeb87403f870fcec0900de2a1c2908b592ec1c98255fe2ecd2fbbf2bf1efdb9c5013a9706e0c16627c36de8dd60731bd96d5bf705bf3db1801267790a00000000000000000000000000000000014a92b6297dc8b5ffb107949f196baf00000000000000000000000000000000009e1187340bc4fd07167462a34b64310000000000000000000000000000000000ed7428f4493d8d819efa6bf71d77c90000000000000000000000000000000000b5d4ef1307ccccefcd331654707e7000000000000000000000000000000000016e2d82bcf9fc45163273840ea8832200000000000000000000000000000000003fb7da2955b7e1c2877da6184af1c800000000000000000000000000000000013876f6867269b091706adf9e6b1ec000000000000000000000000000000000015822b6a7a18159d530974b18a1bb530000000000000000000000000000000001a29c85d823645c5994c167b83090590000000000000000000000000000000001d43619afdf3f353529fdfa1b4f2152000000000000000000000000000000000189975eed5aa142beae1260bf663efd0000000000000000000000000000000001732fd6983070ea2046900a7c3adb430000000000000000000000000000000001564393bb317edbb1cb57cbfa8049ba0000000000000000000000000000000000ac9e95037ab029dae9f9cea8d81c97000000000000000000000000000000000186b47a64af8ea1b79a07d9a97b846b00000000000000000000000000000000007a42797379374010d310f32536bd9f000000000000000000000000000000000000458b290364b9b0bd1d68984c1896000000000000000000000000000000000154b3e7d909e2e281d716c1269b212d0000000000000000000000000000000000482dd4f9954d79b2b46c1e38767ef6000000000000000000000000000000000000000000000000000000000000375c'
}

async function sponsorUserOperation(
userOperation: PartialBy<UserOperation, 'callGasLimit' | 'preVerificationGas' | 'verificationGasLimit'>
): Promise<UserOperation> {
// 有効期限終了(0 で指定することで validAfter 以後有効となる)
const validUntil = 0
// 有効期限開始
const validAfter = Math.ceil(Date.now() / 1000)
// exchangeRate (現状利用しないため 0 )
const exchangeRate = 0n

// generate paymasterAndData with dummy signature
let paymasterAndData = concat([
PAYMASTER_ADDRESS,
encodeAbiParameters(
[
{ name: 'validUntil', type: 'uint48' },
{ name: 'validAfter', type: 'uint48' },
{ name: 'address', type: 'address' },
{ name: 'exchangeRate', type: 'uint256' }
],
[validUntil, validAfter, '0x0000000000000000000000000000000000000000', exchangeRate]
),
// dummy signature
await paymasterAccount.signMessage({ message: '0xdeadbeef' })
])

// assign dummy paymasterAndData
userOperation.paymasterAndData = paymasterAndData

const estimatedGas = await pimlicoBundlerClient.estimateUserOperationGas({
userOperation,
entryPoint: ENTRY_POINT_ADDRESS
})

// assign estimated gas
// estimated gas で返される値が信頼できない場合がある
userOperation.callGasLimit = estimatedGas.callGasLimit
userOperation.preVerificationGas = estimatedGas.preVerificationGas
// 4倍しておく
userOperation.verificationGasLimit =
estimatedGas.verificationGasLimit * 4n < 500000n ? 500000n : estimatedGas.verificationGasLimit * 4n

// calculate paymaster hash
const hash = (await publicClient.readContract({
address: PAYMASTER_ADDRESS,
abi: paymasterABI,
functionName: 'getHash',
args: [userOperation, validUntil, validAfter, '0x0000000000000000000000000000000000000000', exchangeRate]
})) as Hex

const signature = await paymasterAccount.signMessage({
message: { raw: hash }
})

// sign paymaster hash
userOperation.paymasterAndData = concat([
PAYMASTER_ADDRESS,
encodeAbiParameters(
[
{ name: 'validUntil', type: 'uint48' },
{ name: 'validAfter', type: 'uint48' },
{ name: 'address', type: 'address' },
{ name: 'exchangeRate', type: 'uint256' }
],
[validUntil, validAfter, '0x0000000000000000000000000000000000000000', 0n]
),
signature
])

return userOperation as UserOperation
}

function getTestRsaKey() {
return new NodeRSA(`-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAj2BHBk9AD9L/gK1lacLP/COAeeLLGGSDBaWbnx84lzD5v5te
PkNviAZcBiQccYm6Q7atvl7HqXnUtC8qRQzRnoB15agXsEMooNFuv8trwJqWAgIX
r2IY83ZdvBKRMe3QBEcqtFkIvwLsNbfAROHJAPffF5/BnJSDWALljEMrxzzuVBSK
byTXMWzKGVeRyH4H6FsH+Atx3cFbmwU+bwJlqOgcJ8dUbeo4y7lRynHDhIkrgd8S
yMsERPngTSTQ0zI/qFcHW+JnRvS3MaGGpRzsJBUVl7nTHJ73jbg/J+8Nlz1NKi2K
kJPHEYv4YyJgOhfXgUoF9hUJY7cqJ19kWgmTGQIDAQABAoIBAHSqkyC/PBGkT+QV
NIBq1XMGMHT95uViZHsj1w4UCah9YbxYYMepeAfnpNoaaEq7F6Yh8B8IYM+3Iy27
c1ncpHWlckn+DciP3W9+++91R6jiIU5hBYTg/gyeNIflU+Cc8reIcWdvS36ikjLj
4sAqObVf/Vjr1k/jST1EniUUQ3tLCKaaePcuHPJ3fcthrKX3doZ9ym2PNn+XYecz
QE6QR5txEowPN7MVyExaP8TaYZdRQGSE0cMruxdbCebhSKgw7PtrIOjq6LPhDzDy
gUG9kLI/lI4FlDkJYC4hOdezycZ+T13KLHYsGnw+dsC4PAqk4w/JVaqgut4jtUU6
pe8XNQECgYEA807085nVLkV6cEJOHRxVtS5oblw8ZI27deg2mQpBBEaD8/H7IpR2
R1nyNj5UV6Ba8UhBGG+9CLjMrm9yuefydPZN6ki+yxK0d1aF20OjllFKEolKJzG7
ZyE+xulCU9cKHajvTJWra9tKvyheNd+ct1Ae5G47DB9pmzKX/uFJclUCgYEAltrd
OrufmMoNnc0N8uha4SM68s3+pz2tGbQ954Qqux3Co+JgQwsVL0OuUT198BG2wSYB
kTySLU3bKHx68Z8p4HMXVzLheJI3eob+2yJ/UIZKjoz3dO4MsFb2KseiWXYeV7Gp
uUE47KVGlfC6gNM32m2iKB361i1YJDo2oxn7ybUCgYEA3toz/Cerng0fP1FL8Nfy
HNhb6LFs04EJ8c32rCg7MupPlBHQv3SR/XqCInLml7gVdCiFDxfRYfq55w/HWkX7
ymuLJArrTl9ckm3afuGuJVFhcibzl4CysJw/vrsJ+HbfGhmQzWnNMCYUiZA08k1V
YoXtNbdNOCZReUhW9apttl0CgYBxiHiVWl2r1O1YhNnppZu38xbLY+MypMVhIfix
BBRQzP4O7zF5Y57m+m338GqWwg4j4WGul8J/3CeDmePBcwNGS/gWBVIRtyGP0od+
DsF4rgjwrgES/JGKKXiNC8AQykfdwfU1WnPoDh9Ie2sxx0Uy2+39eUqt5GSAp1s1
dzm7PQKBgQDTWs2NKZuB4b6o0CEHte+SoINfHvVFDWbotJAZ//l+z1SmTlH7qb+/
jsDhmF/uizOdlopee6fdDaIzYNxEOseI2dx3UjLk6QYqtPBCu9KJ1juSeCReMSjH
BWhALtiQk07pmfH+zFEYEwBhZ0OKaUAZuabat21qFr0cuX1VN8jtBQ==
-----END RSA PRIVATE KEY-----`)
}

function bigint_to_array(n: number, k: number, x: bigint) {
let mod = 1n
for (let idx = 0; idx < n; idx++) {
mod = mod * 2n
}

const ret: bigint[] = []
let x_temp: bigint = x
for (let idx = 0; idx < k; idx++) {
ret.push(x_temp % mod)
x_temp = x_temp / mod
}
return ret
}

async function verifyZKProof(callData: string): Promise<boolean> {
const argv = callData
.replace(/["[\]\s]/g, '')
.split(',')
.map(x => BigInt(x).toString())

const a = [argv[0], argv[1]]
const b = [
[argv[2], argv[3]],
[argv[4], argv[5]]
]
const c = [argv[6], argv[7]]
const publicInputs = argv.slice(8)

try {
const res = await publicClient.readContract({
address: VERIFIER_ADDRESS,
abi: verifierABI,
functionName: 'verifyProof',
args: [a, b, c, publicInputs]
})
return res as boolean
} catch (e) {
console.log(e)
return false
}
}

0 comments on commit ca3b577

Please sign in to comment.