@cardanowall/crypto-core 0.0.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.
Files changed (81) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +192 -0
  3. package/dist/aead.cjs +44 -0
  4. package/dist/aead.cjs.map +1 -0
  5. package/dist/aead.d.cts +38 -0
  6. package/dist/aead.d.ts +38 -0
  7. package/dist/aead.js +38 -0
  8. package/dist/aead.js.map +1 -0
  9. package/dist/cbor.cjs +69 -0
  10. package/dist/cbor.cjs.map +1 -0
  11. package/dist/cbor.d.cts +17 -0
  12. package/dist/cbor.d.ts +17 -0
  13. package/dist/cbor.js +64 -0
  14. package/dist/cbor.js.map +1 -0
  15. package/dist/cose.cjs +430 -0
  16. package/dist/cose.cjs.map +1 -0
  17. package/dist/cose.d.cts +72 -0
  18. package/dist/cose.d.ts +72 -0
  19. package/dist/cose.js +398 -0
  20. package/dist/cose.js.map +1 -0
  21. package/dist/hash.cjs +165 -0
  22. package/dist/hash.cjs.map +1 -0
  23. package/dist/hash.d.cts +30 -0
  24. package/dist/hash.d.ts +30 -0
  25. package/dist/hash.js +155 -0
  26. package/dist/hash.js.map +1 -0
  27. package/dist/index.cjs +1856 -0
  28. package/dist/index.cjs.map +1 -0
  29. package/dist/index.d.cts +12 -0
  30. package/dist/index.d.ts +12 -0
  31. package/dist/index.js +1759 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/kdf.cjs +26 -0
  34. package/dist/kdf.cjs.map +1 -0
  35. package/dist/kdf.d.cts +25 -0
  36. package/dist/kdf.d.ts +25 -0
  37. package/dist/kdf.js +23 -0
  38. package/dist/kdf.js.map +1 -0
  39. package/dist/kem.cjs +86 -0
  40. package/dist/kem.cjs.map +1 -0
  41. package/dist/kem.d.cts +47 -0
  42. package/dist/kem.d.ts +47 -0
  43. package/dist/kem.js +73 -0
  44. package/dist/kem.js.map +1 -0
  45. package/dist/merkle.cjs +284 -0
  46. package/dist/merkle.cjs.map +1 -0
  47. package/dist/merkle.d.cts +24 -0
  48. package/dist/merkle.d.ts +24 -0
  49. package/dist/merkle.js +279 -0
  50. package/dist/merkle.js.map +1 -0
  51. package/dist/recipient.cjs +141 -0
  52. package/dist/recipient.cjs.map +1 -0
  53. package/dist/recipient.d.cts +16 -0
  54. package/dist/recipient.d.ts +16 -0
  55. package/dist/recipient.js +135 -0
  56. package/dist/recipient.js.map +1 -0
  57. package/dist/sealed-poe.cjs +851 -0
  58. package/dist/sealed-poe.cjs.map +1 -0
  59. package/dist/sealed-poe.d.cts +134 -0
  60. package/dist/sealed-poe.d.ts +134 -0
  61. package/dist/sealed-poe.js +838 -0
  62. package/dist/sealed-poe.js.map +1 -0
  63. package/dist/seed-derive.cjs +129 -0
  64. package/dist/seed-derive.cjs.map +1 -0
  65. package/dist/seed-derive.d.cts +28 -0
  66. package/dist/seed-derive.d.ts +28 -0
  67. package/dist/seed-derive.js +101 -0
  68. package/dist/seed-derive.js.map +1 -0
  69. package/dist/sig.cjs +77 -0
  70. package/dist/sig.cjs.map +1 -0
  71. package/dist/sig.d.cts +17 -0
  72. package/dist/sig.d.ts +17 -0
  73. package/dist/sig.js +53 -0
  74. package/dist/sig.js.map +1 -0
  75. package/dist/util.cjs +36 -0
  76. package/dist/util.cjs.map +1 -0
  77. package/dist/util.d.cts +5 -0
  78. package/dist/util.d.ts +5 -0
  79. package/dist/util.js +33 -0
  80. package/dist/util.js.map +1 -0
  81. package/package.json +122 -0
