@opiro/core 0.0.0-stage → 0.1.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/README.md CHANGED
@@ -1,3 +1,3 @@
1
- # Temporary Holding Version
1
+ # `@opiro/core`
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Core TypeScript/WASM primitives, BN254/BabyJubJub constants, and deterministic 128-bit `opiro1...` identifier derivation for the **OPIRO Framework (v1.0)** ([https://opiro.org](https://opiro.org)).
@@ -0,0 +1,20 @@
1
+ export declare const BN254_PRIME_MODULUS_R = 21888242871839275222246405745257275088548364400416034343698204186575808495617n;
2
+ export declare const BABYJUBJUB_SUBGROUP_ORDER_L = 2736030358979909402780800718157159386076813972158567259200215660948447373041n;
3
+ export interface OpiroPublicSignalsObject {
4
+ doc_binding: string;
5
+ velocity_nullifier: string;
6
+ redaction_commitment: string;
7
+ fvh_root: string;
8
+ document_hash: string;
9
+ epoch_id: string;
10
+ role_id: string;
11
+ }
12
+ /**
13
+ * Deterministically derives a 128-bit URL-safe `opiro1...` identifier (`STATIC_DOC_BINDING`).
14
+ */
15
+ export declare function deriveStaticOpiroId(poseidonDocumentHash: string, docBindingFieldStr: string): string;
16
+ /**
17
+ * Converts the named `layer3_privacy.public_signals` manifest object into the exact
18
+ * 7-element ordered array expected by `snarkjs.groth16.verify(vKey, publicSignals, proof)`.
19
+ */
20
+ export declare function toSnarkJsPublicSignalsArray(pub: OpiroPublicSignalsObject): string[];
package/dist/index.js ADDED
@@ -0,0 +1,480 @@
1
+ // node_modules/.deno/@noble+hashes@1.8.0/node_modules/@noble/hashes/esm/utils.js
2
+ /*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
3
+ function isBytes(a) {
4
+ return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array";
5
+ }
6
+ function abytes(b, ...lengths) {
7
+ if (!isBytes(b))
8
+ throw new Error("Uint8Array expected");
9
+ if (lengths.length > 0 && !lengths.includes(b.length))
10
+ throw new Error("Uint8Array expected of length " + lengths + ", got length=" + b.length);
11
+ }
12
+ function aexists(instance, checkFinished = true) {
13
+ if (instance.destroyed)
14
+ throw new Error("Hash instance has been destroyed");
15
+ if (checkFinished && instance.finished)
16
+ throw new Error("Hash#digest() has already been called");
17
+ }
18
+ function aoutput(out, instance) {
19
+ abytes(out);
20
+ const min = instance.outputLen;
21
+ if (out.length < min) {
22
+ throw new Error("digestInto() expects output buffer of length at least " + min);
23
+ }
24
+ }
25
+ function clean(...arrays) {
26
+ for (let i = 0;i < arrays.length; i++) {
27
+ arrays[i].fill(0);
28
+ }
29
+ }
30
+ function createView(arr) {
31
+ return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
32
+ }
33
+ function rotr(word, shift) {
34
+ return word << 32 - shift | word >>> shift;
35
+ }
36
+ function utf8ToBytes(str) {
37
+ if (typeof str !== "string")
38
+ throw new Error("string expected");
39
+ return new Uint8Array(new TextEncoder().encode(str));
40
+ }
41
+ function toBytes(data) {
42
+ if (typeof data === "string")
43
+ data = utf8ToBytes(data);
44
+ abytes(data);
45
+ return data;
46
+ }
47
+ class Hash {
48
+ }
49
+ function createHasher(hashCons) {
50
+ const hashC = (msg) => hashCons().update(toBytes(msg)).digest();
51
+ const tmp = hashCons();
52
+ hashC.outputLen = tmp.outputLen;
53
+ hashC.blockLen = tmp.blockLen;
54
+ hashC.create = () => hashCons();
55
+ return hashC;
56
+ }
57
+
58
+ // node_modules/.deno/@noble+hashes@1.8.0/node_modules/@noble/hashes/esm/_md.js
59
+ function setBigUint64(view, byteOffset, value, isLE) {
60
+ if (typeof view.setBigUint64 === "function")
61
+ return view.setBigUint64(byteOffset, value, isLE);
62
+ const _32n = BigInt(32);
63
+ const _u32_max = BigInt(4294967295);
64
+ const wh = Number(value >> _32n & _u32_max);
65
+ const wl = Number(value & _u32_max);
66
+ const h = isLE ? 4 : 0;
67
+ const l = isLE ? 0 : 4;
68
+ view.setUint32(byteOffset + h, wh, isLE);
69
+ view.setUint32(byteOffset + l, wl, isLE);
70
+ }
71
+ function Chi(a, b, c) {
72
+ return a & b ^ ~a & c;
73
+ }
74
+ function Maj(a, b, c) {
75
+ return a & b ^ a & c ^ b & c;
76
+ }
77
+
78
+ class HashMD extends Hash {
79
+ constructor(blockLen, outputLen, padOffset, isLE) {
80
+ super();
81
+ this.finished = false;
82
+ this.length = 0;
83
+ this.pos = 0;
84
+ this.destroyed = false;
85
+ this.blockLen = blockLen;
86
+ this.outputLen = outputLen;
87
+ this.padOffset = padOffset;
88
+ this.isLE = isLE;
89
+ this.buffer = new Uint8Array(blockLen);
90
+ this.view = createView(this.buffer);
91
+ }
92
+ update(data) {
93
+ aexists(this);
94
+ data = toBytes(data);
95
+ abytes(data);
96
+ const { view, buffer, blockLen } = this;
97
+ const len = data.length;
98
+ for (let pos = 0;pos < len; ) {
99
+ const take = Math.min(blockLen - this.pos, len - pos);
100
+ if (take === blockLen) {
101
+ const dataView = createView(data);
102
+ for (;blockLen <= len - pos; pos += blockLen)
103
+ this.process(dataView, pos);
104
+ continue;
105
+ }
106
+ buffer.set(data.subarray(pos, pos + take), this.pos);
107
+ this.pos += take;
108
+ pos += take;
109
+ if (this.pos === blockLen) {
110
+ this.process(view, 0);
111
+ this.pos = 0;
112
+ }
113
+ }
114
+ this.length += data.length;
115
+ this.roundClean();
116
+ return this;
117
+ }
118
+ digestInto(out) {
119
+ aexists(this);
120
+ aoutput(out, this);
121
+ this.finished = true;
122
+ const { buffer, view, blockLen, isLE } = this;
123
+ let { pos } = this;
124
+ buffer[pos++] = 128;
125
+ clean(this.buffer.subarray(pos));
126
+ if (this.padOffset > blockLen - pos) {
127
+ this.process(view, 0);
128
+ pos = 0;
129
+ }
130
+ for (let i = pos;i < blockLen; i++)
131
+ buffer[i] = 0;
132
+ setBigUint64(view, blockLen - 8, BigInt(this.length * 8), isLE);
133
+ this.process(view, 0);
134
+ const oview = createView(out);
135
+ const len = this.outputLen;
136
+ if (len % 4)
137
+ throw new Error("_sha2: outputLen should be aligned to 32bit");
138
+ const outLen = len / 4;
139
+ const state = this.get();
140
+ if (outLen > state.length)
141
+ throw new Error("_sha2: outputLen bigger than state");
142
+ for (let i = 0;i < outLen; i++)
143
+ oview.setUint32(4 * i, state[i], isLE);
144
+ }
145
+ digest() {
146
+ const { buffer, outputLen } = this;
147
+ this.digestInto(buffer);
148
+ const res = buffer.slice(0, outputLen);
149
+ this.destroy();
150
+ return res;
151
+ }
152
+ _cloneInto(to) {
153
+ to || (to = new this.constructor);
154
+ to.set(...this.get());
155
+ const { blockLen, buffer, length, finished, destroyed, pos } = this;
156
+ to.destroyed = destroyed;
157
+ to.finished = finished;
158
+ to.length = length;
159
+ to.pos = pos;
160
+ if (length % blockLen)
161
+ to.buffer.set(buffer);
162
+ return to;
163
+ }
164
+ clone() {
165
+ return this._cloneInto();
166
+ }
167
+ }
168
+ var SHA256_IV = /* @__PURE__ */ Uint32Array.from([
169
+ 1779033703,
170
+ 3144134277,
171
+ 1013904242,
172
+ 2773480762,
173
+ 1359893119,
174
+ 2600822924,
175
+ 528734635,
176
+ 1541459225
177
+ ]);
178
+
179
+ // node_modules/.deno/@noble+hashes@1.8.0/node_modules/@noble/hashes/esm/sha2.js
180
+ var SHA256_K = /* @__PURE__ */ Uint32Array.from([
181
+ 1116352408,
182
+ 1899447441,
183
+ 3049323471,
184
+ 3921009573,
185
+ 961987163,
186
+ 1508970993,
187
+ 2453635748,
188
+ 2870763221,
189
+ 3624381080,
190
+ 310598401,
191
+ 607225278,
192
+ 1426881987,
193
+ 1925078388,
194
+ 2162078206,
195
+ 2614888103,
196
+ 3248222580,
197
+ 3835390401,
198
+ 4022224774,
199
+ 264347078,
200
+ 604807628,
201
+ 770255983,
202
+ 1249150122,
203
+ 1555081692,
204
+ 1996064986,
205
+ 2554220882,
206
+ 2821834349,
207
+ 2952996808,
208
+ 3210313671,
209
+ 3336571891,
210
+ 3584528711,
211
+ 113926993,
212
+ 338241895,
213
+ 666307205,
214
+ 773529912,
215
+ 1294757372,
216
+ 1396182291,
217
+ 1695183700,
218
+ 1986661051,
219
+ 2177026350,
220
+ 2456956037,
221
+ 2730485921,
222
+ 2820302411,
223
+ 3259730800,
224
+ 3345764771,
225
+ 3516065817,
226
+ 3600352804,
227
+ 4094571909,
228
+ 275423344,
229
+ 430227734,
230
+ 506948616,
231
+ 659060556,
232
+ 883997877,
233
+ 958139571,
234
+ 1322822218,
235
+ 1537002063,
236
+ 1747873779,
237
+ 1955562222,
238
+ 2024104815,
239
+ 2227730452,
240
+ 2361852424,
241
+ 2428436474,
242
+ 2756734187,
243
+ 3204031479,
244
+ 3329325298
245
+ ]);
246
+ var SHA256_W = /* @__PURE__ */ new Uint32Array(64);
247
+
248
+ class SHA256 extends HashMD {
249
+ constructor(outputLen = 32) {
250
+ super(64, outputLen, 8, false);
251
+ this.A = SHA256_IV[0] | 0;
252
+ this.B = SHA256_IV[1] | 0;
253
+ this.C = SHA256_IV[2] | 0;
254
+ this.D = SHA256_IV[3] | 0;
255
+ this.E = SHA256_IV[4] | 0;
256
+ this.F = SHA256_IV[5] | 0;
257
+ this.G = SHA256_IV[6] | 0;
258
+ this.H = SHA256_IV[7] | 0;
259
+ }
260
+ get() {
261
+ const { A, B, C, D, E, F, G, H } = this;
262
+ return [A, B, C, D, E, F, G, H];
263
+ }
264
+ set(A, B, C, D, E, F, G, H) {
265
+ this.A = A | 0;
266
+ this.B = B | 0;
267
+ this.C = C | 0;
268
+ this.D = D | 0;
269
+ this.E = E | 0;
270
+ this.F = F | 0;
271
+ this.G = G | 0;
272
+ this.H = H | 0;
273
+ }
274
+ process(view, offset) {
275
+ for (let i = 0;i < 16; i++, offset += 4)
276
+ SHA256_W[i] = view.getUint32(offset, false);
277
+ for (let i = 16;i < 64; i++) {
278
+ const W15 = SHA256_W[i - 15];
279
+ const W2 = SHA256_W[i - 2];
280
+ const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ W15 >>> 3;
281
+ const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ W2 >>> 10;
282
+ SHA256_W[i] = s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16] | 0;
283
+ }
284
+ let { A, B, C, D, E, F, G, H } = this;
285
+ for (let i = 0;i < 64; i++) {
286
+ const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);
287
+ const T1 = H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i] | 0;
288
+ const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);
289
+ const T2 = sigma0 + Maj(A, B, C) | 0;
290
+ H = G;
291
+ G = F;
292
+ F = E;
293
+ E = D + T1 | 0;
294
+ D = C;
295
+ C = B;
296
+ B = A;
297
+ A = T1 + T2 | 0;
298
+ }
299
+ A = A + this.A | 0;
300
+ B = B + this.B | 0;
301
+ C = C + this.C | 0;
302
+ D = D + this.D | 0;
303
+ E = E + this.E | 0;
304
+ F = F + this.F | 0;
305
+ G = G + this.G | 0;
306
+ H = H + this.H | 0;
307
+ this.set(A, B, C, D, E, F, G, H);
308
+ }
309
+ roundClean() {
310
+ clean(SHA256_W);
311
+ }
312
+ destroy() {
313
+ this.set(0, 0, 0, 0, 0, 0, 0, 0);
314
+ clean(this.buffer);
315
+ }
316
+ }
317
+ var sha256 = /* @__PURE__ */ createHasher(() => new SHA256);
318
+
319
+ // node_modules/.deno/@noble+hashes@1.8.0/node_modules/@noble/hashes/esm/sha256.js
320
+ var sha2562 = sha256;
321
+
322
+ // node_modules/.deno/base-x@5.0.1/node_modules/base-x/src/esm/index.js
323
+ function base(ALPHABET) {
324
+ if (ALPHABET.length >= 255) {
325
+ throw new TypeError("Alphabet too long");
326
+ }
327
+ const BASE_MAP = new Uint8Array(256);
328
+ for (let j = 0;j < BASE_MAP.length; j++) {
329
+ BASE_MAP[j] = 255;
330
+ }
331
+ for (let i = 0;i < ALPHABET.length; i++) {
332
+ const x = ALPHABET.charAt(i);
333
+ const xc = x.charCodeAt(0);
334
+ if (BASE_MAP[xc] !== 255) {
335
+ throw new TypeError(x + " is ambiguous");
336
+ }
337
+ BASE_MAP[xc] = i;
338
+ }
339
+ const BASE = ALPHABET.length;
340
+ const LEADER = ALPHABET.charAt(0);
341
+ const FACTOR = Math.log(BASE) / Math.log(256);
342
+ const iFACTOR = Math.log(256) / Math.log(BASE);
343
+ function encode(source) {
344
+ if (source instanceof Uint8Array) {} else if (ArrayBuffer.isView(source)) {
345
+ source = new Uint8Array(source.buffer, source.byteOffset, source.byteLength);
346
+ } else if (Array.isArray(source)) {
347
+ source = Uint8Array.from(source);
348
+ }
349
+ if (!(source instanceof Uint8Array)) {
350
+ throw new TypeError("Expected Uint8Array");
351
+ }
352
+ if (source.length === 0) {
353
+ return "";
354
+ }
355
+ let zeroes = 0;
356
+ let length = 0;
357
+ let pbegin = 0;
358
+ const pend = source.length;
359
+ while (pbegin !== pend && source[pbegin] === 0) {
360
+ pbegin++;
361
+ zeroes++;
362
+ }
363
+ const size = (pend - pbegin) * iFACTOR + 1 >>> 0;
364
+ const b58 = new Uint8Array(size);
365
+ while (pbegin !== pend) {
366
+ let carry = source[pbegin];
367
+ let i = 0;
368
+ for (let it1 = size - 1;(carry !== 0 || i < length) && it1 !== -1; it1--, i++) {
369
+ carry += 256 * b58[it1] >>> 0;
370
+ b58[it1] = carry % BASE >>> 0;
371
+ carry = carry / BASE >>> 0;
372
+ }
373
+ if (carry !== 0) {
374
+ throw new Error("Non-zero carry");
375
+ }
376
+ length = i;
377
+ pbegin++;
378
+ }
379
+ let it2 = size - length;
380
+ while (it2 !== size && b58[it2] === 0) {
381
+ it2++;
382
+ }
383
+ let str = LEADER.repeat(zeroes);
384
+ for (;it2 < size; ++it2) {
385
+ str += ALPHABET.charAt(b58[it2]);
386
+ }
387
+ return str;
388
+ }
389
+ function decodeUnsafe(source) {
390
+ if (typeof source !== "string") {
391
+ throw new TypeError("Expected String");
392
+ }
393
+ if (source.length === 0) {
394
+ return new Uint8Array;
395
+ }
396
+ let psz = 0;
397
+ let zeroes = 0;
398
+ let length = 0;
399
+ while (source[psz] === LEADER) {
400
+ zeroes++;
401
+ psz++;
402
+ }
403
+ const size = (source.length - psz) * FACTOR + 1 >>> 0;
404
+ const b256 = new Uint8Array(size);
405
+ while (psz < source.length) {
406
+ const charCode = source.charCodeAt(psz);
407
+ if (charCode > 255) {
408
+ return;
409
+ }
410
+ let carry = BASE_MAP[charCode];
411
+ if (carry === 255) {
412
+ return;
413
+ }
414
+ let i = 0;
415
+ for (let it3 = size - 1;(carry !== 0 || i < length) && it3 !== -1; it3--, i++) {
416
+ carry += BASE * b256[it3] >>> 0;
417
+ b256[it3] = carry % 256 >>> 0;
418
+ carry = carry / 256 >>> 0;
419
+ }
420
+ if (carry !== 0) {
421
+ throw new Error("Non-zero carry");
422
+ }
423
+ length = i;
424
+ psz++;
425
+ }
426
+ let it4 = size - length;
427
+ while (it4 !== size && b256[it4] === 0) {
428
+ it4++;
429
+ }
430
+ const vch = new Uint8Array(zeroes + (size - it4));
431
+ let j = zeroes;
432
+ while (it4 !== size) {
433
+ vch[j++] = b256[it4++];
434
+ }
435
+ return vch;
436
+ }
437
+ function decode(string) {
438
+ const buffer = decodeUnsafe(string);
439
+ if (buffer) {
440
+ return buffer;
441
+ }
442
+ throw new Error("Non-base" + BASE + " character");
443
+ }
444
+ return {
445
+ encode,
446
+ decodeUnsafe,
447
+ decode
448
+ };
449
+ }
450
+ var esm_default = base;
451
+
452
+ // node_modules/.deno/bs58@6.0.0/node_modules/bs58/src/esm/index.js
453
+ var ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
454
+ var esm_default2 = esm_default(ALPHABET);
455
+
456
+ // src/index.ts
457
+ var BN254_PRIME_MODULUS_R = 21888242871839275222246405745257275088548364400416034343698204186575808495617n;
458
+ var BABYJUBJUB_SUBGROUP_ORDER_L = 2736030358979909402780800718157159386076813972158567259200215660948447373041n;
459
+ function deriveStaticOpiroId(poseidonDocumentHash, docBindingFieldStr) {
460
+ const bytes = new TextEncoder().encode(`OPIRO-v1-ID:${poseidonDocumentHash}:${docBindingFieldStr}`);
461
+ const idBytes128 = sha2562(bytes).slice(0, 16);
462
+ return `opiro1${esm_default2.encode(idBytes128)}`;
463
+ }
464
+ function toSnarkJsPublicSignalsArray(pub) {
465
+ return [
466
+ pub.doc_binding,
467
+ pub.velocity_nullifier,
468
+ pub.redaction_commitment,
469
+ pub.fvh_root,
470
+ pub.document_hash,
471
+ pub.epoch_id,
472
+ pub.role_id
473
+ ];
474
+ }
475
+ export {
476
+ BABYJUBJUB_SUBGROUP_ORDER_L,
477
+ BN254_PRIME_MODULUS_R,
478
+ deriveStaticOpiroId,
479
+ toSnarkJsPublicSignalsArray
480
+ };
package/package.json CHANGED
@@ -1,6 +1,31 @@
1
1
  {
2
2
  "name": "@opiro/core",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.0",
4
+ "description": "OPIRO-Core SDK: Cryptographic constants, public signal formatters, and deterministic 128-bit opiro1 ID derivation.",
5
+ "license": "MIT OR Apache-2.0",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/opiro-org/opiro-js.git"
9
+ },
10
+ "homepage": "https://opiro.org",
11
+ "type": "module",
12
+ "main": "./dist/index.js",
13
+ "types": "./dist/index.d.ts",
14
+ "files": [
15
+ "dist",
16
+ "README.md"
17
+ ],
18
+ "scripts": {
19
+ "build": "tsc"
20
+ },
21
+ "dependencies": {
22
+ "@noble/hashes": "^1.5.0",
23
+ "bs58": "^6.0.0"
24
+ },
25
+ "devDependencies": {
26
+ "typescript": "^5.6.0"
27
+ },
28
+ "publishConfig": {
29
+ "access": "public"
30
+ }
31
+ }