Skip to content

Commit 9cca787

Browse files
authored
Merge pull request #151 from hyperledger-labs/lock-4-kyc
Add locking to Zeto_AnonNullifierKyc
2 parents ba786a6 + 397cc04 commit 9cca787

29 files changed

+2053
-234
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright © 2025 Kaleido, Inc.
2+
//
3+
// SPDX-License-Identifier: Apache-2.0
4+
//
5+
// Licensed under the Apache License, Version 2.0 (the "License");
6+
// you may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing, software
12+
// distributed under the License is distributed on an "AS IS" BASIS,
13+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
// See the License for the specific language governing permissions and
15+
// limitations under the License.
16+
pragma solidity ^0.8.27;
17+
18+
import {Commonlib} from "../common.sol";
19+
20+
interface IZetoKyc {
21+
event IdentityRegistered(uint256[2] publicKey, bytes data);
22+
23+
function register(
24+
uint256[2] memory publicKey,
25+
bytes calldata data
26+
) external;
27+
28+
function isRegistered(
29+
uint256[2] memory publicKey
30+
) external view returns (bool);
31+
32+
function getIdentitiesRoot() external view returns (uint256);
33+
}

solidity/contracts/lib/registry.sol

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Own
1919
import {SmtLib} from "@iden3/contracts/lib/SmtLib.sol";
2020
import {PoseidonUnit2L, PoseidonUnit3L} from "@iden3/contracts/lib/Poseidon.sol";
2121
import {Commonlib} from "./common.sol";
22+
import {IZeto} from "./interfaces/izeto.sol";
23+
import {IZetoKyc} from "./interfaces/izeto_kyc.sol";
2224

2325
uint256 constant MAX_SMT_DEPTH = 64;
2426