package/dist/sig.cjs ADDED
@@ -0,0 +1,77 @@
1
+ 'use strict';
2
+
3
+ var ed = require('@noble/ed25519');
4
+ var sha2_js = require('@noble/hashes/sha2.js');
5
+
6
+ function _interopNamespace(e) {
7
+ if (e && e.__esModule) return e;
8
+ var n = Object.create(null);
9
+ if (e) {
10
+ Object.keys(e).forEach(function (k) {
11
+ if (k !== 'default') {
12
+ var d = Object.getOwnPropertyDescriptor(e, k);
13
+ Object.defineProperty(n, k, d.get ? d : {
14
+ enumerable: true,
15
+ get: function () { return e[k]; }
16
+ });
17
+ }
18
+ });
19
+ }
20
+ n.default = e;
21
+ return Object.freeze(n);
22
+ }
23
+
24
+ var ed__namespace = /*#__PURE__*/_interopNamespace(ed);
25
+
26
+ // src/sig/ed25519.ts
27
+ ed__namespace.hashes.sha512 = sha2_js.sha512;
28
+ var L = ed__namespace.Point.CURVE().n;
29
+ function signEd25519(opts) {
30
+ return ed__namespace.sign(opts.message, opts.seed);
31
+ }
32
+ function leBytesToBigInt(bytes) {
33
+ let value = 0n;
34
+ for (let i = bytes.length - 1; i >= 0; i--) {
35
+ value = value << 8n | BigInt(bytes[i]);
36
+ }
37
+ return value;
38
+ }
39
+ function verifyEd25519(opts) {
40
+ const { signature, message, publicKey } = opts;
41
+ if (signature.length !== 64 || publicKey.length !== 32) return false;
42
+ const S = leBytesToBigInt(signature.subarray(32, 64));
43
+ if (S >= L) return false;
44
+ let A;
45
+ let R;
46
+ try {
47
+ A = ed__namespace.Point.fromBytes(publicKey);
48
+ R = ed__namespace.Point.fromBytes(signature.subarray(0, 32));
49
+ } catch {
50
+ return false;
51
+ }
52
+ if (A.isSmallOrder() || R.isSmallOrder()) return false;
53
+ const k = leBytesToBigInt(ed__namespace.hash(concatBytes(signature.subarray(0, 32), publicKey, message))) % L;
54
+ const sB = S === 0n ? ed__namespace.Point.ZERO : ed__namespace.Point.BASE.multiplyUnsafe(S);
55
+ const kA = k === 0n ? ed__namespace.Point.ZERO : A.multiplyUnsafe(k);
56
+ return sB.subtract(kA).subtract(R).is0();
57
+ }
58
+ function concatBytes(...parts) {
59
+ let total = 0;
60
+ for (const p of parts) total += p.length;
61
+ const out = new Uint8Array(total);
62
+ let offset = 0;
63
+ for (const p of parts) {
64
+ out.set(p, offset);
65
+ offset += p.length;
66
+ }
67
+ return out;
68
+ }
69
+ function getPublicKeyEd25519(opts) {
70
+ return ed__namespace.getPublicKey(opts.seed);
71
+ }
72
+
73
+ exports.getPublicKeyEd25519 = getPublicKeyEd25519;
74
+ exports.signEd25519 = signEd25519;
75
+ exports.verifyEd25519 = verifyEd25519;
76
+ //# sourceMappingURL=sig.cjs.map
77
+ //# sourceMappingURL=sig.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/sig/ed25519.ts"],"names":["ed","sha512"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAGGA,aAAA,CAAA,MAAA,CAAO,MAAA,GAASC,cAAA;AAGnB,IAAM,CAAA,GAAOD,aAAA,CAAA,KAAA,CAAM,KAAA,EAAM,CAAE,CAAA;AAiBpB,SAAS,YAAY,IAAA,EAAmC;AAC7D,EAAA,OAAUA,aAAA,CAAA,IAAA,CAAK,IAAA,CAAK,OAAA,EAAS,IAAA,CAAK,IAAI,CAAA;AACxC;AAGA,SAAS,gBAAgB,KAAA,EAA2B;AAClD,EAAA,IAAI,KAAA,GAAQ,EAAA;AACZ,EAAA,KAAA,IAAS,IAAI,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG,CAAA,IAAK,GAAG,CAAA,EAAA,EAAK;AAC1C,IAAA,KAAA,GAAS,KAAA,IAAS,EAAA,GAAM,MAAA,CAAO,KAAA,CAAM,CAAC,CAAE,CAAA;AAAA,EAC1C;AACA,EAAA,OAAO,KAAA;AACT;AAaO,SAAS,cAAc,IAAA,EAAkC;AAC9D,EAAA,MAAM,EAAE,SAAA,EAAW,OAAA,EAAS,SAAA,EAAU,GAAI,IAAA;AAC1C,EAAA,IAAI,UAAU,MAAA,KAAW,EAAA,IAAM,SAAA,CAAU,MAAA,KAAW,IAAI,OAAO,KAAA;AAG/D,EAAA,MAAM,IAAI,eAAA,CAAgB,SAAA,CAAU,QAAA,CAAS,EAAA,EAAI,EAAE,CAAC,CAAA;AACpD,EAAA,IAAI,CAAA,IAAK,GAAG,OAAO,KAAA;AAInB,EAAA,IAAI,CAAA;AACJ,EAAA,IAAI,CAAA;AACJ,EAAA,IAAI;AACF,IAAA,CAAA,GAAOA,aAAA,CAAA,KAAA,CAAM,UAAU,SAAS,CAAA;AAChC,IAAA,CAAA,GAAOA,oBAAM,SAAA,CAAU,SAAA,CAAU,QAAA,CAAS,CAAA,EAAG,EAAE,CAAC,CAAA;AAAA,EAClD,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AAIA,EAAA,IAAI,EAAE,YAAA,EAAa,IAAK,CAAA,CAAE,YAAA,IAAgB,OAAO,KAAA;AAGjD,EAAA,MAAM,CAAA,GACJ,eAAA,CAAmBA,aAAA,CAAA,IAAA,CAAK,WAAA,CAAY,SAAA,CAAU,QAAA,CAAS,CAAA,EAAG,EAAE,CAAA,EAAG,SAAA,EAAW,OAAO,CAAC,CAAC,CAAA,GAAI,CAAA;AAIzF,EAAA,MAAM,EAAA,GAAK,MAAM,EAAA,GAAQA,aAAA,CAAA,KAAA,CAAM,OAAUA,aAAA,CAAA,KAAA,CAAM,IAAA,CAAK,eAAe,CAAC,CAAA;AACpE,EAAA,MAAM,KAAK,CAAA,KAAM,EAAA,GAAQA,oBAAM,IAAA,GAAO,CAAA,CAAE,eAAe,CAAC,CAAA;AACxD,EAAA,OAAO,GAAG,QAAA,CAAS,EAAE,EAAE,QAAA,CAAS,CAAC,EAAE,GAAA,EAAI;AACzC;AAEA,SAAS,eAAe,KAAA,EAAiC;AACvD,EAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,EAAA,KAAA,MAAW,CAAA,IAAK,KAAA,EAAO,KAAA,IAAS,CAAA,CAAE,MAAA;AAClC,EAAA,MAAM,GAAA,GAAM,IAAI,UAAA,CAAW,KAAK,CAAA;AAChC,EAAA,IAAI,MAAA,GAAS,CAAA;AACb,EAAA,KAAA,MAAW,KAAK,KAAA,EAAO;AACrB,IAAA,GAAA,CAAI,GAAA,CAAI,GAAG,MAAM,CAAA;AACjB,IAAA,MAAA,IAAU,CAAA,CAAE,MAAA;AAAA,EACd;AACA,EAAA,OAAO,GAAA;AACT;AAEO,SAAS,oBAAoB,IAAA,EAA2C;AAC7E,EAAA,OAAUA,aAAA,CAAA,YAAA,CAAa,KAAK,IAAI,CAAA;AAClC","file":"sig.cjs","sourcesContent":["import * as ed from '@noble/ed25519';\nimport { sha512 } from '@noble/hashes/sha2.js';\n\ned.hashes.sha512 = sha512;\n\n// Ed25519 group order L (= 2^252 + 27742317777372353535851937790883648493).\nconst L = ed.Point.CURVE().n;\n\nexport interface SignEd25519Opts {\n readonly seed: Uint8Array;\n readonly message: Uint8Array;\n}\n\nexport interface VerifyEd25519Opts {\n readonly publicKey: Uint8Array;\n readonly message: Uint8Array;\n readonly signature: Uint8Array;\n}\n\nexport interface GetPublicKeyEd25519Opts {\n readonly seed: Uint8Array;\n}\n\nexport function signEd25519(opts: SignEd25519Opts): Uint8Array {\n return ed.sign(opts.message, opts.seed);\n}\n\n// Little-endian 32-byte scalar → bigint.\nfunction leBytesToBigInt(bytes: Uint8Array): bigint {\n let value = 0n;\n for (let i = bytes.length - 1; i >= 0; i--) {\n value = (value << 8n) | BigInt(bytes[i]!);\n }\n return value;\n}\n\n// Strict (non-cofactored) Ed25519 verification per RFC 8032 §5.1.7, matching\n// libsodium/PyNaCl `crypto_sign_verify_detached` and ed25519-dalek\n// `verify_strict`. The cofactor-less check rejects every small-order /\n// torsion-component edge case in the C2SP/CCTV corpus, which noble's\n// `{ zip215: false }` mode does NOT (it remains cofactored: it checks\n// `[8]([S]B - [k]A - R) == 0`, accepting torsion components).\n//\n// The verification equation is the unscaled `[S]B == R + [k]A`, rewritten as\n// `[S]B - [k]A - R == identity`. We reject S >= L (non-canonical scalar) and\n// any small-order A or R up front, so a torsion component can never be smuggled\n// through the cofactor multiplication the cofactored variant performs.\nexport function verifyEd25519(opts: VerifyEd25519Opts): boolean {\n const { signature, message, publicKey } = opts;\n if (signature.length !== 64 || publicKey.length !== 32) return false;\n\n // S = LE(sig[32..64]); reject if not a canonical scalar (S >= L).\n const S = leBytesToBigInt(signature.subarray(32, 64));\n if (S >= L) return false;\n\n // Decode A (public key) and R (sig[0..32]) with the canonical (non-zip215)\n // point encoding; a non-canonical encoding throws and rejects.\n let A: ed.Point;\n let R: ed.Point;\n try {\n A = ed.Point.fromBytes(publicKey);\n R = ed.Point.fromBytes(signature.subarray(0, 32));\n } catch {\n return false;\n }\n\n // Reject small-order (cofactor-torsion) A or R: this is exactly the strictness\n // that distinguishes verify_strict from the cofactored check.\n if (A.isSmallOrder() || R.isSmallOrder()) return false;\n\n // k = SHA-512(R || A || M) reduced mod L.\n const k =\n leBytesToBigInt(ed.hash(concatBytes(signature.subarray(0, 32), publicKey, message))) % L;\n\n // Accept iff [S]B - [k]A - R == identity. `multiplyUnsafe` returns the\n // identity for a 0 scalar, but guard explicitly to avoid relying on that.\n const sB = S === 0n ? ed.Point.ZERO : ed.Point.BASE.multiplyUnsafe(S);\n const kA = k === 0n ? ed.Point.ZERO : A.multiplyUnsafe(k);\n return sB.subtract(kA).subtract(R).is0();\n}\n\nfunction concatBytes(...parts: Uint8Array[]): Uint8Array {\n let total = 0;\n for (const p of parts) total += p.length;\n const out = new Uint8Array(total);\n let offset = 0;\n for (const p of parts) {\n out.set(p, offset);\n offset += p.length;\n }\n return out;\n}\n\nexport function getPublicKeyEd25519(opts: GetPublicKeyEd25519Opts): Uint8Array {\n return ed.getPublicKey(opts.seed);\n}\n"]}
package/dist/sig.d.cts ADDED
@@ -0,0 +1,17 @@
1
+ interface SignEd25519Opts {
2
+ readonly seed: Uint8Array;
3
+ readonly message: Uint8Array;
4
+ }
5
+ interface VerifyEd25519Opts {
6
+ readonly publicKey: Uint8Array;
7
+ readonly message: Uint8Array;
8
+ readonly signature: Uint8Array;
9
+ }
10
+ interface GetPublicKeyEd25519Opts {
11
+ readonly seed: Uint8Array;
12
+ }
13
+ declare function signEd25519(opts: SignEd25519Opts): Uint8Array;
14
+ declare function verifyEd25519(opts: VerifyEd25519Opts): boolean;
15
+ declare function getPublicKeyEd25519(opts: GetPublicKeyEd25519Opts): Uint8Array;
16
+
17
+ export { type GetPublicKeyEd25519Opts, type SignEd25519Opts, type VerifyEd25519Opts, getPublicKeyEd25519, signEd25519, verifyEd25519 };
package/dist/sig.d.ts ADDED
@@ -0,0 +1,17 @@
1
+ interface SignEd25519Opts {
2
+ readonly seed: Uint8Array;
3
+ readonly message: Uint8Array;
4
+ }
5
+ interface VerifyEd25519Opts {
6
+ readonly publicKey: Uint8Array;
7
+ readonly message: Uint8Array;
8
+ readonly signature: Uint8Array;
9
+ }
10
+ interface GetPublicKeyEd25519Opts {
11
+ readonly seed: Uint8Array;
12
+ }
13
+ declare function signEd25519(opts: SignEd25519Opts): Uint8Array;
14
+ declare function verifyEd25519(opts: VerifyEd25519Opts): boolean;
15
+ declare function getPublicKeyEd25519(opts: GetPublicKeyEd25519Opts): Uint8Array;
16
+
17
+ export { type GetPublicKeyEd25519Opts, type SignEd25519Opts, type VerifyEd25519Opts, getPublicKeyEd25519, signEd25519, verifyEd25519 };
package/dist/sig.js ADDED
@@ -0,0 +1,53 @@
1
+ import * as ed from '@noble/ed25519';
2
+ import { sha512 } from '@noble/hashes/sha2.js';
3
+
4
+ // src/sig/ed25519.ts
5
+ ed.hashes.sha512 = sha512;
6
+ var L = ed.Point.CURVE().n;
7
+ function signEd25519(opts) {
8
+ return ed.sign(opts.message, opts.seed);
9
+ }
10
+ function leBytesToBigInt(bytes) {
11
+ let value = 0n;
12
+ for (let i = bytes.length - 1; i >= 0; i--) {
13
+ value = value << 8n | BigInt(bytes[i]);
14
+ }
15
+ return value;
16
+ }
17
+ function verifyEd25519(opts) {
18
+ const { signature, message, publicKey } = opts;
19
+ if (signature.length !== 64 || publicKey.length !== 32) return false;
20
+ const S = leBytesToBigInt(signature.subarray(32, 64));
21
+ if (S >= L) return false;
22
+ let A;
23
+ let R;
24
+ try {
25
+ A = ed.Point.fromBytes(publicKey);
26
+ R = ed.Point.fromBytes(signature.subarray(0, 32));
27
+ } catch {
28
+ return false;
29
+ }
30
+ if (A.isSmallOrder() || R.isSmallOrder()) return false;
31
+ const k = leBytesToBigInt(ed.hash(concatBytes(signature.subarray(0, 32), publicKey, message))) % L;
32
+ const sB = S === 0n ? ed.Point.ZERO : ed.Point.BASE.multiplyUnsafe(S);
33
+ const kA = k === 0n ? ed.Point.ZERO : A.multiplyUnsafe(k);
34
+ return sB.subtract(kA).subtract(R).is0();
35
+ }
36
+ function concatBytes(...parts) {
37
+ let total = 0;
38
+ for (const p of parts) total += p.length;
39
+ const out = new Uint8Array(total);
40
+ let offset = 0;
41
+ for (const p of parts) {
42
+ out.set(p, offset);
43
+ offset += p.length;
44
+ }
45
+ return out;
46
+ }
47
+ function getPublicKeyEd25519(opts) {
48
+ return ed.getPublicKey(opts.seed);
49
+ }
50
+
51
+ export { getPublicKeyEd25519, signEd25519, verifyEd25519 };
52
+ //# sourceMappingURL=sig.js.map
53
+ //# sourceMappingURL=sig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/sig/ed25519.ts"],"names":[],"mappings":";;;;AAGG,EAAA,CAAA,MAAA,CAAO,MAAA,GAAS,MAAA;AAGnB,IAAM,CAAA,GAAO,EAAA,CAAA,KAAA,CAAM,KAAA,EAAM,CAAE,CAAA;AAiBpB,SAAS,YAAY,IAAA,EAAmC;AAC7D,EAAA,OAAU,EAAA,CAAA,IAAA,CAAK,IAAA,CAAK,OAAA,EAAS,IAAA,CAAK,IAAI,CAAA;AACxC;AAGA,SAAS,gBAAgB,KAAA,EAA2B;AAClD,EAAA,IAAI,KAAA,GAAQ,EAAA;AACZ,EAAA,KAAA,IAAS,IAAI,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG,CAAA,IAAK,GAAG,CAAA,EAAA,EAAK;AAC1C,IAAA,KAAA,GAAS,KAAA,IAAS,EAAA,GAAM,MAAA,CAAO,KAAA,CAAM,CAAC,CAAE,CAAA;AAAA,EAC1C;AACA,EAAA,OAAO,KAAA;AACT;AAaO,SAAS,cAAc,IAAA,EAAkC;AAC9D,EAAA,MAAM,EAAE,SAAA,EAAW,OAAA,EAAS,SAAA,EAAU,GAAI,IAAA;AAC1C,EAAA,IAAI,UAAU,MAAA,KAAW,EAAA,IAAM,SAAA,CAAU,MAAA,KAAW,IAAI,OAAO,KAAA;AAG/D,EAAA,MAAM,IAAI,eAAA,CAAgB,SAAA,CAAU,QAAA,CAAS,EAAA,EAAI,EAAE,CAAC,CAAA;AACpD,EAAA,IAAI,CAAA,IAAK,GAAG,OAAO,KAAA;AAInB,EAAA,IAAI,CAAA;AACJ,EAAA,IAAI,CAAA;AACJ,EAAA,IAAI;AACF,IAAA,CAAA,GAAO,EAAA,CAAA,KAAA,CAAM,UAAU,SAAS,CAAA;AAChC,IAAA,CAAA,GAAO,SAAM,SAAA,CAAU,SAAA,CAAU,QAAA,CAAS,CAAA,EAAG,EAAE,CAAC,CAAA;AAAA,EAClD,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AAIA,EAAA,IAAI,EAAE,YAAA,EAAa,IAAK,CAAA,CAAE,YAAA,IAAgB,OAAO,KAAA;AAGjD,EAAA,MAAM,CAAA,GACJ,eAAA,CAAmB,EAAA,CAAA,IAAA,CAAK,WAAA,CAAY,SAAA,CAAU,QAAA,CAAS,CAAA,EAAG,EAAE,CAAA,EAAG,SAAA,EAAW,OAAO,CAAC,CAAC,CAAA,GAAI,CAAA;AAIzF,EAAA,MAAM,EAAA,GAAK,MAAM,EAAA,GAAQ,EAAA,CAAA,KAAA,CAAM,OAAU,EAAA,CAAA,KAAA,CAAM,IAAA,CAAK,eAAe,CAAC,CAAA;AACpE,EAAA,MAAM,KAAK,CAAA,KAAM,EAAA,GAAQ,SAAM,IAAA,GAAO,CAAA,CAAE,eAAe,CAAC,CAAA;AACxD,EAAA,OAAO,GAAG,QAAA,CAAS,EAAE,EAAE,QAAA,CAAS,CAAC,EAAE,GAAA,EAAI;AACzC;AAEA,SAAS,eAAe,KAAA,EAAiC;AACvD,EAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,EAAA,KAAA,MAAW,CAAA,IAAK,KAAA,EAAO,KAAA,IAAS,CAAA,CAAE,MAAA;AAClC,EAAA,MAAM,GAAA,GAAM,IAAI,UAAA,CAAW,KAAK,CAAA;AAChC,EAAA,IAAI,MAAA,GAAS,CAAA;AACb,EAAA,KAAA,MAAW,KAAK,KAAA,EAAO;AACrB,IAAA,GAAA,CAAI,GAAA,CAAI,GAAG,MAAM,CAAA;AACjB,IAAA,MAAA,IAAU,CAAA,CAAE,MAAA;AAAA,EACd;AACA,EAAA,OAAO,GAAA;AACT;AAEO,SAAS,oBAAoB,IAAA,EAA2C;AAC7E,EAAA,OAAU,EAAA,CAAA,YAAA,CAAa,KAAK,IAAI,CAAA;AAClC","file":"sig.js","sourcesContent":["import * as ed from '@noble/ed25519';\nimport { sha512 } from '@noble/hashes/sha2.js';\n\ned.hashes.sha512 = sha512;\n\n// Ed25519 group order L (= 2^252 + 27742317777372353535851937790883648493).\nconst L = ed.Point.CURVE().n;\n\nexport interface SignEd25519Opts {\n readonly seed: Uint8Array;\n readonly message: Uint8Array;\n}\n\nexport interface VerifyEd25519Opts {\n readonly publicKey: Uint8Array;\n readonly message: Uint8Array;\n readonly signature: Uint8Array;\n}\n\nexport interface GetPublicKeyEd25519Opts {\n readonly seed: Uint8Array;\n}\n\nexport function signEd25519(opts: SignEd25519Opts): Uint8Array {\n return ed.sign(opts.message, opts.seed);\n}\n\n// Little-endian 32-byte scalar → bigint.\nfunction leBytesToBigInt(bytes: Uint8Array): bigint {\n let value = 0n;\n for (let i = bytes.length - 1; i >= 0; i--) {\n value = (value << 8n) | BigInt(bytes[i]!);\n }\n return value;\n}\n\n// Strict (non-cofactored) Ed25519 verification per RFC 8032 §5.1.7, matching\n// libsodium/PyNaCl `crypto_sign_verify_detached` and ed25519-dalek\n// `verify_strict`. The cofactor-less check rejects every small-order /\n// torsion-component edge case in the C2SP/CCTV corpus, which noble's\n// `{ zip215: false }` mode does NOT (it remains cofactored: it checks\n// `[8]([S]B - [k]A - R) == 0`, accepting torsion components).\n//\n// The verification equation is the unscaled `[S]B == R + [k]A`, rewritten as\n// `[S]B - [k]A - R == identity`. We reject S >= L (non-canonical scalar) and\n// any small-order A or R up front, so a torsion component can never be smuggled\n// through the cofactor multiplication the cofactored variant performs.\nexport function verifyEd25519(opts: VerifyEd25519Opts): boolean {\n const { signature, message, publicKey } = opts;\n if (signature.length !== 64 || publicKey.length !== 32) return false;\n\n // S = LE(sig[32..64]); reject if not a canonical scalar (S >= L).\n const S = leBytesToBigInt(signature.subarray(32, 64));\n if (S >= L) return false;\n\n // Decode A (public key) and R (sig[0..32]) with the canonical (non-zip215)\n // point encoding; a non-canonical encoding throws and rejects.\n let A: ed.Point;\n let R: ed.Point;\n try {\n A = ed.Point.fromBytes(publicKey);\n R = ed.Point.fromBytes(signature.subarray(0, 32));\n } catch {\n return false;\n }\n\n // Reject small-order (cofactor-torsion) A or R: this is exactly the strictness\n // that distinguishes verify_strict from the cofactored check.\n if (A.isSmallOrder() || R.isSmallOrder()) return false;\n\n // k = SHA-512(R || A || M) reduced mod L.\n const k =\n leBytesToBigInt(ed.hash(concatBytes(signature.subarray(0, 32), publicKey, message))) % L;\n\n // Accept iff [S]B - [k]A - R == identity. `multiplyUnsafe` returns the\n // identity for a 0 scalar, but guard explicitly to avoid relying on that.\n const sB = S === 0n ? ed.Point.ZERO : ed.Point.BASE.multiplyUnsafe(S);\n const kA = k === 0n ? ed.Point.ZERO : A.multiplyUnsafe(k);\n return sB.subtract(kA).subtract(R).is0();\n}\n\nfunction concatBytes(...parts: Uint8Array[]): Uint8Array {\n let total = 0;\n for (const p of parts) total += p.length;\n const out = new Uint8Array(total);\n let offset = 0;\n for (const p of parts) {\n out.set(p, offset);\n offset += p.length;\n }\n return out;\n}\n\nexport function getPublicKeyEd25519(opts: GetPublicKeyEd25519Opts): Uint8Array {\n return ed.getPublicKey(opts.seed);\n}\n"]}
package/dist/util.cjs ADDED
@@ -0,0 +1,36 @@
1
+ 'use strict';
2
+
3
+ // src/util/compare-ct.ts
4
+ function compareCt(a, b) {
5
+ if (a.length !== b.length) return false;
6
+ let diff = 0;
7
+ for (let i = 0; i < a.length; i++) diff |= a[i] ^ b[i];
8
+ return diff === 0;
9
+ }
10
+
11
+ // src/util/hex.ts
12
+ function hexToBytes(hex) {
13
+ if ((hex.length & 1) !== 0) {
14
+ throw new Error(`hexToBytes: input length ${hex.length} is not even`);
15
+ }
16
+ const out = new Uint8Array(hex.length >>> 1);
17
+ for (let i = 0; i < out.length; i++) {
18
+ const hi = charToNibble(hex.charCodeAt(i * 2));
19
+ const lo = charToNibble(hex.charCodeAt(i * 2 + 1));
20
+ if (hi < 0 || lo < 0) {
21
+ throw new Error(`hexToBytes: non-hex character at offset ${i * 2}`);
22
+ }
23
+ out[i] = hi << 4 | lo;
24
+ }
25
+ return out;
26
+ }
27
+ function charToNibble(code) {
28
+ if (code >= 48 && code <= 57) return code - 48;
29
+ if (code >= 97 && code <= 102) return code - 87;
30
+ return -1;
31
+ }
32
+
33
+ exports.compareCt = compareCt;
34
+ exports.hexToBytes = hexToBytes;
35
+ //# sourceMappingURL=util.cjs.map
36
+ //# sourceMappingURL=util.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/util/compare-ct.ts","../src/util/hex.ts"],"names":[],"mappings":";;;AAKO,SAAS,SAAA,CAAU,GAAe,CAAA,EAAwB;AAC/D,EAAA,IAAI,CAAA,CAAE,MAAA,KAAW,CAAA,CAAE,MAAA,EAAQ,OAAO,KAAA;AAClC,EAAA,IAAI,IAAA,GAAO,CAAA;AAIX,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,CAAE,MAAA,EAAQ,CAAA,EAAA,EAAK,IAAA,IAAS,CAAA,CAAE,CAAC,CAAA,GAAgB,CAAA,CAAE,CAAC,CAAA;AAClE,EAAA,OAAO,IAAA,KAAS,CAAA;AAClB;;;ACPO,SAAS,WAAW,GAAA,EAAyB;AAClD,EAAA,IAAA,CAAK,GAAA,CAAI,MAAA,GAAS,CAAA,MAAO,CAAA,EAAG;AAC1B,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,yBAAA,EAA4B,GAAA,CAAI,MAAM,CAAA,YAAA,CAAc,CAAA;AAAA,EACtE;AACA,EAAA,MAAM,GAAA,GAAM,IAAI,UAAA,CAAW,GAAA,CAAI,WAAW,CAAC,CAAA;AAC3C,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,GAAA,CAAI,QAAQ,CAAA,EAAA,EAAK;AACnC,IAAA,MAAM,KAAK,YAAA,CAAa,GAAA,CAAI,UAAA,CAAW,CAAA,GAAI,CAAC,CAAC,CAAA;AAC7C,IAAA,MAAM,KAAK,YAAA,CAAa,GAAA,CAAI,WAAW,CAAA,GAAI,CAAA,GAAI,CAAC,CAAC,CAAA;AACjD,IAAA,IAAI,EAAA,GAAK,CAAA,IAAK,EAAA,GAAK,CAAA,EAAG;AACpB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,wCAAA,EAA2C,CAAA,GAAI,CAAC,CAAA,CAAE,CAAA;AAAA,IACpE;AACA,IAAA,GAAA,CAAI,CAAC,CAAA,GAAK,EAAA,IAAM,CAAA,GAAK,EAAA;AAAA,EACvB;AACA,EAAA,OAAO,GAAA;AACT;AAEA,SAAS,aAAa,IAAA,EAAsB;AAC1C,EAAA,IAAI,IAAA,IAAQ,EAAA,IAAM,IAAA,IAAQ,EAAA,SAAW,IAAA,GAAO,EAAA;AAC5C,EAAA,IAAI,IAAA,IAAQ,EAAA,IAAM,IAAA,IAAQ,GAAA,SAAY,IAAA,GAAO,EAAA;AAC7C,EAAA,OAAO,EAAA;AACT","file":"util.cjs","sourcesContent":["// Isomorphic constant-time byte-equality. crypto-core is browser-safe by\n// design, so we cannot import `node:crypto.timingSafeEqual` — webpack rejects\n// the `node:` scheme in the browser bundle. A pure-JS XOR loop is constant-time\n// for equal-length inputs; length mismatch is a deliberate early-return (the\n// API surface itself leaks length, same as node's timingSafeEqual which throws).\nexport function compareCt(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false;\n let diff = 0;\n // Lengths are equal and `i` stays in-bounds, so both indexes are always\n // defined — no nullish guard is needed (and one would read as a guard for\n // an impossible case).\n for (let i = 0; i < a.length; i++) diff |= (a[i] as number) ^ (b[i] as number);\n return diff === 0;\n}\n","// Lower-case hex → bytes decoder. Caller is responsible for normalising\n// case + stripping any 0x prefix; the input must match /^[0-9a-f]*$/ with\n// even length. The decoder allocates exactly one fresh Uint8Array and\n// returns it as-is so callers downstream can rely on reference identity\n// (e.g. caller-owns-zeroize discipline for raw-seed import: the caller can\n// wipe the exact buffer this function returned).\nexport function hexToBytes(hex: string): Uint8Array {\n if ((hex.length & 1) !== 0) {\n throw new Error(`hexToBytes: input length ${hex.length} is not even`);\n }\n const out = new Uint8Array(hex.length >>> 1);\n for (let i = 0; i < out.length; i++) {\n const hi = charToNibble(hex.charCodeAt(i * 2));\n const lo = charToNibble(hex.charCodeAt(i * 2 + 1));\n if (hi < 0 || lo < 0) {\n throw new Error(`hexToBytes: non-hex character at offset ${i * 2}`);\n }\n out[i] = (hi << 4) | lo;\n }\n return out;\n}\n\nfunction charToNibble(code: number): number {\n if (code >= 48 && code <= 57) return code - 48;\n if (code >= 97 && code <= 102) return code - 87;\n return -1;\n}\n"]}
@@ -0,0 +1,5 @@
1
+ declare function compareCt(a: Uint8Array, b: Uint8Array): boolean;
2
+
3
+ declare function hexToBytes(hex: string): Uint8Array;
4
+
5
+ export { compareCt, hexToBytes };
package/dist/util.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ declare function compareCt(a: Uint8Array, b: Uint8Array): boolean;
2
+
3
+ declare function hexToBytes(hex: string): Uint8Array;
4
+
5
+ export { compareCt, hexToBytes };
package/dist/util.js ADDED
@@ -0,0 +1,33 @@
1
+ // src/util/compare-ct.ts
2
+ function compareCt(a, b) {
3
+ if (a.length !== b.length) return false;
4
+ let diff = 0;
5
+ for (let i = 0; i < a.length; i++) diff |= a[i] ^ b[i];
6
+ return diff === 0;
7
+ }
8
+
9
+ // src/util/hex.ts
10
+ function hexToBytes(hex) {
11
+ if ((hex.length & 1) !== 0) {
12
+ throw new Error(`hexToBytes: input length ${hex.length} is not even`);
13
+ }
14
+ const out = new Uint8Array(hex.length >>> 1);
15
+ for (let i = 0; i < out.length; i++) {
16
+ const hi = charToNibble(hex.charCodeAt(i * 2));
17
+ const lo = charToNibble(hex.charCodeAt(i * 2 + 1));
18
+ if (hi < 0 || lo < 0) {
19
+ throw new Error(`hexToBytes: non-hex character at offset ${i * 2}`);
20
+ }
21
+ out[i] = hi << 4 | lo;
22
+ }
23
+ return out;
24
+ }
25
+ function charToNibble(code) {
26
+ if (code >= 48 && code <= 57) return code - 48;
27
+ if (code >= 97 && code <= 102) return code - 87;
28
+ return -1;
29
+ }
30
+
31
+ export { compareCt, hexToBytes };
32
+ //# sourceMappingURL=util.js.map
33
+ //# sourceMappingURL=util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/util/compare-ct.ts","../src/util/hex.ts"],"names":[],"mappings":";AAKO,SAAS,SAAA,CAAU,GAAe,CAAA,EAAwB;AAC/D,EAAA,IAAI,CAAA,CAAE,MAAA,KAAW,CAAA,CAAE,MAAA,EAAQ,OAAO,KAAA;AAClC,EAAA,IAAI,IAAA,GAAO,CAAA;AAIX,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,CAAE,MAAA,EAAQ,CAAA,EAAA,EAAK,IAAA,IAAS,CAAA,CAAE,CAAC,CAAA,GAAgB,CAAA,CAAE,CAAC,CAAA;AAClE,EAAA,OAAO,IAAA,KAAS,CAAA;AAClB;;;ACPO,SAAS,WAAW,GAAA,EAAyB;AAClD,EAAA,IAAA,CAAK,GAAA,CAAI,MAAA,GAAS,CAAA,MAAO,CAAA,EAAG;AAC1B,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,yBAAA,EAA4B,GAAA,CAAI,MAAM,CAAA,YAAA,CAAc,CAAA;AAAA,EACtE;AACA,EAAA,MAAM,GAAA,GAAM,IAAI,UAAA,CAAW,GAAA,CAAI,WAAW,CAAC,CAAA;AAC3C,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,GAAA,CAAI,QAAQ,CAAA,EAAA,EAAK;AACnC,IAAA,MAAM,KAAK,YAAA,CAAa,GAAA,CAAI,UAAA,CAAW,CAAA,GAAI,CAAC,CAAC,CAAA;AAC7C,IAAA,MAAM,KAAK,YAAA,CAAa,GAAA,CAAI,WAAW,CAAA,GAAI,CAAA,GAAI,CAAC,CAAC,CAAA;AACjD,IAAA,IAAI,EAAA,GAAK,CAAA,IAAK,EAAA,GAAK,CAAA,EAAG;AACpB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,wCAAA,EAA2C,CAAA,GAAI,CAAC,CAAA,CAAE,CAAA;AAAA,IACpE;AACA,IAAA,GAAA,CAAI,CAAC,CAAA,GAAK,EAAA,IAAM,CAAA,GAAK,EAAA;AAAA,EACvB;AACA,EAAA,OAAO,GAAA;AACT;AAEA,SAAS,aAAa,IAAA,EAAsB;AAC1C,EAAA,IAAI,IAAA,IAAQ,EAAA,IAAM,IAAA,IAAQ,EAAA,SAAW,IAAA,GAAO,EAAA;AAC5C,EAAA,IAAI,IAAA,IAAQ,EAAA,IAAM,IAAA,IAAQ,GAAA,SAAY,IAAA,GAAO,EAAA;AAC7C,EAAA,OAAO,EAAA;AACT","file":"util.js","sourcesContent":["// Isomorphic constant-time byte-equality. crypto-core is browser-safe by\n// design, so we cannot import `node:crypto.timingSafeEqual` — webpack rejects\n// the `node:` scheme in the browser bundle. A pure-JS XOR loop is constant-time\n// for equal-length inputs; length mismatch is a deliberate early-return (the\n// API surface itself leaks length, same as node's timingSafeEqual which throws).\nexport function compareCt(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false;\n let diff = 0;\n // Lengths are equal and `i` stays in-bounds, so both indexes are always\n // defined — no nullish guard is needed (and one would read as a guard for\n // an impossible case).\n for (let i = 0; i < a.length; i++) diff |= (a[i] as number) ^ (b[i] as number);\n return diff === 0;\n}\n","// Lower-case hex → bytes decoder. Caller is responsible for normalising\n// case + stripping any 0x prefix; the input must match /^[0-9a-f]*$/ with\n// even length. The decoder allocates exactly one fresh Uint8Array and\n// returns it as-is so callers downstream can rely on reference identity\n// (e.g. caller-owns-zeroize discipline for raw-seed import: the caller can\n// wipe the exact buffer this function returned).\nexport function hexToBytes(hex: string): Uint8Array {\n if ((hex.length & 1) !== 0) {\n throw new Error(`hexToBytes: input length ${hex.length} is not even`);\n }\n const out = new Uint8Array(hex.length >>> 1);\n for (let i = 0; i < out.length; i++) {\n const hi = charToNibble(hex.charCodeAt(i * 2));\n const lo = charToNibble(hex.charCodeAt(i * 2 + 1));\n if (hi < 0 || lo < 0) {\n throw new Error(`hexToBytes: non-hex character at offset ${i * 2}`);\n }\n out[i] = (hi << 4) | lo;\n }\n return out;\n}\n\nfunction charToNibble(code: number): number {\n if (code >= 48 && code <= 57) return code - 48;\n if (code >= 97 && code <= 102) return code - 87;\n return -1;\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,122 @@
1
+ {
2
+ "name": "@cardanowall/crypto-core",
3
+ "version": "0.0.0",
4
+ "type": "module",
5
+ "description": "Closed-catalogue cryptographic primitives for CIP-309 Proof-of-Existence (TypeScript reference implementation; byte-identical Python parity twin).",
6
+ "license": "Apache-2.0",
7
+ "author": "Cardanowall <hello@cardanowall.com>",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/cardanowall/cip309-ts.git",
11
+ "directory": "packages/crypto-core"
12
+ },
13
+ "homepage": "https://github.com/cardanowall/cip309-ts#readme",
14
+ "bugs": {
15
+ "url": "https://github.com/cardanowall/cip309-ts/issues"
16
+ },
17
+ "main": "./dist/index.cjs",
18
+ "module": "./dist/index.js",
19
+ "types": "./dist/index.d.ts",
20
+ "exports": {
21
+ ".": {
22
+ "types": "./dist/index.d.ts",
23
+ "development": "./src/index.ts",
24
+ "import": "./dist/index.js",
25
+ "require": "./dist/index.cjs"
26
+ },
27
+ "./hash": {
28
+ "types": "./dist/hash.d.ts",
29
+ "development": "./src/hash/index.ts",
30
+ "import": "./dist/hash.js",
31
+ "require": "./dist/hash.cjs"
32
+ },
33
+ "./kdf": {
34
+ "types": "./dist/kdf.d.ts",
35
+ "development": "./src/kdf/index.ts",
36
+ "import": "./dist/kdf.js",
37
+ "require": "./dist/kdf.cjs"
38
+ },
39
+ "./sig": {
40
+ "types": "./dist/sig.d.ts",
41
+ "development": "./src/sig/index.ts",
42
+ "import": "./dist/sig.js",
43
+ "require": "./dist/sig.cjs"
44
+ },
45
+ "./kem": {
46
+ "types": "./dist/kem.d.ts",
47
+ "development": "./src/kem/index.ts",
48
+ "import": "./dist/kem.js",
49
+ "require": "./dist/kem.cjs"
50
+ },
51
+ "./aead": {
52
+ "types": "./dist/aead.d.ts",
53
+ "development": "./src/aead/index.ts",
54
+ "import": "./dist/aead.js",
55
+ "require": "./dist/aead.cjs"
56
+ },
57
+ "./util": {
58
+ "types": "./dist/util.d.ts",
59
+ "development": "./src/util/index.ts",
60
+ "import": "./dist/util.js",
61
+ "require": "./dist/util.cjs"
62
+ },
63
+ "./cbor": {
64
+ "types": "./dist/cbor.d.ts",
65
+ "development": "./src/cbor/index.ts",
66
+ "import": "./dist/cbor.js",
67
+ "require": "./dist/cbor.cjs"
68
+ },
69
+ "./cose": {
70
+ "types": "./dist/cose.d.ts",
71
+ "development": "./src/cose/index.ts",
72
+ "import": "./dist/cose.js",
73
+ "require": "./dist/cose.cjs"
74
+ },
75
+ "./seed-derive": {
76
+ "types": "./dist/seed-derive.d.ts",
77
+ "development": "./src/seed-derive/index.ts",
78
+ "import": "./dist/seed-derive.js",
79
+ "require": "./dist/seed-derive.cjs"
80
+ },
81
+ "./sealed-poe": {
82
+ "types": "./dist/sealed-poe.d.ts",
83
+ "development": "./src/sealed-poe/index.ts",
84
+ "import": "./dist/sealed-poe.js",
85
+ "require": "./dist/sealed-poe.cjs"
86
+ },
87
+ "./merkle": {
88
+ "types": "./dist/merkle.d.ts",
89
+ "development": "./src/merkle/index.ts",
90
+ "import": "./dist/merkle.js",
91
+ "require": "./dist/merkle.cjs"
92
+ },
93
+ "./recipient": {
94
+ "types": "./dist/recipient.d.ts",
95
+ "development": "./src/recipient/index.ts",
96
+ "import": "./dist/recipient.js",
97
+ "require": "./dist/recipient.cjs"
98
+ }
99
+ },
100
+ "files": [
101
+ "dist",
102
+ "README.md",
103
+ "LICENSE"
104
+ ],
105
+ "devDependencies": {
106
+ "@scure/base": "2.2.0",
107
+ "tsup": "^8.5.1"
108
+ },
109
+ "dependencies": {
110
+ "@noble/ciphers": "^2.2.0",
111
+ "@noble/curves": "^2.2.0",
112
+ "@noble/ed25519": "^3.1.0",
113
+ "@noble/hashes": "^2.2.0",
114
+ "@noble/post-quantum": "^0.6.1",
115
+ "cbor2": "^2.3.0",
116
+ "hash-wasm": "4.12.0"
117
+ },
118
+ "scripts": {
119
+ "build": "tsup",
120
+ "typecheck": "tsc --noEmit -p tsconfig.json"
121
+ }
122
+ }