@pvium/p2id-core 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/contracts/P2IDVault.sol +320 -214
- package/contracts/PviumIdentity.sol +29 -36
- package/contracts/PviumP2IDPolicy.sol +4 -7
- package/contracts/PviumP2IDVaultProxy.sol +199 -0
- package/contracts/PviumP2IdVaultFactory.sol +346 -34
- package/contracts/PviumVerifier.sol +15 -21
- package/contracts/PviumZKVerifier.sol +137 -111
- package/contracts/interfaces/IP2IDPolicy.sol +5 -21
- package/contracts/interfaces/IP2IDVault.sol +42 -17
- package/contracts/interfaces/IP2IDVaultProxy.sol +42 -0
- package/contracts/interfaces/IP2IDVerifier.sol +12 -13
- package/contracts/interfaces/IP2IdVaultFactory.sol +41 -7
- package/contracts/interfaces/IPviumIdentity.sol +6 -7
- package/contracts/lib/P2IDHash.sol +5 -5
- package/dist/cjs/p2idConstants.js +2 -2
- package/dist/esm/p2idConstants.d.ts +2 -2
- package/dist/esm/p2idConstants.js +2 -2
- package/package.json +1 -1
|
@@ -5,7 +5,7 @@ pragma solidity >=0.8.21;
|
|
|
5
5
|
uint256 constant N = 2097152;
|
|
6
6
|
uint256 constant LOG_N = 21;
|
|
7
7
|
uint256 constant NUMBER_OF_PUBLIC_INPUTS = 19;
|
|
8
|
-
uint256 constant VK_HASH =
|
|
8
|
+
uint256 constant VK_HASH = 0x0d98c94bcdac10f79e1dbc899f232b9f151eab31b116d644f732cf7693ccb2c7;
|
|
9
9
|
library HonkVerificationKey {
|
|
10
10
|
function loadVerificationKey() internal pure returns (Honk.VerificationKey memory) {
|
|
11
11
|
Honk.VerificationKey memory vk = Honk.VerificationKey({
|
|
@@ -13,52 +13,52 @@ library HonkVerificationKey {
|
|
|
13
13
|
logCircuitSize: uint256(21),
|
|
14
14
|
publicInputsSize: uint256(19),
|
|
15
15
|
ql: Honk.G1Point({
|
|
16
|
-
x: uint256(
|
|
17
|
-
y: uint256(
|
|
16
|
+
x: uint256(0x2c1b7ea2b43336dae4184a4801b8c79fffd33d5100ba495a65634baba55320b0),
|
|
17
|
+
y: uint256(0x0f723f6b2e6971c51541d84fb1eb2ee52bb2d43fb795cdbbee170c8bf60133ef)
|
|
18
18
|
}),
|
|
19
19
|
qr: Honk.G1Point({
|
|
20
|
-
x: uint256(
|
|
21
|
-
y: uint256(
|
|
20
|
+
x: uint256(0x2c4dfa9fca3821834c1dcd9c2e25d1174a9c3b6f0d6da8e0acb1119fa298ba15),
|
|
21
|
+
y: uint256(0x107a91f3db55144452b243b03094afde1c72dd616bf9197bc224f6fb3344ea8c)
|
|
22
22
|
}),
|
|
23
23
|
qo: Honk.G1Point({
|
|
24
|
-
x: uint256(
|
|
25
|
-
y: uint256(
|
|
24
|
+
x: uint256(0x1d8028efbf5771b66ad4087af7ea6c35f9acc6c921f8f5a9446111303720e435),
|
|
25
|
+
y: uint256(0x13182d6fdb9595517eeccb94fdc1de3f7135d1e558b18f6a876551743842fdc6)
|
|
26
26
|
}),
|
|
27
27
|
q4: Honk.G1Point({
|
|
28
|
-
x: uint256(
|
|
29
|
-
y: uint256(
|
|
28
|
+
x: uint256(0x1fb380e568a40d62e568da9695626cb48b9b8cda059868692a1f5e66f62f5a5c),
|
|
29
|
+
y: uint256(0x20a1e9ec32fee522f0affb8b36473d12cdb4094cf6ee8521b35ed31c5af6fd73)
|
|
30
30
|
}),
|
|
31
31
|
qm: Honk.G1Point({
|
|
32
|
-
x: uint256(
|
|
33
|
-
y: uint256(
|
|
32
|
+
x: uint256(0x173c3b41f6a2e66fb5859fe7d4b3fa6fc3c85496678fcb0da81435f3454cfab4),
|
|
33
|
+
y: uint256(0x2b26dea97c3a9127f3b5d941370746caa7ef18f660f78c69fe4e96f4805835d7)
|
|
34
34
|
}),
|
|
35
35
|
qc: Honk.G1Point({
|
|
36
|
-
x: uint256(
|
|
37
|
-
y: uint256(
|
|
36
|
+
x: uint256(0x089128522a7b4a89fe49976e0a150f93a96a2aebe7bb6b771fd43f5fc2a23f43),
|
|
37
|
+
y: uint256(0x1f520fbb2372257258df2ba7dfee35a119a20b27104e5690bc2536ead8b95f55)
|
|
38
38
|
}),
|
|
39
39
|
qLookup: Honk.G1Point({
|
|
40
|
-
x: uint256(
|
|
41
|
-
y: uint256(
|
|
40
|
+
x: uint256(0x1bf694c2ad84c2e633ad392257d63436e84b1073c582920f33f420b8badb3ab9),
|
|
41
|
+
y: uint256(0x01202c520ff5fde19c77f5a6001adb17063548a8259cf6757071aaf3db033318)
|
|
42
42
|
}),
|
|
43
43
|
qArith: Honk.G1Point({
|
|
44
|
-
x: uint256(
|
|
45
|
-
y: uint256(
|
|
44
|
+
x: uint256(0x2c560e8c3de53f23f0e0d8f607a67b8fb08d11ca7a86967157bb77d3539fd5b8),
|
|
45
|
+
y: uint256(0x2653c63366a9d5d42c8c91ac7c1247ee7fa6a3d5e2f05329cd2fc0358ce9933a)
|
|
46
46
|
}),
|
|
47
47
|
qDeltaRange: Honk.G1Point({
|
|
48
|
-
x: uint256(
|
|
49
|
-
y: uint256(
|
|
48
|
+
x: uint256(0x20557135427958307c97e6017f8e6f20a82d9028c26c77fb2b208d688dcafbd5),
|
|
49
|
+
y: uint256(0x12e20d83b19cc767fe8f26e1040d70457db9d9a9eb6b60838ea4b6891ddd0c36)
|
|
50
50
|
}),
|
|
51
51
|
qElliptic: Honk.G1Point({
|
|
52
52
|
x: uint256(0x0000000000000000000000000000000000000000000000000000000000000000),
|
|
53
53
|
y: uint256(0x0000000000000000000000000000000000000000000000000000000000000000)
|
|
54
54
|
}),
|
|
55
55
|
qMemory: Honk.G1Point({
|
|
56
|
-
x: uint256(
|
|
57
|
-
y: uint256(
|
|
56
|
+
x: uint256(0x21cdf6a43b0c43854cdd624ce2b81cf4278b7d846c55d7ec5e6d3dbaf9887fe0),
|
|
57
|
+
y: uint256(0x13ea21cb8cb4fe366919786206717c0f6f30120b11731e72a21549f6b8d79321)
|
|
58
58
|
}),
|
|
59
59
|
qNnf: Honk.G1Point({
|
|
60
|
-
x: uint256(
|
|
61
|
-
y: uint256(
|
|
60
|
+
x: uint256(0x2ef3c3abd690cab2fc188207a64429b35983f3c138b34cff5df89c838a921e25),
|
|
61
|
+
y: uint256(0x22e084b6a5c49a607eab5559d8a7b008387949cb1542a2b54bca353e1802700e)
|
|
62
62
|
}),
|
|
63
63
|
qPoseidon2External: Honk.G1Point({
|
|
64
64
|
x: uint256(0x0000000000000000000000000000000000000000000000000000000000000000),
|
|
@@ -69,60 +69,60 @@ library HonkVerificationKey {
|
|
|
69
69
|
y: uint256(0x0000000000000000000000000000000000000000000000000000000000000000)
|
|
70
70
|
}),
|
|
71
71
|
s1: Honk.G1Point({
|
|
72
|
-
x: uint256(
|
|
73
|
-
y: uint256(
|
|
72
|
+
x: uint256(0x1e17b6ccf8b8e53b7e608baa1ff7baaebb0d9618ee408ff5aa1066769b5ce099),
|
|
73
|
+
y: uint256(0x20ea265296e1787a7abf45d8679adbda4e0ed6f51d6008273462d8a1683b9c97)
|
|
74
74
|
}),
|
|
75
75
|
s2: Honk.G1Point({
|
|
76
|
-
x: uint256(
|
|
77
|
-
y: uint256(
|
|
76
|
+
x: uint256(0x25e022aaad31633e0ae1a860634e4cb30e670c11ea015d7bd18ac4f614cfcdc1),
|
|
77
|
+
y: uint256(0x18725c00f8a4e402cf61d161427cd9749eb89e9ba67f25ce0b4f079aa19c3383)
|
|
78
78
|
}),
|
|
79
79
|
s3: Honk.G1Point({
|
|
80
|
-
x: uint256(
|
|
81
|
-
y: uint256(
|
|
80
|
+
x: uint256(0x03e207722b9059d570b271412cbc4d39f01522acea22be09d6b4a55ff7007cc5),
|
|
81
|
+
y: uint256(0x1c708dcd032cac64aa3b175b52b1889a2624912f12f9ee1990a37eeabbe7544c)
|
|
82
82
|
}),
|
|
83
83
|
s4: Honk.G1Point({
|
|
84
|
-
x: uint256(
|
|
85
|
-
y: uint256(
|
|
84
|
+
x: uint256(0x1f5f1b4663c078c26c4fadd628674465605d5eaafe37c331333ea0507299601b),
|
|
85
|
+
y: uint256(0x073024ad75b3390f369912b19ffa894a3434cf00110c3db1391064cc60304f74)
|
|
86
86
|
}),
|
|
87
87
|
t1: Honk.G1Point({
|
|
88
|
-
x: uint256(
|
|
89
|
-
y: uint256(
|
|
88
|
+
x: uint256(0x00a4cfcadaf65bd7f05c8b4513b4b429cef6c157cc855c30f031130f4c7e9879),
|
|
89
|
+
y: uint256(0x12139f1ede1b1b8a2a7754e61743e962c66c66cb83c2951e9d947ee4b5886285)
|
|
90
90
|
}),
|
|
91
91
|
t2: Honk.G1Point({
|
|
92
|
-
x: uint256(
|
|
93
|
-
y: uint256(
|
|
92
|
+
x: uint256(0x179c3371ab328f00f06755a773ffdb63d9f3428b0eb49602aeb8f46b3a93846e),
|
|
93
|
+
y: uint256(0x1e548495de26512389f97243fa06be419425366e6fe3eda4db2243f3eb289343)
|
|
94
94
|
}),
|
|
95
95
|
t3: Honk.G1Point({
|
|
96
|
-
x: uint256(
|
|
97
|
-
y: uint256(
|
|
96
|
+
x: uint256(0x08403e53c817b332f25f0ef623566bf0c4a29c01702613bebc26b504887b0067),
|
|
97
|
+
y: uint256(0x0fd72a489dae56d109122252c1af93b807a8d6b1a7e58a2c1c68a88610361c9d)
|
|
98
98
|
}),
|
|
99
99
|
t4: Honk.G1Point({
|
|
100
|
-
x: uint256(
|
|
101
|
-
y: uint256(
|
|
100
|
+
x: uint256(0x1097841f06e277321386ae25322b03fb507f607640a7ffdf6b3361d9d5f61b67),
|
|
101
|
+
y: uint256(0x147da05a1760a1556233a63a2e49e8015aba77f810a260171b4f5995c894c26b)
|
|
102
102
|
}),
|
|
103
103
|
id1: Honk.G1Point({
|
|
104
|
-
x: uint256(
|
|
105
|
-
y: uint256(
|
|
104
|
+
x: uint256(0x2a1f137bb8c60c305275523f9968fff7e9eb285da590d13249655613babe3337),
|
|
105
|
+
y: uint256(0x1727a5cc5937328989b85d7a089fcd7f8b6acd9b5a236e8ecd4b8d5e9a66acf9)
|
|
106
106
|
}),
|
|
107
107
|
id2: Honk.G1Point({
|
|
108
|
-
x: uint256(
|
|
109
|
-
y: uint256(
|
|
108
|
+
x: uint256(0x06fdc373e611acbc236928ba93f9db893fbc4650e432c53471d604cb29c6996a),
|
|
109
|
+
y: uint256(0x0cb71589eb762de7ce73a8857f824dd73418e6afe241403bc75c89d79b513915)
|
|
110
110
|
}),
|
|
111
111
|
id3: Honk.G1Point({
|
|
112
|
-
x: uint256(
|
|
113
|
-
y: uint256(
|
|
112
|
+
x: uint256(0x2cddcc6b2824898e1df1136cddd9da391d8aa20b6bef4c3d0e99cd9510936e1b),
|
|
113
|
+
y: uint256(0x129cee475789db6bd598beb441f89215098db1eff7a30e0c3a35a5ba02079393)
|
|
114
114
|
}),
|
|
115
115
|
id4: Honk.G1Point({
|
|
116
|
-
x: uint256(
|
|
117
|
-
y: uint256(
|
|
116
|
+
x: uint256(0x2be0ca8701ccf30e669b2fe921b76c7190ae075df53396368862f695cfbea37a),
|
|
117
|
+
y: uint256(0x29df147c807c9dac924146e8cbac06b948cb568d1dd693324d2576bed1fae740)
|
|
118
118
|
}),
|
|
119
119
|
lagrangeFirst: Honk.G1Point({
|
|
120
120
|
x: uint256(0x2a56ce41f6b0be13b9c26747621b821eee81b23a887f299049b14c11e98460d6),
|
|
121
121
|
y: uint256(0x1aa98f2de3ddda547d8f6de4e725ded5827d6338c78656c0d12ca1aea6ef2c7c)
|
|
122
122
|
}),
|
|
123
123
|
lagrangeLast: Honk.G1Point({
|
|
124
|
-
x: uint256(
|
|
125
|
-
y: uint256(
|
|
124
|
+
x: uint256(0x25e42d0017747becf6182d6739ad9ea07f20a8d507337962155871d23d402611),
|
|
125
|
+
y: uint256(0x13b7c5a27924211c8b1f134228b07798bc35d589d07ceb8ccdcefc6139861095)
|
|
126
126
|
})
|
|
127
127
|
});
|
|
128
128
|
return vk;
|
|
@@ -177,6 +177,12 @@ Fr constant SUBGROUP_GENERATOR_INVERSE = Fr.wrap(0x204bd3277422fad364751ad938e2b
|
|
|
177
177
|
Fr constant MINUS_ONE = Fr.wrap(MODULUS - 1);
|
|
178
178
|
Fr constant ONE = Fr.wrap(1);
|
|
179
179
|
Fr constant ZERO = Fr.wrap(0);
|
|
180
|
+
|
|
181
|
+
// SmallSubgroupIPA opening-claim layout — mirrors SMALL_IPA_CLAIMS in
|
|
182
|
+
// barretenberg/cpp/src/barretenberg/commitment_schemes/small_subgroup_ipa/small_subgroup_ipa_utils.hpp.
|
|
183
|
+
uint256 constant NUM_SMALL_IPA_OPENING_CLAIMS = 5;
|
|
184
|
+
uint256 constant SMALL_IPA_BOUNDARY_OPENING_IDX = 3;
|
|
185
|
+
uint256 constant NUM_SMALL_IPA_TRANSCRIPT_EVALS = 4;
|
|
180
186
|
// Instantiation
|
|
181
187
|
|
|
182
188
|
library FrLib {
|
|
@@ -333,22 +339,8 @@ uint256 constant GROUP_ELEMENT_SIZE = 0x40;
|
|
|
333
339
|
// Powers of alpha used to batch subrelations (alpha, alpha^2, ..., alpha^(NUM_SUBRELATIONS-1))
|
|
334
340
|
uint256 constant NUMBER_OF_ALPHAS = NUMBER_OF_SUBRELATIONS - 1;
|
|
335
341
|
|
|
336
|
-
//
|
|
342
|
+
// Must match UltraFlavor_Generated::EntityId order.
|
|
337
343
|
enum WIRE {
|
|
338
|
-
Q_M,
|
|
339
|
-
Q_C,
|
|
340
|
-
Q_L,
|
|
341
|
-
Q_R,
|
|
342
|
-
Q_O,
|
|
343
|
-
Q_4,
|
|
344
|
-
Q_LOOKUP,
|
|
345
|
-
Q_ARITH,
|
|
346
|
-
Q_RANGE,
|
|
347
|
-
Q_ELLIPTIC,
|
|
348
|
-
Q_MEMORY,
|
|
349
|
-
Q_NNF,
|
|
350
|
-
Q_POSEIDON2_EXTERNAL,
|
|
351
|
-
Q_POSEIDON2_INTERNAL,
|
|
352
344
|
SIGMA_1,
|
|
353
345
|
SIGMA_2,
|
|
354
346
|
SIGMA_3,
|
|
@@ -357,12 +349,26 @@ enum WIRE {
|
|
|
357
349
|
ID_2,
|
|
358
350
|
ID_3,
|
|
359
351
|
ID_4,
|
|
352
|
+
LAGRANGE_FIRST,
|
|
353
|
+
LAGRANGE_LAST,
|
|
354
|
+
Q_LOOKUP,
|
|
360
355
|
TABLE_1,
|
|
361
356
|
TABLE_2,
|
|
362
357
|
TABLE_3,
|
|
363
358
|
TABLE_4,
|
|
364
|
-
|
|
365
|
-
|
|
359
|
+
Q_M,
|
|
360
|
+
Q_R,
|
|
361
|
+
Q_O,
|
|
362
|
+
Q_C,
|
|
363
|
+
Q_L,
|
|
364
|
+
Q_4,
|
|
365
|
+
Q_ARITH,
|
|
366
|
+
Q_RANGE,
|
|
367
|
+
Q_ELLIPTIC,
|
|
368
|
+
Q_MEMORY,
|
|
369
|
+
Q_NNF,
|
|
370
|
+
Q_POSEIDON2_EXTERNAL,
|
|
371
|
+
Q_POSEIDON2_INTERNAL,
|
|
366
372
|
W_L,
|
|
367
373
|
W_R,
|
|
368
374
|
W_O,
|
|
@@ -987,7 +993,7 @@ library RelationsLib {
|
|
|
987
993
|
accum = accum + (q_arith - ONE) * wire(p, WIRE.W_4_SHIFT);
|
|
988
994
|
accum = accum * q_arith;
|
|
989
995
|
accum = accum * domainSep;
|
|
990
|
-
evals[
|
|
996
|
+
evals[6] = accum;
|
|
991
997
|
}
|
|
992
998
|
|
|
993
999
|
// Relation 1
|
|
@@ -997,7 +1003,7 @@ library RelationsLib {
|
|
|
997
1003
|
accum = accum * (q_arith - ONE);
|
|
998
1004
|
accum = accum * q_arith;
|
|
999
1005
|
accum = accum * domainSep;
|
|
1000
|
-
evals[
|
|
1006
|
+
evals[7] = accum;
|
|
1001
1007
|
}
|
|
1002
1008
|
}
|
|
1003
1009
|
|
|
@@ -1035,19 +1041,19 @@ library RelationsLib {
|
|
|
1035
1041
|
- ((wire(p, WIRE.Z_PERM_SHIFT) + (wire(p, WIRE.LAGRANGE_LAST) * rp.publicInputsDelta))
|
|
1036
1042
|
* grand_product_denominator);
|
|
1037
1043
|
acc = acc * domainSep;
|
|
1038
|
-
evals[
|
|
1044
|
+
evals[0] = acc;
|
|
1039
1045
|
}
|
|
1040
1046
|
|
|
1041
1047
|
// Contribution 3
|
|
1042
1048
|
{
|
|
1043
1049
|
Fr acc = (wire(p, WIRE.LAGRANGE_LAST) * wire(p, WIRE.Z_PERM_SHIFT)) * domainSep;
|
|
1044
|
-
evals[
|
|
1050
|
+
evals[1] = acc;
|
|
1045
1051
|
}
|
|
1046
1052
|
|
|
1047
1053
|
// Contribution 4: z_perm initialization check (lagrange_first * z_perm = 0)
|
|
1048
1054
|
{
|
|
1049
1055
|
Fr acc = (wire(p, WIRE.LAGRANGE_FIRST) * wire(p, WIRE.Z_PERM)) * domainSep;
|
|
1050
|
-
evals[
|
|
1056
|
+
evals[2] = acc;
|
|
1051
1057
|
}
|
|
1052
1058
|
}
|
|
1053
1059
|
|
|
@@ -1098,9 +1104,9 @@ library RelationsLib {
|
|
|
1098
1104
|
|
|
1099
1105
|
Fr read_tag_boolean_relation = read_tag * read_tag - read_tag;
|
|
1100
1106
|
|
|
1101
|
-
evals[
|
|
1102
|
-
evals[
|
|
1103
|
-
evals[
|
|
1107
|
+
evals[3] = accumulatorNone;
|
|
1108
|
+
evals[4] = accumulatorOne;
|
|
1109
|
+
evals[5] = read_tag_boolean_relation * domainSep;
|
|
1104
1110
|
}
|
|
1105
1111
|
|
|
1106
1112
|
function accumulateDeltaRangeRelation(
|
|
@@ -1588,8 +1594,8 @@ library CommitmentSchemeLib {
|
|
|
1588
1594
|
Fr batchingChallenge;
|
|
1589
1595
|
// Linear combination of multilinear (sumcheck) evaluations and powers of rho
|
|
1590
1596
|
Fr batchedEvaluation;
|
|
1591
|
-
Fr[
|
|
1592
|
-
Fr[
|
|
1597
|
+
Fr[NUM_SMALL_IPA_OPENING_CLAIMS] denominators;
|
|
1598
|
+
Fr[NUM_SMALL_IPA_OPENING_CLAIMS] batchingScalars;
|
|
1593
1599
|
// 1/(z - r^{2^i}) for i = 0, ..., logSize, dynamically updated
|
|
1594
1600
|
Fr posInvertedDenominator;
|
|
1595
1601
|
// 1/(z + r^{2^i}) for i = 0, ..., logSize, dynamically updated
|
|
@@ -2183,34 +2189,34 @@ abstract contract BaseZKHonkVerifier is IVerifier {
|
|
|
2183
2189
|
|
|
2184
2190
|
commitments[1] = proof.geminiMaskingPoly;
|
|
2185
2191
|
|
|
2186
|
-
commitments[2] = vk.
|
|
2187
|
-
commitments[3] = vk.
|
|
2188
|
-
commitments[4] = vk.
|
|
2189
|
-
commitments[5] = vk.
|
|
2190
|
-
commitments[6] = vk.
|
|
2191
|
-
commitments[7] = vk.
|
|
2192
|
-
commitments[8] = vk.
|
|
2193
|
-
commitments[9] = vk.
|
|
2194
|
-
commitments[10] = vk.
|
|
2195
|
-
commitments[11] = vk.
|
|
2196
|
-
commitments[12] = vk.
|
|
2197
|
-
commitments[13] = vk.
|
|
2198
|
-
commitments[14] = vk.
|
|
2199
|
-
commitments[15] = vk.
|
|
2200
|
-
commitments[16] = vk.
|
|
2201
|
-
commitments[17] = vk.
|
|
2202
|
-
commitments[18] = vk.
|
|
2203
|
-
commitments[19] = vk.
|
|
2204
|
-
commitments[20] = vk.
|
|
2205
|
-
commitments[21] = vk.
|
|
2206
|
-
commitments[22] = vk.
|
|
2207
|
-
commitments[23] = vk.
|
|
2208
|
-
commitments[24] = vk.
|
|
2209
|
-
commitments[25] = vk.
|
|
2210
|
-
commitments[26] = vk.
|
|
2211
|
-
commitments[27] = vk.
|
|
2212
|
-
commitments[28] = vk.
|
|
2213
|
-
commitments[29] = vk.
|
|
2192
|
+
commitments[2] = vk.s1;
|
|
2193
|
+
commitments[3] = vk.s2;
|
|
2194
|
+
commitments[4] = vk.s3;
|
|
2195
|
+
commitments[5] = vk.s4;
|
|
2196
|
+
commitments[6] = vk.id1;
|
|
2197
|
+
commitments[7] = vk.id2;
|
|
2198
|
+
commitments[8] = vk.id3;
|
|
2199
|
+
commitments[9] = vk.id4;
|
|
2200
|
+
commitments[10] = vk.lagrangeFirst;
|
|
2201
|
+
commitments[11] = vk.lagrangeLast;
|
|
2202
|
+
commitments[12] = vk.qLookup;
|
|
2203
|
+
commitments[13] = vk.t1;
|
|
2204
|
+
commitments[14] = vk.t2;
|
|
2205
|
+
commitments[15] = vk.t3;
|
|
2206
|
+
commitments[16] = vk.t4;
|
|
2207
|
+
commitments[17] = vk.qm;
|
|
2208
|
+
commitments[18] = vk.qr;
|
|
2209
|
+
commitments[19] = vk.qo;
|
|
2210
|
+
commitments[20] = vk.qc;
|
|
2211
|
+
commitments[21] = vk.ql;
|
|
2212
|
+
commitments[22] = vk.q4;
|
|
2213
|
+
commitments[23] = vk.qArith;
|
|
2214
|
+
commitments[24] = vk.qDeltaRange;
|
|
2215
|
+
commitments[25] = vk.qElliptic;
|
|
2216
|
+
commitments[26] = vk.qMemory;
|
|
2217
|
+
commitments[27] = vk.qNnf;
|
|
2218
|
+
commitments[28] = vk.qPoseidon2External;
|
|
2219
|
+
commitments[29] = vk.qPoseidon2Internal;
|
|
2214
2220
|
|
|
2215
2221
|
// Accumulate proof points
|
|
2216
2222
|
commitments[30] = proof.w1;
|
|
@@ -2291,21 +2297,41 @@ abstract contract BaseZKHonkVerifier is IVerifier {
|
|
|
2291
2297
|
|
|
2292
2298
|
boundary += $LOG_N - 1;
|
|
2293
2299
|
|
|
2294
|
-
//
|
|
2295
|
-
mem.denominators[0] =
|
|
2296
|
-
mem.denominators[1] =
|
|
2300
|
+
// Denominators 1/(z - point_i) for the five opening points {r, g*r, r, 1, r}.
|
|
2301
|
+
mem.denominators[0] = ONE.div(tp.shplonkZ - tp.geminiR);
|
|
2302
|
+
mem.denominators[1] = ONE.div(tp.shplonkZ - SUBGROUP_GENERATOR * tp.geminiR);
|
|
2297
2303
|
mem.denominators[2] = mem.denominators[0];
|
|
2298
|
-
mem.denominators[
|
|
2304
|
+
mem.denominators[SMALL_IPA_BOUNDARY_OPENING_IDX] = ONE.div(tp.shplonkZ - ONE);
|
|
2305
|
+
mem.denominators[NUM_SMALL_IPA_OPENING_CLAIMS - 1] = mem.denominators[0];
|
|
2299
2306
|
|
|
2300
|
-
|
|
2307
|
+
// Iterate the opening claims in three segments — the inner loops can't be merged without an extra induction
|
|
2308
|
+
// variable, which pushes us into stack-too-deep.
|
|
2309
|
+
for (uint256 i = 0; i < SMALL_IPA_BOUNDARY_OPENING_IDX; i++) {
|
|
2301
2310
|
Fr scalingFactor = mem.denominators[i] * mem.batchingChallenge;
|
|
2302
2311
|
mem.batchingScalars[i] = scalingFactor.neg();
|
|
2303
2312
|
mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu;
|
|
2304
2313
|
mem.constantTermAccumulator = mem.constantTermAccumulator + scalingFactor * proof.libraPolyEvals[i];
|
|
2305
2314
|
}
|
|
2315
|
+
|
|
2316
|
+
// Boundary slot: claimed value is hardcoded 0, so no constantTermAccumulator contribution.
|
|
2317
|
+
{
|
|
2318
|
+
Fr scalingFactor = mem.denominators[SMALL_IPA_BOUNDARY_OPENING_IDX] * mem.batchingChallenge;
|
|
2319
|
+
mem.batchingScalars[SMALL_IPA_BOUNDARY_OPENING_IDX] = scalingFactor.neg();
|
|
2320
|
+
mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu;
|
|
2321
|
+
}
|
|
2322
|
+
|
|
2323
|
+
for (uint256 i = SMALL_IPA_BOUNDARY_OPENING_IDX + 1; i < NUM_SMALL_IPA_OPENING_CLAIMS; i++) {
|
|
2324
|
+
Fr scalingFactor = mem.denominators[i] * mem.batchingChallenge;
|
|
2325
|
+
mem.batchingScalars[i] = scalingFactor.neg();
|
|
2326
|
+
mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu;
|
|
2327
|
+
mem.constantTermAccumulator = mem.constantTermAccumulator + scalingFactor * proof.libraPolyEvals[i - 1];
|
|
2328
|
+
}
|
|
2329
|
+
|
|
2330
|
+
// Group per-claim batching scalars by commitment: [G], [A] (three openings), [Q].
|
|
2306
2331
|
scalars[boundary] = mem.batchingScalars[0];
|
|
2307
|
-
scalars[boundary + 1] =
|
|
2308
|
-
|
|
2332
|
+
scalars[boundary + 1] =
|
|
2333
|
+
mem.batchingScalars[1] + mem.batchingScalars[2] + mem.batchingScalars[SMALL_IPA_BOUNDARY_OPENING_IDX];
|
|
2334
|
+
scalars[boundary + 2] = mem.batchingScalars[NUM_SMALL_IPA_OPENING_CLAIMS - 1];
|
|
2309
2335
|
|
|
2310
2336
|
for (uint256 i = 0; i < LIBRA_COMMITMENTS; i++) {
|
|
2311
2337
|
commitments[boundary++] = proof.libraCommitments[i];
|
|
@@ -2,26 +2,11 @@
|
|
|
2
2
|
pragma solidity ^0.8.27;
|
|
3
3
|
|
|
4
4
|
/// @title IP2IDPolicy
|
|
5
|
-
/// @notice
|
|
6
|
-
///
|
|
7
|
-
///
|
|
8
|
-
/// a timelock; every vault consults the factory's current policy on each call.
|
|
9
|
-
///
|
|
10
|
-
/// What a policy decides, and the limits the vault enforces on it:
|
|
11
|
-
/// - which verifiers deposits may be funded under and claimed through. Gating is the one
|
|
12
|
-
/// thing a policy can use to stop claims (by disallowing a verifier), which freezes
|
|
13
|
-
/// claims under it but never moves funds; refunds never consult the policy.
|
|
14
|
-
/// - the protocol fee on payouts, in basis points. The vault caps it at its own
|
|
15
|
-
/// MAX_FEE_BPS, fixes a deposit's rate when the deposit is made, never charges it on
|
|
16
|
-
/// refunds, and treats a failing quote as no fee.
|
|
17
|
-
/// - how accrued fees are distributed. Fees accrue in each vault per (verifier, token);
|
|
18
|
-
/// anyone can have a vault hand them to the policy (withdrawFees), which pulls them and
|
|
19
|
-
/// splits them however it chooses, e.g. between a verifier's operator and the protocol.
|
|
20
|
-
///
|
|
21
|
-
/// Launch policy: an owner-managed verifier allowlist and no fee. Permissionless,
|
|
22
|
-
/// stake-based verifier registration and fees are later policies.
|
|
5
|
+
/// @notice Verifier approval, fee quotation and fee distribution callbacks used by P2IDVault.
|
|
6
|
+
/// @dev P2IDVault caps fee quotes, stores rates on funded deposits and quotes untracked funds at
|
|
7
|
+
/// sweep time. It skips policy approval for claims through the current default verifier.
|
|
23
8
|
interface IP2IDPolicy {
|
|
24
|
-
/// @notice
|
|
9
|
+
/// @notice Approval used for funding and for claims through a non-default verifier.
|
|
25
10
|
function isVerifierAllowed(address verifier) external view returns (bool);
|
|
26
11
|
|
|
27
12
|
/// @notice Fee on paying out `token` claimed through `verifier`, in basis points. Quoted when a
|
|
@@ -31,8 +16,7 @@ interface IP2IDPolicy {
|
|
|
31
16
|
/// @notice Called by a vault holding fees earned through `verifier`. For an ERC-20 the vault
|
|
32
17
|
/// first approves this policy for exactly `amount`: pull the tokens (transferFrom the
|
|
33
18
|
/// caller) and distribute them; whatever is not pulled stays accrued in the vault, and
|
|
34
|
-
/// the allowance is reset afterwards.
|
|
35
|
-
/// self-verifying: a caller that is not a vault can only give away its own tokens.
|
|
19
|
+
/// the allowance is reset afterwards.
|
|
36
20
|
/// For the native coin (token == address(0)) the vault sends `amount` as msg.value
|
|
37
21
|
/// instead, and all of it counts as distributed.
|
|
38
22
|
function distributeFee(address verifier, address token, uint256 amount) external payable;
|
|
@@ -4,10 +4,8 @@ pragma solidity ^0.8.27;
|
|
|
4
4
|
import {IP2IDVerifier} from "./IP2IDVerifier.sol";
|
|
5
5
|
|
|
6
6
|
/// @title IP2IDVault
|
|
7
|
-
/// @notice
|
|
8
|
-
///
|
|
9
|
-
/// Every deposit names the verifier whose proofs can release it; the factory's policy
|
|
10
|
-
/// decides which verifiers are allowed and what (capped) fee applies.
|
|
7
|
+
/// @notice Deposit funding, claims, refunds and accounting for one identity commitment.
|
|
8
|
+
/// Token address(0) denotes native coin. Each deposit records its verifier and fee rate.
|
|
11
9
|
interface IP2IDVault {
|
|
12
10
|
/// @dev Field order packs into 5 storage slots:
|
|
13
11
|
/// [funder, fundedAt, consumed] [token, refundWindow] [verifier, feeBps] [amount] [constraint].
|
|
@@ -25,8 +23,7 @@ interface IP2IDVault {
|
|
|
25
23
|
}
|
|
26
24
|
|
|
27
25
|
// ------------------------------------------------------------------ events
|
|
28
|
-
//
|
|
29
|
-
// Sweeps also emit one aggregate event with the net amount paid and the fee.
|
|
26
|
+
// Funding emits Funded; consumption emits Refunded or Claimed. Sweeps emit aggregate amounts.
|
|
30
27
|
|
|
31
28
|
/// @notice A deposit was recorded via fund()/fundWith()/fundFor().
|
|
32
29
|
/// @param ref Opaque application reference; zero means absent. Emitted only, not stored or enforced as unique.
|
|
@@ -35,15 +32,15 @@ interface IP2IDVault {
|
|
|
35
32
|
event Refunded(uint256 indexed depositId, address indexed funder, address indexed token, uint256 amount);
|
|
36
33
|
/// @notice A deposit was paid out by a sweep: `amount` gross, of which `fee` accrued as a fee.
|
|
37
34
|
event Claimed(uint256 indexed depositId, address indexed to, uint256 amount, uint256 fee);
|
|
38
|
-
/// @notice
|
|
35
|
+
/// @notice The owner cache was set or revalidated under the verifier's current revision.
|
|
39
36
|
event OwnerRefreshed(address indexed verifier, address indexed owner, uint64 iat);
|
|
40
|
-
/// @notice Default
|
|
37
|
+
/// @notice Default sweep result, including eligible untracked funds; amount is net of fee and may be zero.
|
|
41
38
|
event Swept(address indexed verifier, address indexed token, uint256 amount, uint256 fee, address indexed to, uint256 depositsConsumed);
|
|
42
39
|
/// @notice Funds from a constrained bucket were paid to the wallet the proof resolved to (`amount` net of `fee`).
|
|
43
40
|
event SweptBucket(address indexed verifier, bytes32 indexed constraint, address indexed token, uint256 amount, uint256 fee, address to, uint256 depositsConsumed);
|
|
44
41
|
/// @notice A fee accrued for `verifier`; it stays in the vault until withdrawFees() hands it to the policy.
|
|
45
42
|
event FeeAccrued(address indexed verifier, address indexed token, uint256 amount);
|
|
46
|
-
/// @notice
|
|
43
|
+
/// @notice Amount deducted from accrued fees after policy distribution, via token pull or native transfer.
|
|
47
44
|
event FeesDistributed(address indexed verifier, address indexed token, uint256 amount, address policy);
|
|
48
45
|
|
|
49
46
|
// setup (factory only, once)
|
|
@@ -56,7 +53,7 @@ interface IP2IDVault {
|
|
|
56
53
|
/// @notice Fund under any verifier the factory's policy allows.
|
|
57
54
|
/// @param ref Opaque application reference emitted in Funded; bytes32(0) for none.
|
|
58
55
|
function fundWith(address verifier, address token, uint256 amount, bytes32 constraint, uint64 refundWindow, bytes32 ref) external payable returns (uint256 depositId);
|
|
59
|
-
/// @notice Factory-only: record a deposit
|
|
56
|
+
/// @notice Factory-only: record a deposit for `funder`; pull ERC-20 from the factory or receive native msg.value.
|
|
60
57
|
/// @param ref Opaque application reference emitted in Funded; bytes32(0) for none.
|
|
61
58
|
function fundFor(address funder, address verifier, address token, uint256 amount, bytes32 constraint, uint64 refundWindow, bytes32 ref) external payable returns (uint256 depositId);
|
|
62
59
|
function refund(uint256 depositId) external;
|
|
@@ -66,9 +63,16 @@ interface IP2IDVault {
|
|
|
66
63
|
/// if the proof is newer than anything seen under it, and retires older proofs.
|
|
67
64
|
function refreshProof(address verifier, bytes calldata proof) external;
|
|
68
65
|
function refreshProofAndSweep(address verifier, bytes calldata proof, address token, uint256 depositCountLimit) external returns (uint256 amount, uint256 consumed);
|
|
66
|
+
/// @notice Apply a proof the vault's own proxy has already verified (msg.sender must be this
|
|
67
|
+
/// address): the freshness, revision and owner-cache rules of refreshProof without
|
|
68
|
+
/// re-verifying. Reverts unless `wallet` is the recorded owner under `verifier` afterwards.
|
|
69
|
+
/// Returns its own selector as acknowledgement so the proxy rejects empty fallbacks.
|
|
70
|
+
/// The acknowledgement checks compatibility; implementations remain trusted to apply the result.
|
|
71
|
+
function acceptOwnerProof(address verifier, address wallet, uint64 iat) external returns (bytes4);
|
|
69
72
|
|
|
70
73
|
// claiming (amounts returned are net of fees)
|
|
71
|
-
/// @notice Sweep
|
|
74
|
+
/// @notice Sweep a page of the verifier's default bucket to its cached owner. Eligible untracked
|
|
75
|
+
/// funds are included for the current default verifier when its cache meets the cross-default floor.
|
|
72
76
|
function sweep(address verifier, address token, uint256 depositCountLimit) external returns (uint256 amount, uint256 consumed);
|
|
73
77
|
function sweepUntracked(address token) external returns (uint256 amount);
|
|
74
78
|
function sweepDeposits(address verifier, address token, uint256[] calldata depositIds) external returns (uint256 amount);
|
|
@@ -83,9 +87,11 @@ interface IP2IDVault {
|
|
|
83
87
|
/// @notice P2ID vault interface version implemented by this contract.
|
|
84
88
|
function p2idVersion() external pure returns (string memory);
|
|
85
89
|
function MAX_FEE_BPS() external view returns (uint16);
|
|
90
|
+
/// @notice Record cap for cursor-based sweeps; a zero or above-cap depositCountLimit uses this value.
|
|
91
|
+
function MAX_SWEEP_PAGE() external view returns (uint256);
|
|
86
92
|
/// @notice address(0): the token address standing for the native coin.
|
|
87
93
|
function NATIVE() external view returns (address);
|
|
88
|
-
/// @notice
|
|
94
|
+
/// @notice Namespace value supplied at initialization; not used to recompute this vault's address.
|
|
89
95
|
function nsHash() external view returns (bytes32);
|
|
90
96
|
function factory() external view returns (address);
|
|
91
97
|
function policy() external view returns (address);
|
|
@@ -96,17 +102,36 @@ interface IP2IDVault {
|
|
|
96
102
|
function untrackedProofIat() external view returns (uint64);
|
|
97
103
|
function saltCommitment() external view returns (bytes32);
|
|
98
104
|
function depositCount() external view returns (uint256);
|
|
99
|
-
|
|
105
|
+
/// @notice A page of the bucket's deposit ids: up to `limit` from `offset` (limit 0 = all from `offset`).
|
|
106
|
+
function bucketDepositIds(address verifier, bytes32 constraint, address token, uint256 offset, uint256 limit) external view returns (uint256[] memory);
|
|
100
107
|
function bucketDepositCount(address verifier, bytes32 constraint, address token) external view returns (uint256);
|
|
101
|
-
/// @notice
|
|
102
|
-
///
|
|
103
|
-
/// at most one of their deposits. Funders must make constraints unique, e.g. by salting.
|
|
108
|
+
/// @notice Deposit recorded for a nonzero constraint and funder in this vault. The record persists
|
|
109
|
+
/// after a refund or claim and prevents the same funder from reusing that constraint here.
|
|
104
110
|
function constraintDeposit(bytes32 constraint, address funder) external view returns (bool used, uint256 depositId);
|
|
105
111
|
function bucketTotal(address verifier, bytes32 constraint, address token) external view returns (uint256);
|
|
106
112
|
function trackedTotal(address token) external view returns (uint256);
|
|
107
113
|
function feesOwed(address verifier, address token) external view returns (uint256);
|
|
108
114
|
function feesOwedTotal(address token) external view returns (uint256);
|
|
109
|
-
/// @notice
|
|
115
|
+
/// @notice Total default-bucket amount plus eligible untracked funds, before fees.
|
|
116
|
+
/// Does not apply the sweep page limit or validate default-bucket claimability.
|
|
110
117
|
function sweepable(address verifier, address token) external view returns (uint256);
|
|
111
118
|
function untrackedBalance(address token) external view returns (uint256);
|
|
119
|
+
|
|
120
|
+
struct AlphaAttestation {
|
|
121
|
+
uint256 nonce;
|
|
122
|
+
uint256 deadline;
|
|
123
|
+
bytes signature;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Alpha authorization: same vault API, additional signed entry points.
|
|
127
|
+
function supportsAlphaGuard() external pure returns (bool);
|
|
128
|
+
/// @notice Whether a caller-supplied random nonce has been consumed by an alpha business call.
|
|
129
|
+
function alphaNonceUsed(uint256 nonce) external view returns (bool);
|
|
130
|
+
function executeWithAttestation(bytes calldata action, AlphaAttestation calldata attestation) external returns (bytes memory);
|
|
131
|
+
/// @notice Alpha entry points: sign the ABI-encoded ordinary method with its original arguments.
|
|
132
|
+
/// Ordinary methods require no signature when factory.isAlpha(verifier.vkHash()) is false.
|
|
133
|
+
function refreshProofWithAttestation(address verifier, bytes calldata proof, AlphaAttestation calldata attestation) external;
|
|
134
|
+
function refreshProofAndSweepWithAttestation(address verifier, bytes calldata proof, address token, uint256 depositCountLimit, AlphaAttestation calldata attestation) external returns (uint256 amount, uint256 consumed);
|
|
135
|
+
function sweepBucketWithAttestation(address verifier, IP2IDVerifier.Constraint calldata constraint, address token, bytes calldata proof, uint256 depositCountLimit, AlphaAttestation calldata attestation) external returns (uint256 amount, uint256 consumed);
|
|
136
|
+
function sweepBucketDepositsWithAttestation(address verifier, IP2IDVerifier.Constraint calldata constraint, address token, uint256[] calldata depositIds, bytes calldata proof, AlphaAttestation calldata attestation) external returns (uint256 amount);
|
|
112
137
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.27;
|
|
3
|
+
|
|
4
|
+
import {IP2IDVault} from "./IP2IDVault.sol";
|
|
5
|
+
|
|
6
|
+
/// @title IP2IDVaultProxy
|
|
7
|
+
/// @notice A P2ID proxy with creation code fixed for its deployed factory. Its upgradeTo entry
|
|
8
|
+
/// point requires an identity proof and a registered target. Delegated implementations
|
|
9
|
+
/// are trusted with all proxy storage, including the implementation slot.
|
|
10
|
+
interface IP2IDVaultProxy {
|
|
11
|
+
function alphaUpgradeNonceUsed(uint256 nonce) external view returns (bool);
|
|
12
|
+
function upgradeToWithAttestation(bytes32 identityHash, address newImplementation, bytes calldata proof, IP2IDVault.AlphaAttestation calldata attestation) external;
|
|
13
|
+
/// @notice ERC-1967 upgrade event.
|
|
14
|
+
event Upgraded(address indexed implementation);
|
|
15
|
+
|
|
16
|
+
/// @notice The factory that deployed this proxy and whose registry bounds its implementations.
|
|
17
|
+
function factory() external view returns (address);
|
|
18
|
+
/// @notice The implementation used for delegated calls; proxy-defined selectors take precedence.
|
|
19
|
+
function implementation() external view returns (address);
|
|
20
|
+
/// @notice The wallet and issue time of the proof behind the last upgrade (zero before the first).
|
|
21
|
+
/// Later upgrades need a proof at least this recent; an equal time only for the same wallet.
|
|
22
|
+
/// Delegated code can overwrite this record; upgradeTo ignores a record beyond its future-time bound.
|
|
23
|
+
function lastUpgrade() external view returns (address wallet, uint64 iat);
|
|
24
|
+
/// @notice Move this vault to `newImplementation`, which the factory must have registered.
|
|
25
|
+
/// `proof` is verified through the factory's default verifier for `identityHash` (the
|
|
26
|
+
/// identity this address was derived from); the wallet it resolves to must be the caller,
|
|
27
|
+
/// and its issue time must not exceed block.timestamp + 15 minutes or fall below lastUpgrade.
|
|
28
|
+
/// It must also meet the current implementation's latestProofIat for that verifier and
|
|
29
|
+
/// untrackedProofIat; failed, malformed or excessively future-dated floor reads count as zero.
|
|
30
|
+
/// This call writes the implementation slot and lastUpgrade record, then calls
|
|
31
|
+
/// acceptOwnerProof through the new implementation without verifying the proof again.
|
|
32
|
+
/// Hook failure reverts the entire upgrade. P2IDVault's hook requires the proven wallet
|
|
33
|
+
/// to be the resulting cached owner, rejecting conflicting equal-time wallet proofs.
|
|
34
|
+
/// The proxy requires the hook selector as a canonical 32-byte ABI acknowledgement;
|
|
35
|
+
/// absent, malformed or incorrect acknowledgements revert the entire upgrade.
|
|
36
|
+
/// After the hook, the implementation must still match the target, owner(verifier)
|
|
37
|
+
/// must report the proven wallet, and latestProofIat(verifier) must be at least iat.
|
|
38
|
+
/// Nested upgradeTo calls revert while an upgrade is running.
|
|
39
|
+
/// @dev Getters run through delegated code and cannot establish that an implementation is safe.
|
|
40
|
+
/// This entry point performs no separate initialization or storage-migration call.
|
|
41
|
+
function upgradeTo(bytes32 identityHash, address newImplementation, bytes calldata proof) external;
|
|
42
|
+
}
|