@@ -28,28 +30,21 @@ uint256 constant MAX_SMT_DEPTH = 64;
2830
/// submitters can generate proofs of membership for the
2931
/// accounts in a privacy-preserving manner.
3032
/// @author Kaleido, Inc.
31-
abstract contract Registry is OwnableUpgradeable {
33+
abstract contract Registry is OwnableUpgradeable, IZetoKyc {
3234
SmtLib.Data internal _publicKeysTree;
3335
using SmtLib for SmtLib.Data;
3436

35-
event IdentityRegistered(uint256[2] publicKey);
36-
3737
error AlreadyRegistered(uint256[2]);
3838

3939
function __Registry_init() internal onlyInitializing {
4040
_publicKeysTree.initialize(MAX_SMT_DEPTH);
4141
}
4242

43-
/// @dev Register a new Zeto account
44-
/// @param publicKey The public Babyjubjub key to register
45-
function _register(uint256[2] memory publicKey) internal {
46-
uint256 nodeHash = _getIdentitiesLeafNodeHash(publicKey);
47-
SmtLib.Node memory node = _publicKeysTree.getNode(nodeHash);
48-
if (node.nodeType != SmtLib.NodeType.EMPTY) {
49-
revert AlreadyRegistered(publicKey);
50-
}
51-
_publicKeysTree.addLeaf(nodeHash, nodeHash);
52-
emit IdentityRegistered(publicKey);
43+
function register(
44+
uint256[2] memory publicKey,
45+
bytes calldata data
46+
) public onlyOwner {
47+
_register(publicKey, data);
5348
}
5449

5550
/// @dev returns whether the given public key is registered
@@ -67,6 +62,21 @@ abstract contract Registry is OwnableUpgradeable {
6762
return _publicKeysTree.getRoot();
6863
}
6964

65+
/// @dev Register a new Zeto account
66+
/// @param publicKey The public Babyjubjub key to register
67+
function _register(
68+
uint256[2] memory publicKey,
69+
bytes calldata data
70+
) internal {
71+
uint256 nodeHash = _getIdentitiesLeafNodeHash(publicKey);
72+
SmtLib.Node memory node = _publicKeysTree.getNode(nodeHash);
73+
if (node.nodeType != SmtLib.NodeType.EMPTY) {
74+
revert AlreadyRegistered(publicKey);
75+
}
76+
_publicKeysTree.addLeaf(nodeHash, nodeHash);
77+
emit IdentityRegistered(publicKey, data);
78+
}
79+
7080
function _getIdentitiesLeafNodeHash(
7181
uint256[2] memory publicKey
7282
) internal pure returns (uint256) {

solidity/contracts/verifiers/verifier_anon_nullifier_kyc.sol renamed to solidity/contracts/verifiers/verifier_anon_nullifier_kyc_transfer.sol

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
pragma solidity >=0.7.0 <0.9.0;
2222

23-
contract Groth16Verifier_AnonNullifierKyc {
23+
contract Groth16Verifier_AnonNullifierKycTransfer {
2424
// Scalar field size
2525
uint256 constant r = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
2626
// Base field size
@@ -43,32 +43,32 @@ contract Groth16Verifier_AnonNullifierKyc {
4343
uint256 constant deltay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930;
4444

4545

46-
uint256 constant IC0x = 1368020126977316196213187057636983114330468061731699977744344817587788882990;
47-
uint256 constant IC0y = 7686063895143330261591855899880142399404728944441362517893141962995856727929;
46+
uint256 constant IC0x = 4549255854730728979068045147826494135688297252583383060843842296705895492978;
47+
uint256 constant IC0y = 5950970323653353113740267223097183547451063574376546024149863590759652058488;
4848

49-
uint256 constant IC1x = 14502254530076089964675033671517993862419783705089359180705605116873724842019;
50-
uint256 constant IC1y = 9049190990509151956509627927047158802465613185726643157556086701266946091568;
49+
uint256 constant IC1x = 1216073448663996885271432419027841106055434472971561665165335238062653822316;
50+
uint256 constant IC1y = 5097558434483111811746720335754493980758046673865340798005109731076493822092;
5151

52-
uint256 constant IC2x = 3455128039314231841012773119366413118715790719104028464745205146228319556246;
53-
uint256 constant IC2y = 13175890403996370630092498196483049850968580675778268285842736204668575597675;
52+
uint256 constant IC2x = 11161664165685458227890392607023596630662854996855616216929683515288525643261;
53+
uint256 constant IC2y = 12818956025711134634246546712440119681905145689756714720889316358763299716670;
5454

55-
uint256 constant IC3x = 13393887812211802083177209056510129401898394892926768888874562627657192399962;
56-
uint256 constant IC3y = 9042351346749284573092801161759462514076637268352518870596537996458419743091;
55+
uint256 constant IC3x = 9365147676333024284193510374200233681101801733129915318628858200430878767972;
56+
uint256 constant IC3y = 16602542985321581865161591791610629735092802111155748538031045719192964144533;
5757

58-
uint256 constant IC4x = 19203333608926332054415117565053561595496895142521866494460868409916811713957;
59-
uint256 constant IC4y = 4334310208006613584617716058867417381004655491738058483537403401767079516612;
58+
uint256 constant IC4x = 16628303690015057161260898115672715952728211813184122219719600578319362166707;
59+
uint256 constant IC4y = 15728053840296638802851558372415064634368090476197617381470156332889352222403;
6060

61-
uint256 constant IC5x = 8459703094760317168584339428426828704909860684147786556335328845261416934167;
62-
uint256 constant IC5y = 5466581123301380049065739652342512947564262375698860839217249516144678047196;
61+
uint256 constant IC5x = 5827873543537045343412383010600634430953834092125113195251309483077699447403;
62+
uint256 constant IC5y = 10857871525251638374522087235240657063634455578539572588195509683601405770706;
6363

64-
uint256 constant IC6x = 15924950080287000946685929883765297309673360990922044949928505866624182997859;
65-
uint256 constant IC6y = 5360581200037747345688259956951448973597185992056174685326726615654044407192;
64+
uint256 constant IC6x = 6904548272880268591909423473706195905482887793913653919663823478756560783089;
65+
uint256 constant IC6y = 13063380749905117216780308403936319461263137579341895411135333490405118421388;
6666

67-
uint256 constant IC7x = 9672280002529117458221100657711877410026000365131526255571070587277130104994;
68-
uint256 constant IC7y = 8600285172183660002776649258511861921290142756223662537727755349462907425056;
67+
uint256 constant IC7x = 14792454403924655648675695084766983654532792668337095643557509432994258770907;
68+
uint256 constant IC7y = 275832895488262903192405898395553290304405685441693387518881548143112407836;
6969

70-
uint256 constant IC8x = 21090833180119544777441412377177995972112553132880250907146360470568389276832;
71-
uint256 constant IC8y = 17643666097863395616263152084290402410806471541492999210218290396458240055652;
70+
uint256 constant IC8x = 9609823634861781908325095271708251605778434197921847173219811698057550155044;
71+
uint256 constant IC8y = 3132713041953533394988012935482842223032660540368789530274800749083525578584;
7272

7373

7474
// Memory data
Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
// SPDX-License-Identifier: GPL-3.0
2+
/*
3+
Copyright 2021 0KIMS association.
4+
5+
This file is generated with [snarkJS](https://github.com/iden3/snarkjs).
6+
7+
snarkJS is a free software: you can redistribute it and/or modify it
8+
under the terms of the GNU General Public License as published by
9+
the Free Software Foundation, either version 3 of the License, or
10+
(at your option) any later version.
11+
12+
snarkJS is distributed in the hope that it will be useful, but WITHOUT
13+
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14+
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15+
License for more details.
16+
17+
You should have received a copy of the GNU General Public License
18+
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
19+
*/
20+
21+
pragma solidity >=0.7.0 <0.9.0;
22+
23+
contract Groth16Verifier_AnonNullifierKycTransferLocked {
24+
// Scalar field size
25+
uint256 constant r = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
26+
// Base field size
27+
uint256 constant q = 21888242871839275222246405745257275088696311157297823662689037894645226208583;
28+
29+
// Verification Key data
30+
uint256 constant alphax = 20491192805390485299153009773594534940189261866228447918068658471970481763042;
31+
uint256 constant alphay = 9383485363053290200918347156157836566562967994039712273449902621266178545958;
32+
uint256 constant betax1 = 4252822878758300859123897981450591353533073413197771768651442665752259397132;
33+
uint256 constant betax2 = 6375614351688725206403948262868962793625744043794305715222011528459656738731;
34+
uint256 constant betay1 = 21847035105528745403288232691147584728191162732299865338377159692350059136679;
35+
uint256 constant betay2 = 10505242626370262277552901082094356697409835680220590971873171140371331206856;
36+
uint256 constant gammax1 = 11559732032986387107991004021392285783925812861821192530917403151452391805634;
37+
uint256 constant gammax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781;
38+
uint256 constant gammay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531;
39+
uint256 constant gammay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930;
40+
uint256 constant deltax1 = 11559732032986387107991004021392285783925812861821192530917403151452391805634;
41+
uint256 constant deltax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781;
42+
uint256 constant deltay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531;
43+
uint256 constant deltay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930;
44+
45+
46+
uint256 constant IC0x = 4549255854730728979068045147826494135688297252583383060843842296705895492978;
47+
uint256 constant IC0y = 5950970323653353113740267223097183547451063574376546024149863590759652058488;
48+
49+
uint256 constant IC1x = 1216073448663996885271432419027841106055434472971561665165335238062653822316;
50+
uint256 constant IC1y = 5097558434483111811746720335754493980758046673865340798005109731076493822092;
51+
52+
uint256 constant IC2x = 11161664165685458227890392607023596630662854996855616216929683515288525643261;
53+
uint256 constant IC2y = 12818956025711134634246546712440119681905145689756714720889316358763299716670;
54+
55+
uint256 constant IC3x = 18953400531314048493020249666915884736194198558848991201724079983703815588941;
56+
uint256 constant IC3y = 13699191758758035746733801303773823863589848011566156471658385360695236966394;
57+
58+
uint256 constant IC4x = 6418340491795971921392115660810008144220633855594784047024627824300258762503;
59+
uint256 constant IC4y = 331206681118086868666335692518221964875102632478886860969461713448972106730;
60+
61+
uint256 constant IC5x = 20672826781381085929236676912315916823659231399175782091852650610024412774769;
62+
uint256 constant IC5y = 11005715100892641133661679250179409252147733448250729630291805759444701807471;
63+
64+
uint256 constant IC6x = 12231940204046029565793569026881079629242556494447978554412435777385899724966;
65+
uint256 constant IC6y = 3022258914215080208953007370687180295593086983336375430220334804021677602519;
66+
67+
uint256 constant IC7x = 2730676615629181794195823324572752660852961858858579583326943949762787485542;
68+
uint256 constant IC7y = 19195486438582872786798796988852373517285255929228549822615489262799978113088;
69+
70+
uint256 constant IC8x = 20579458023158866087289023203244829165084026526103516895694907053440656858473;
71+
uint256 constant IC8y = 3021614608224014561606228442635508559916615305041679215398457772032721217921;
72+
73+
uint256 constant IC9x = 19700709081187424389075413367891493951275133113931731320975747028787203904612;
74+
uint256 constant IC9y = 14877838899466508832438353194361674038017333564191473092717528104566401199120;
75+
76+
77+
// Memory data
78+
uint16 constant pVk = 0;
79+
uint16 constant pPairing = 128;
80+
81+
uint16 constant pLastMem = 896;
82+
83+
function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[9] calldata _pubSignals) public view returns (bool) {
84+
assembly {
85+
function checkField(v) {
86+
if iszero(lt(v, r)) {
87+
mstore(0, 0)
88+
return(0, 0x20)
89+
}
90+
}
91+
92+
// G1 function to multiply a G1 value(x,y) to value in an address
93+
function g1_mulAccC(pR, x, y, s) {
94+
let success
95+
let mIn := mload(0x40)
96+
mstore(mIn, x)
97+
mstore(add(mIn, 32), y)
98+
mstore(add(mIn, 64), s)
99+
100+
success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64)
101+
102+
if iszero(success) {
103+
mstore(0, 0)
104+
return(0, 0x20)
105+
}
106+
107+
mstore(add(mIn, 64), mload(pR))
108+
mstore(add(mIn, 96), mload(add(pR, 32)))
109+
110+
success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64)
111+
112+
if iszero(success) {
113+
mstore(0, 0)
114+
return(0, 0x20)
115+
}
116+
}
117+
118+
function checkPairing(pA, pB, pC, pubSignals, pMem) -> isOk {
119+
let _pPairing := add(pMem, pPairing)
120+
let _pVk := add(pMem, pVk)
121+
122+
mstore(_pVk, IC0x)
123+
mstore(add(_pVk, 32), IC0y)
124+
125+
// Compute the linear combination vk_x
126+
127+
g1_mulAccC(_pVk, IC1x, IC1y, calldataload(add(pubSignals, 0)))
128+
129+
g1_mulAccC(_pVk, IC2x, IC2y, calldataload(add(pubSignals, 32)))
130+
131+
g1_mulAccC(_pVk, IC3x, IC3y, calldataload(add(pubSignals, 64)))
132+
133+
g1_mulAccC(_pVk, IC4x, IC4y, calldataload(add(pubSignals, 96)))
134+
135+
g1_mulAccC(_pVk, IC5x, IC5y, calldataload(add(pubSignals, 128)))
136+
137+
g1_mulAccC(_pVk, IC6x, IC6y, calldataload(add(pubSignals, 160)))
138+
139+
g1_mulAccC(_pVk, IC7x, IC7y, calldataload(add(pubSignals, 192)))
140+
141+
g1_mulAccC(_pVk, IC8x, IC8y, calldataload(add(pubSignals, 224)))
142+
143+
g1_mulAccC(_pVk, IC9x, IC9y, calldataload(add(pubSignals, 256)))
144+
145+
146+
// -A
147+
mstore(_pPairing, calldataload(pA))
148+
mstore(add(_pPairing, 32), mod(sub(q, calldataload(add(pA, 32))), q))
149+
150+
// B
151+
mstore(add(_pPairing, 64), calldataload(pB))
152+
mstore(add(_pPairing, 96), calldataload(add(pB, 32)))
153+
mstore(add(_pPairing, 128), calldataload(add(pB, 64)))
154+
mstore(add(_pPairing, 160), calldataload(add(pB, 96)))
155+
156+
// alpha1
157+
mstore(add(_pPairing, 192), alphax)
158+
mstore(add(_pPairing, 224), alphay)
159+
160+
// beta2
161+
mstore(add(_pPairing, 256), betax1)
162+
mstore(add(_pPairing, 288), betax2)
163+
mstore(add(_pPairing, 320), betay1)
164+
mstore(add(_pPairing, 352), betay2)
165+
166+
// vk_x
167+
mstore(add(_pPairing, 384), mload(add(pMem, pVk)))
168+
mstore(add(_pPairing, 416), mload(add(pMem, add(pVk, 32))))
169+
170+
171+
// gamma2
172+
mstore(add(_pPairing, 448), gammax1)
173+
mstore(add(_pPairing, 480), gammax2)
174+
mstore(add(_pPairing, 512), gammay1)
175+
mstore(add(_pPairing, 544), gammay2)
176+
177+
// C
178+
mstore(add(_pPairing, 576), calldataload(pC))
179+
mstore(add(_pPairing, 608), calldataload(add(pC, 32)))
180+
181+
// delta2
182+
mstore(add(_pPairing, 640), deltax1)
183+
mstore(add(_pPairing, 672), deltax2)
184+
mstore(add(_pPairing, 704), deltay1)
185+
mstore(add(_pPairing, 736), deltay2)
186+
187+
188+
let success := staticcall(sub(gas(), 2000), 8, _pPairing, 768, _pPairing, 0x20)
189+
190+
isOk := and(success, mload(_pPairing))
191+
}
192+
193+
let pMem := mload(0x40)
194+
mstore(0x40, add(pMem, pLastMem))
195+
196+
// Validate that all evaluations ∈ F
197+
198+
checkField(calldataload(add(_pubSignals, 0)))
199+
200+
checkField(calldataload(add(_pubSignals, 32)))
201+
202+
checkField(calldataload(add(_pubSignals, 64)))
203+
204+
checkField(calldataload(add(_pubSignals, 96)))
205+
206+
checkField(calldataload(add(_pubSignals, 128)))
207+
208+
checkField(calldataload(add(_pubSignals, 160)))
209+
210+
checkField(calldataload(add(_pubSignals, 192)))
211+
212+
checkField(calldataload(add(_pubSignals, 224)))
213+
214+
checkField(calldataload(add(_pubSignals, 256)))
215+
216+
217+
// Validate all evaluations
218+
let isValid := checkPairing(_pA, _pB, _pC, _pubSignals, pMem)
219+
220+
mstore(0, isValid)
221+
return(0, 0x20)
222+
}
223+
}
224+
}

0 commit comments

Comments
 (0)