zkjson 0.7.0 → 0.7.2
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/cjs/circomlibjs/SMT.js +481 -0
- package/cjs/circomlibjs/SMTMemDb.js +173 -0
- package/cjs/circomlibjs/buildPoseidon.js +162 -0
- package/cjs/circomlibjs/buildPoseidonWasm.js +124 -0
- package/cjs/circomlibjs/getHashes.js +220 -0
- package/cjs/circomlibjs/poseidonConstants$1.js +1 -0
- package/cjs/circomlibjs.js +6 -6
- package/cjs/collection.js +2 -2
- package/cjs/collection_tree.js +148 -0
- package/cjs/db.js +2 -2
- package/cjs/db_tree.js +398 -0
- package/cjs/index.js +16 -0
- package/cjs/newMemEmptyTrie.js +42 -0
- package/cjs/nft.js +3 -4
- package/esm/circomlibjs/SMT.js +349 -0
- package/esm/circomlibjs/SMTMemDb.js +69 -0
- package/esm/circomlibjs/buildPoseidon.js +113 -0
- package/esm/circomlibjs/buildPoseidonWasm.js +445 -0
- package/esm/circomlibjs/getHashes.js +515 -0
- package/esm/circomlibjs/poseidonConstants$1.js +24806 -0
- package/esm/circomlibjs.js +70 -25385
- package/esm/collection.js +1 -1
- package/esm/collection_tree.js +43 -0
- package/esm/db.js +1 -1
- package/esm/db_tree.js +122 -0
- package/esm/index.js +3 -1
- package/esm/newMemEmptyTrie.js +11 -0
- package/esm/nft.js +5 -3
- package/package.json +1 -1
package/cjs/nft.js
CHANGED
@@ -4,12 +4,11 @@ Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
5
5
|
});
|
6
6
|
exports["default"] = void 0;
|
7
|
-
var
|
7
|
+
var _fastSha = require("fast-sha256");
|
8
8
|
var _snarkjs = require("snarkjs");
|
9
9
|
var _encoder = require("./encoder.js");
|
10
10
|
var _uint = require("./uint.js");
|
11
11
|
var _parse = require("./parse.js");
|
12
|
-
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
|
13
12
|
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
14
13
|
function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i["return"]) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
|
15
14
|
function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { if (r) i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n;else { var o = function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); }; o("next", 0), o("throw", 1), o("return", 2); } }, _regeneratorDefine2(e, r, n, t); }
|
@@ -158,8 +157,8 @@ var NFT = exports["default"] = /*#__PURE__*/function () {
|
|
158
157
|
key: "cid",
|
159
158
|
value: function cid() {
|
160
159
|
var str = new TextEncoder().encode(JSON.stringify(this.json));
|
161
|
-
var
|
162
|
-
return toCID(new Uint8Array([18,
|
160
|
+
var hashBytes = (0, _fastSha.hash)(str);
|
161
|
+
return toCID(new Uint8Array([18, hashBytes.length].concat(_toConsumableArray(Array.from(hashBytes)))));
|
163
162
|
}
|
164
163
|
}]);
|
165
164
|
}();
|
@@ -0,0 +1,349 @@
|
|
1
|
+
import * as ffjavascript from "ffjavascript"
|
2
|
+
import buildPoseidon from "./buildPoseidon.js"
|
3
|
+
import { splitEvery } from "ramda"
|
4
|
+
export default class SMT {
|
5
|
+
constructor(db, root, hash0, hash1, F) {
|
6
|
+
this.db = db
|
7
|
+
this.root = root
|
8
|
+
this.hash0 = hash0
|
9
|
+
this.hash1 = hash1
|
10
|
+
this.F = F
|
11
|
+
}
|
12
|
+
|
13
|
+
_splitBits(_key) {
|
14
|
+
const F = this.F
|
15
|
+
const res = ffjavascript.Scalar.bits(F.toObject(_key))
|
16
|
+
|
17
|
+
while (res.length < 256) res.push(false)
|
18
|
+
|
19
|
+
return res
|
20
|
+
}
|
21
|
+
|
22
|
+
async update(_key, _newValue) {
|
23
|
+
this.poseidon ??= await buildPoseidon()
|
24
|
+
this.zero ??= this.poseidon([
|
25
|
+
"0",
|
26
|
+
"0",
|
27
|
+
"0",
|
28
|
+
"0",
|
29
|
+
"0",
|
30
|
+
"0",
|
31
|
+
"0",
|
32
|
+
"0",
|
33
|
+
"0",
|
34
|
+
"0",
|
35
|
+
"0",
|
36
|
+
"0",
|
37
|
+
"0",
|
38
|
+
"0",
|
39
|
+
"0",
|
40
|
+
"0",
|
41
|
+
])
|
42
|
+
let _hash_value = _newValue
|
43
|
+
if (_newValue.length === 256) {
|
44
|
+
_hash_value = []
|
45
|
+
for (let v of splitEvery(16, _newValue)) {
|
46
|
+
const value =
|
47
|
+
v.join("") === "0000000000000000" ? this.zero : this.poseidon(v)
|
48
|
+
_hash_value.push(value)
|
49
|
+
}
|
50
|
+
}
|
51
|
+
const newValue = this.poseidon(_hash_value)
|
52
|
+
const F = this.F
|
53
|
+
const key = F.e(_key)
|
54
|
+
const resFind = await this.find(key)
|
55
|
+
const res = {}
|
56
|
+
res.oldRoot = this.root
|
57
|
+
res.oldKey = key
|
58
|
+
res.oldValue = resFind.foundValue
|
59
|
+
res.newKey = key
|
60
|
+
res.newValue = newValue
|
61
|
+
res.siblings = resFind.siblings
|
62
|
+
|
63
|
+
const ins = []
|
64
|
+
const dels = []
|
65
|
+
|
66
|
+
let rtOld = this.hash1(key, resFind.foundValue)
|
67
|
+
let rtNew = this.hash1(key, newValue)
|
68
|
+
ins.push([rtNew, [1, key, newValue]])
|
69
|
+
dels.push(rtOld)
|
70
|
+
|
71
|
+
const keyBits = this._splitBits(key)
|
72
|
+
for (let level = resFind.siblings.length - 1; level >= 0; level--) {
|
73
|
+
let oldNode, newNode
|
74
|
+
const sibling = resFind.siblings[level]
|
75
|
+
if (keyBits[level]) {
|
76
|
+
oldNode = [sibling, rtOld]
|
77
|
+
newNode = [sibling, rtNew]
|
78
|
+
} else {
|
79
|
+
oldNode = [rtOld, sibling]
|
80
|
+
newNode = [rtNew, sibling]
|
81
|
+
}
|
82
|
+
rtOld = this.hash0(oldNode[0], oldNode[1])
|
83
|
+
rtNew = this.hash0(newNode[0], newNode[1])
|
84
|
+
dels.push(rtOld)
|
85
|
+
ins.push([rtNew, newNode])
|
86
|
+
}
|
87
|
+
|
88
|
+
res.newRoot = rtNew
|
89
|
+
|
90
|
+
await this.db.multiDel(dels)
|
91
|
+
await this.db.multiIns(ins)
|
92
|
+
await this.db.setRoot(rtNew)
|
93
|
+
this.root = rtNew
|
94
|
+
|
95
|
+
return res
|
96
|
+
}
|
97
|
+
|
98
|
+
async delete(_key) {
|
99
|
+
const F = this.F
|
100
|
+
const key = F.e(_key)
|
101
|
+
|
102
|
+
const resFind = await this.find(key)
|
103
|
+
if (!resFind.found) throw new Error("Key does not exists")
|
104
|
+
|
105
|
+
const res = {
|
106
|
+
siblings: [],
|
107
|
+
delKey: key,
|
108
|
+
delValue: resFind.foundValue,
|
109
|
+
}
|
110
|
+
|
111
|
+
const dels = []
|
112
|
+
const ins = []
|
113
|
+
let rtOld = this.hash1(key, resFind.foundValue)
|
114
|
+
let rtNew
|
115
|
+
dels.push(rtOld)
|
116
|
+
|
117
|
+
let mixed
|
118
|
+
if (resFind.siblings.length > 0) {
|
119
|
+
const record = await this.db.get(
|
120
|
+
resFind.siblings[resFind.siblings.length - 1],
|
121
|
+
)
|
122
|
+
if (record.length == 3 && F.eq(record[0], F.one)) {
|
123
|
+
mixed = false
|
124
|
+
res.oldKey = record[1]
|
125
|
+
res.oldValue = record[2]
|
126
|
+
res.isOld0 = false
|
127
|
+
rtNew = resFind.siblings[resFind.siblings.length - 1]
|
128
|
+
} else if (record.length == 2) {
|
129
|
+
mixed = true
|
130
|
+
res.oldKey = key
|
131
|
+
res.oldValue = F.zero
|
132
|
+
res.isOld0 = true
|
133
|
+
rtNew = F.zero
|
134
|
+
} else {
|
135
|
+
throw new Error("Invalid node. Database corrupted")
|
136
|
+
}
|
137
|
+
} else {
|
138
|
+
rtNew = F.zero
|
139
|
+
res.oldKey = key
|
140
|
+
res.oldValue = F.zero
|
141
|
+
res.isOld0 = true
|
142
|
+
}
|
143
|
+
|
144
|
+
const keyBits = this._splitBits(key)
|
145
|
+
|
146
|
+
for (let level = resFind.siblings.length - 1; level >= 0; level--) {
|
147
|
+
let newSibling = resFind.siblings[level]
|
148
|
+
if (level == resFind.siblings.length - 1 && !res.isOld0) {
|
149
|
+
newSibling = F.zero
|
150
|
+
}
|
151
|
+
const oldSibling = resFind.siblings[level]
|
152
|
+
if (keyBits[level]) {
|
153
|
+
rtOld = this.hash0(oldSibling, rtOld)
|
154
|
+
} else {
|
155
|
+
rtOld = this.hash0(rtOld, oldSibling)
|
156
|
+
}
|
157
|
+
dels.push(rtOld)
|
158
|
+
if (!F.isZero(newSibling)) {
|
159
|
+
mixed = true
|
160
|
+
}
|
161
|
+
|
162
|
+
if (mixed) {
|
163
|
+
res.siblings.unshift(resFind.siblings[level])
|
164
|
+
let newNode
|
165
|
+
if (keyBits[level]) {
|
166
|
+
newNode = [newSibling, rtNew]
|
167
|
+
} else {
|
168
|
+
newNode = [rtNew, newSibling]
|
169
|
+
}
|
170
|
+
rtNew = this.hash0(newNode[0], newNode[1])
|
171
|
+
ins.push([rtNew, newNode])
|
172
|
+
}
|
173
|
+
}
|
174
|
+
|
175
|
+
await this.db.multiIns(ins)
|
176
|
+
await this.db.setRoot(rtNew)
|
177
|
+
this.root = rtNew
|
178
|
+
await this.db.multiDel(dels)
|
179
|
+
|
180
|
+
res.newRoot = rtNew
|
181
|
+
res.oldRoot = rtOld
|
182
|
+
|
183
|
+
return res
|
184
|
+
}
|
185
|
+
|
186
|
+
async insert(_key, _value) {
|
187
|
+
this.poseidon ??= await buildPoseidon()
|
188
|
+
this.zero ??= this.poseidon([
|
189
|
+
"0",
|
190
|
+
"0",
|
191
|
+
"0",
|
192
|
+
"0",
|
193
|
+
"0",
|
194
|
+
"0",
|
195
|
+
"0",
|
196
|
+
"0",
|
197
|
+
"0",
|
198
|
+
"0",
|
199
|
+
"0",
|
200
|
+
"0",
|
201
|
+
"0",
|
202
|
+
"0",
|
203
|
+
"0",
|
204
|
+
"0",
|
205
|
+
])
|
206
|
+
let _hash_value = _value
|
207
|
+
if (_value.length === 256) {
|
208
|
+
_hash_value = []
|
209
|
+
for (let v of splitEvery(16, _value)) {
|
210
|
+
const value =
|
211
|
+
v.join("") === "0000000000000000" ? this.zero : this.poseidon(v)
|
212
|
+
_hash_value.push(value)
|
213
|
+
}
|
214
|
+
}
|
215
|
+
|
216
|
+
const value = this.poseidon(_hash_value)
|
217
|
+
const F = this.F
|
218
|
+
const key = F.e(_key)
|
219
|
+
let addedOne = false
|
220
|
+
const res = {}
|
221
|
+
res.oldRoot = this.root
|
222
|
+
const newKeyBits = this._splitBits(key)
|
223
|
+
|
224
|
+
let rtOld
|
225
|
+
|
226
|
+
const resFind = await this.find(key)
|
227
|
+
if (resFind.found) throw new Error("Key already exists")
|
228
|
+
|
229
|
+
res.siblings = resFind.siblings
|
230
|
+
let mixed
|
231
|
+
|
232
|
+
if (!resFind.isOld0) {
|
233
|
+
const oldKeyits = this._splitBits(resFind.notFoundKey)
|
234
|
+
for (let i = res.siblings.length; oldKeyits[i] == newKeyBits[i]; i++) {
|
235
|
+
res.siblings.push(F.zero)
|
236
|
+
}
|
237
|
+
rtOld = this.hash1(resFind.notFoundKey, resFind.notFoundValue)
|
238
|
+
res.siblings.push(rtOld)
|
239
|
+
addedOne = true
|
240
|
+
mixed = false
|
241
|
+
} else if (res.siblings.length > 0) {
|
242
|
+
mixed = true
|
243
|
+
rtOld = F.zero
|
244
|
+
}
|
245
|
+
|
246
|
+
const inserts = []
|
247
|
+
const dels = []
|
248
|
+
|
249
|
+
let rt = this.hash1(key, value)
|
250
|
+
inserts.push([rt, [1, key, value]])
|
251
|
+
|
252
|
+
for (let i = res.siblings.length - 1; i >= 0; i--) {
|
253
|
+
if (i < res.siblings.length - 1 && !F.isZero(res.siblings[i])) {
|
254
|
+
mixed = true
|
255
|
+
}
|
256
|
+
if (mixed) {
|
257
|
+
const oldSibling = resFind.siblings[i]
|
258
|
+
if (newKeyBits[i]) {
|
259
|
+
rtOld = this.hash0(oldSibling, rtOld)
|
260
|
+
} else {
|
261
|
+
rtOld = this.hash0(rtOld, oldSibling)
|
262
|
+
}
|
263
|
+
dels.push(rtOld)
|
264
|
+
}
|
265
|
+
|
266
|
+
let newRt
|
267
|
+
if (newKeyBits[i]) {
|
268
|
+
newRt = this.hash0(res.siblings[i], rt)
|
269
|
+
inserts.push([newRt, [res.siblings[i], rt]])
|
270
|
+
} else {
|
271
|
+
newRt = this.hash0(rt, res.siblings[i])
|
272
|
+
inserts.push([newRt, [rt, res.siblings[i]]])
|
273
|
+
}
|
274
|
+
rt = newRt
|
275
|
+
}
|
276
|
+
|
277
|
+
if (addedOne) res.siblings.pop()
|
278
|
+
while (
|
279
|
+
res.siblings.length > 0 &&
|
280
|
+
F.isZero(res.siblings[res.siblings.length - 1])
|
281
|
+
) {
|
282
|
+
res.siblings.pop()
|
283
|
+
}
|
284
|
+
res.oldKey = resFind.notFoundKey
|
285
|
+
res.oldValue = resFind.notFoundValue
|
286
|
+
res.newRoot = rt
|
287
|
+
res.isOld0 = resFind.isOld0
|
288
|
+
|
289
|
+
await this.db.multiIns(inserts)
|
290
|
+
await this.db.setRoot(rt)
|
291
|
+
this.root = rt
|
292
|
+
await this.db.multiDel(dels)
|
293
|
+
|
294
|
+
return res
|
295
|
+
}
|
296
|
+
|
297
|
+
async find(_key) {
|
298
|
+
const key = this.F.e(_key)
|
299
|
+
const keyBits = this._splitBits(key)
|
300
|
+
return await this._find(key, keyBits, this.root, 0)
|
301
|
+
}
|
302
|
+
|
303
|
+
async _find(key, keyBits, root, level) {
|
304
|
+
const F = this.F
|
305
|
+
if (typeof root === "undefined") root = this.root
|
306
|
+
|
307
|
+
let res
|
308
|
+
if (F.isZero(root)) {
|
309
|
+
res = {
|
310
|
+
found: false,
|
311
|
+
siblings: [],
|
312
|
+
notFoundKey: key,
|
313
|
+
notFoundValue: F.zero,
|
314
|
+
isOld0: true,
|
315
|
+
}
|
316
|
+
return res
|
317
|
+
}
|
318
|
+
|
319
|
+
const record = await this.db.get(root)
|
320
|
+
|
321
|
+
if (record.length == 3 && F.eq(record[0], F.one)) {
|
322
|
+
if (F.eq(record[1], key)) {
|
323
|
+
res = {
|
324
|
+
found: true,
|
325
|
+
siblings: [],
|
326
|
+
foundValue: record[2],
|
327
|
+
isOld0: false,
|
328
|
+
}
|
329
|
+
} else {
|
330
|
+
res = {
|
331
|
+
found: false,
|
332
|
+
siblings: [],
|
333
|
+
notFoundKey: record[1],
|
334
|
+
notFoundValue: record[2],
|
335
|
+
isOld0: false,
|
336
|
+
}
|
337
|
+
}
|
338
|
+
} else {
|
339
|
+
if (keyBits[level] == 0) {
|
340
|
+
res = await this._find(key, keyBits, record[0], level + 1)
|
341
|
+
res.siblings.unshift(record[1])
|
342
|
+
} else {
|
343
|
+
res = await this._find(key, keyBits, record[1], level + 1)
|
344
|
+
res.siblings.unshift(record[0])
|
345
|
+
}
|
346
|
+
}
|
347
|
+
return res
|
348
|
+
}
|
349
|
+
}
|
@@ -0,0 +1,69 @@
|
|
1
|
+
export default class SMTMemDb {
|
2
|
+
constructor(F, kv) {
|
3
|
+
this.kv = kv
|
4
|
+
this.nodes = {}
|
5
|
+
this.root = F.zero
|
6
|
+
if (this.kv) {
|
7
|
+
const root = this.kv.get("__root__")
|
8
|
+
if (root) this.root = root
|
9
|
+
else this.kv.put("__root__", this.root)
|
10
|
+
}
|
11
|
+
this.F = F
|
12
|
+
}
|
13
|
+
|
14
|
+
async getRoot() {
|
15
|
+
return this.root
|
16
|
+
}
|
17
|
+
|
18
|
+
_key2str(k) {
|
19
|
+
this.F
|
20
|
+
const keyS = this.F.toString(k)
|
21
|
+
return keyS
|
22
|
+
}
|
23
|
+
|
24
|
+
_normalize(n) {
|
25
|
+
this.F
|
26
|
+
for (let i = 0; i < n.length; i++) {
|
27
|
+
n[i] = this.F.e(n[i])
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
async get(key) {
|
32
|
+
const keyS = this._key2str(key)
|
33
|
+
if (!this.nodes[keyS]) {
|
34
|
+
let node = this.kv.get(`__nodes__/${keyS}`)
|
35
|
+
if (node) this.nodes[keyS] = node
|
36
|
+
}
|
37
|
+
return this.nodes[keyS]
|
38
|
+
}
|
39
|
+
|
40
|
+
async multiGet(keys) {
|
41
|
+
const promises = []
|
42
|
+
for (let i = 0; i < keys.length; i++) {
|
43
|
+
promises.push(this.get(keys[i]))
|
44
|
+
}
|
45
|
+
return await Promise.all(promises)
|
46
|
+
}
|
47
|
+
|
48
|
+
async setRoot(rt) {
|
49
|
+
this.root = rt
|
50
|
+
if (this.kv) this.kv.put("__root__", this.root)
|
51
|
+
}
|
52
|
+
|
53
|
+
async multiIns(inserts) {
|
54
|
+
for (let i = 0; i < inserts.length; i++) {
|
55
|
+
const keyS = this._key2str(inserts[i][0])
|
56
|
+
this._normalize(inserts[i][1])
|
57
|
+
this.nodes[keyS] = inserts[i][1]
|
58
|
+
if (this.kv) this.kv.put(`__nodes__/${keyS}`, this.nodes[keyS])
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
async multiDel(dels) {
|
63
|
+
for (let i = 0; i < dels.length; i++) {
|
64
|
+
const keyS = this._key2str(dels[i])
|
65
|
+
delete this.nodes[keyS]
|
66
|
+
if (this.kv) this.kv.del(`__nodes__/${keyS}`)
|
67
|
+
}
|
68
|
+
}
|
69
|
+
}
|
@@ -0,0 +1,113 @@
|
|
1
|
+
import * as ffjavascript from "ffjavascript"
|
2
|
+
import poseidonConstants$1 from "./poseidonConstants$1.js"
|
3
|
+
import * as assert from "assert"
|
4
|
+
const assert__default = assert
|
5
|
+
|
6
|
+
function unsringifyConstants(Fr, o) {
|
7
|
+
if (typeof o == "string" && /^[0-9]+$/.test(o)) {
|
8
|
+
return Fr.e(o)
|
9
|
+
} else if (typeof o == "string" && /^0x[0-9a-fA-F]+$/.test(o)) {
|
10
|
+
return Fr.e(o)
|
11
|
+
} else if (Array.isArray(o)) {
|
12
|
+
return o.map(unsringifyConstants.bind(null, Fr))
|
13
|
+
} else if (typeof o == "object") {
|
14
|
+
if (o === null) return null
|
15
|
+
const res = {}
|
16
|
+
const keys = Object.keys(o)
|
17
|
+
keys.forEach(k => {
|
18
|
+
res[k] = unsringifyConstants(Fr, o[k])
|
19
|
+
})
|
20
|
+
return res
|
21
|
+
} else {
|
22
|
+
return o
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
export default async function buildPoseidon() {
|
27
|
+
const bn128 = await ffjavascript.getCurveFromName("bn128", true)
|
28
|
+
|
29
|
+
const F = bn128.Fr
|
30
|
+
|
31
|
+
const opt = unsringifyConstants(F, poseidonConstants$1)
|
32
|
+
|
33
|
+
const N_ROUNDS_F = 8
|
34
|
+
const N_ROUNDS_P = [
|
35
|
+
56, 57, 56, 60, 60, 63, 64, 63, 60, 66, 60, 65, 70, 60, 64, 68,
|
36
|
+
]
|
37
|
+
|
38
|
+
const pow5 = a => F.mul(a, F.square(F.square(a, a)))
|
39
|
+
|
40
|
+
function poseidon(inputs, initState, nOut) {
|
41
|
+
assert__default["default"](inputs.length > 0)
|
42
|
+
assert__default["default"](inputs.length <= N_ROUNDS_P.length)
|
43
|
+
|
44
|
+
if (initState) {
|
45
|
+
initState = F.e(initState)
|
46
|
+
} else {
|
47
|
+
initState = F.zero
|
48
|
+
}
|
49
|
+
nOut = nOut || 1
|
50
|
+
|
51
|
+
const t = inputs.length + 1
|
52
|
+
const nRoundsF = N_ROUNDS_F
|
53
|
+
const nRoundsP = N_ROUNDS_P[t - 2]
|
54
|
+
const C = opt.C[t - 2]
|
55
|
+
const S = opt.S[t - 2]
|
56
|
+
const M = opt.M[t - 2]
|
57
|
+
const P = opt.P[t - 2]
|
58
|
+
|
59
|
+
let state = [initState, ...inputs.map(a => F.e(a))]
|
60
|
+
|
61
|
+
state = state.map((a, i) => F.add(a, C[i]))
|
62
|
+
|
63
|
+
for (let r = 0; r < nRoundsF / 2 - 1; r++) {
|
64
|
+
state = state.map(a => pow5(a))
|
65
|
+
state = state.map((a, i) => F.add(a, C[(r + 1) * t + i]))
|
66
|
+
state = state.map((_, i) =>
|
67
|
+
state.reduce((acc, a, j) => F.add(acc, F.mul(M[j][i], a)), F.zero),
|
68
|
+
)
|
69
|
+
}
|
70
|
+
state = state.map(a => pow5(a))
|
71
|
+
state = state.map((a, i) => F.add(a, C[(nRoundsF / 2 - 1 + 1) * t + i]))
|
72
|
+
state = state.map((_, i) =>
|
73
|
+
state.reduce((acc, a, j) => F.add(acc, F.mul(P[j][i], a)), F.zero),
|
74
|
+
)
|
75
|
+
for (let r = 0; r < nRoundsP; r++) {
|
76
|
+
state[0] = pow5(state[0])
|
77
|
+
state[0] = F.add(state[0], C[(nRoundsF / 2 + 1) * t + r])
|
78
|
+
|
79
|
+
const s0 = state.reduce((acc, a, j) => {
|
80
|
+
return F.add(acc, F.mul(S[(t * 2 - 1) * r + j], a))
|
81
|
+
}, F.zero)
|
82
|
+
for (let k = 1; k < t; k++) {
|
83
|
+
state[k] = F.add(
|
84
|
+
state[k],
|
85
|
+
F.mul(state[0], S[(t * 2 - 1) * r + t + k - 1]),
|
86
|
+
)
|
87
|
+
}
|
88
|
+
state[0] = s0
|
89
|
+
}
|
90
|
+
for (let r = 0; r < nRoundsF / 2 - 1; r++) {
|
91
|
+
state = state.map(a => pow5(a))
|
92
|
+
state = state.map((a, i) =>
|
93
|
+
F.add(a, C[(nRoundsF / 2 + 1) * t + nRoundsP + r * t + i]),
|
94
|
+
)
|
95
|
+
state = state.map((_, i) =>
|
96
|
+
state.reduce((acc, a, j) => F.add(acc, F.mul(M[j][i], a)), F.zero),
|
97
|
+
)
|
98
|
+
}
|
99
|
+
state = state.map(a => pow5(a))
|
100
|
+
state = state.map((_, i) =>
|
101
|
+
state.reduce((acc, a, j) => F.add(acc, F.mul(M[j][i], a)), F.zero),
|
102
|
+
)
|
103
|
+
|
104
|
+
if (nOut == 1) {
|
105
|
+
return state[0]
|
106
|
+
} else {
|
107
|
+
return state.slice(0, nOut)
|
108
|
+
}
|
109
|
+
}
|
110
|
+
|
111
|
+
poseidon.F = F
|
112
|
+
return poseidon
|
113
|
+
}
|