@degenerate/sharedata 0.2.6 → 0.3.1

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 (80) hide show
  1. package/README.md +31 -0
  2. package/dist/index.d.ts +16 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +20 -0
  5. package/dist/manager/share-data-manager-events.d.ts +27 -0
  6. package/dist/manager/share-data-manager-events.d.ts.map +1 -0
  7. package/dist/manager/share-data-manager-events.js +2 -0
  8. package/dist/manager/share-data-manager.d.ts +84 -0
  9. package/dist/manager/share-data-manager.d.ts.map +1 -0
  10. package/dist/manager/share-data-manager.js +210 -0
  11. package/dist/persistence/block-factory-registry.d.ts +51 -0
  12. package/dist/persistence/block-factory-registry.d.ts.map +1 -0
  13. package/dist/persistence/block-factory-registry.js +36 -0
  14. package/dist/persistence/deserialize-share-data.d.ts +18 -0
  15. package/dist/persistence/deserialize-share-data.d.ts.map +1 -0
  16. package/dist/persistence/deserialize-share-data.js +144 -0
  17. package/dist/persistence/file-share-data-repository.d.ts +30 -0
  18. package/dist/persistence/file-share-data-repository.d.ts.map +1 -0
  19. package/dist/persistence/file-share-data-repository.js +147 -0
  20. package/dist/persistence/firestore-share-data-repository.d.ts +38 -0
  21. package/dist/persistence/firestore-share-data-repository.d.ts.map +1 -0
  22. package/dist/persistence/firestore-share-data-repository.js +78 -0
  23. package/dist/persistence/in-memory-share-data-repository.d.ts +19 -0
  24. package/dist/persistence/in-memory-share-data-repository.d.ts.map +1 -0
  25. package/dist/persistence/in-memory-share-data-repository.js +48 -0
  26. package/dist/persistence/serialize-share-data.d.ts +22 -0
  27. package/dist/persistence/serialize-share-data.d.ts.map +1 -0
  28. package/dist/persistence/serialize-share-data.js +62 -0
  29. package/dist/persistence/share-data-repository.d.ts +49 -0
  30. package/dist/persistence/share-data-repository.d.ts.map +1 -0
  31. package/dist/persistence/share-data-repository.js +2 -0
  32. package/dist/share-data/creation/create-share-data-initial-crypto.d.ts +11 -0
  33. package/dist/share-data/creation/create-share-data-initial-crypto.d.ts.map +1 -0
  34. package/dist/share-data/creation/create-share-data-initial-crypto.js +26 -0
  35. package/dist/share-data/helpers/calculate-share-data-string.d.ts +21 -0
  36. package/dist/share-data/helpers/calculate-share-data-string.d.ts.map +1 -0
  37. package/dist/share-data/helpers/calculate-share-data-string.js +71 -0
  38. package/dist/share-data/helpers/config/default-share-data-string.config.d.ts +7 -0
  39. package/dist/share-data/helpers/config/default-share-data-string.config.d.ts.map +1 -0
  40. package/dist/share-data/helpers/config/default-share-data-string.config.js +25 -0
  41. package/dist/share-data/helpers/config/stringify.d.ts +5 -0
  42. package/dist/share-data/helpers/config/stringify.d.ts.map +1 -0
  43. package/dist/share-data/helpers/config/stringify.js +10 -0
  44. package/dist/share-data/helpers/get-array-string.d.ts +6 -0
  45. package/dist/share-data/helpers/get-array-string.d.ts.map +1 -0
  46. package/dist/share-data/helpers/get-array-string.js +17 -0
  47. package/dist/share-data/proofs/creation/build-transaction-proposal-signer.d.ts +57 -0
  48. package/dist/share-data/proofs/creation/build-transaction-proposal-signer.d.ts.map +1 -0
  49. package/dist/share-data/proofs/creation/build-transaction-proposal-signer.js +36 -0
  50. package/dist/share-data/proofs/creation/create-share-data-proposal-proof.d.ts +12 -0
  51. package/dist/share-data/proofs/creation/create-share-data-proposal-proof.d.ts.map +1 -0
  52. package/dist/share-data/proofs/creation/create-share-data-proposal-proof.js +41 -0
  53. package/dist/share-data/proofs/creation/create-transaction-proposal-proof.d.ts +27 -0
  54. package/dist/share-data/proofs/creation/create-transaction-proposal-proof.d.ts.map +1 -0
  55. package/dist/share-data/proofs/creation/create-transaction-proposal-proof.js +58 -0
  56. package/dist/share-data/proofs/helpers/create-share-data-string-to-sign.d.ts +12 -0
  57. package/dist/share-data/proofs/helpers/create-share-data-string-to-sign.d.ts.map +1 -0
  58. package/dist/share-data/proofs/helpers/create-share-data-string-to-sign.js +17 -0
  59. package/dist/share-data/proofs/helpers/create-transaction-proposal-string-to-sign.d.ts +24 -0
  60. package/dist/share-data/proofs/helpers/create-transaction-proposal-string-to-sign.d.ts.map +1 -0
  61. package/dist/share-data/proofs/helpers/create-transaction-proposal-string-to-sign.js +29 -0
  62. package/dist/share-data/proofs/helpers/get-previous-hash-from-share-data.d.ts +9 -0
  63. package/dist/share-data/proofs/helpers/get-previous-hash-from-share-data.d.ts.map +1 -0
  64. package/dist/share-data/proofs/helpers/get-previous-hash-from-share-data.js +28 -0
  65. package/dist/share-data/proofs/helpers/hash-proposed-state.d.ts +12 -0
  66. package/dist/share-data/proofs/helpers/hash-proposed-state.d.ts.map +1 -0
  67. package/dist/share-data/proofs/helpers/hash-proposed-state.js +18 -0
  68. package/dist/share-data/proofs/testing/test-proof-signer.d.ts +53 -0
  69. package/dist/share-data/proofs/testing/test-proof-signer.d.ts.map +1 -0
  70. package/dist/share-data/proofs/testing/test-proof-signer.js +113 -0
  71. package/dist/share-data/proofs/verification/verify-share-data-proposal-proof.d.ts +40 -0
  72. package/dist/share-data/proofs/verification/verify-share-data-proposal-proof.d.ts.map +1 -0
  73. package/dist/share-data/proofs/verification/verify-share-data-proposal-proof.js +126 -0
  74. package/dist/share-data/proofs/verification/verify-transaction-proposal-proof.d.ts +37 -0
  75. package/dist/share-data/proofs/verification/verify-transaction-proposal-proof.d.ts.map +1 -0
  76. package/dist/share-data/proofs/verification/verify-transaction-proposal-proof.js +125 -0
  77. package/dist/share-data/share-data.d.ts +180 -27
  78. package/dist/share-data/share-data.d.ts.map +1 -1
  79. package/dist/share-data/share-data.js +303 -60
  80. package/package.json +33 -12
@@ -0,0 +1,12 @@
1
+ import { IShareData } from '@degenerate/generic';
2
+ /**
3
+ * Canonical hash of a proposed ShareData state.
4
+ *
5
+ * Uses the same serialization the default string config applies to the live
6
+ * `currentState` (`JSON.stringify` via `stringify`), so a proposed state
7
+ * hashes identically whether it is computed here at signing time or recomputed
8
+ * at verify time from the same object. Keeping this in one helper guarantees
9
+ * the signer and verifier never drift apart on how proposed state is hashed.
10
+ */
11
+ export declare const hashProposedState: (proposedState: IShareData) => string;
12
+ //# sourceMappingURL=hash-proposed-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash-proposed-state.d.ts","sourceRoot":"","sources":["../../../../src/share-data/proofs/helpers/hash-proposed-state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGhE;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,GAAI,eAAe,UAAU,KAAG,MAE7D,CAAC"}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.hashProposedState = void 0;
4
+ const generic_1 = require("@degenerate/generic");
5
+ const stringify_1 = require("../../helpers/config/stringify");
6
+ /**
7
+ * Canonical hash of a proposed ShareData state.
8
+ *
9
+ * Uses the same serialization the default string config applies to the live
10
+ * `currentState` (`JSON.stringify` via `stringify`), so a proposed state
11
+ * hashes identically whether it is computed here at signing time or recomputed
12
+ * at verify time from the same object. Keeping this in one helper guarantees
13
+ * the signer and verifier never drift apart on how proposed state is hashed.
14
+ */
15
+ const hashProposedState = (proposedState) => {
16
+ return (0, generic_1.calculateHash)((0, stringify_1.stringify)(proposedState));
17
+ };
18
+ exports.hashProposedState = hashProposedState;
@@ -0,0 +1,53 @@
1
+ import { EllipticalCurvesSigning, IShareData, IShareDataCryptoProof } from '@degenerate/generic';
2
+ import { ShareData } from '../../share-data';
3
+ /**
4
+ * Generate a fresh elliptic keypair suitable for signing ShareData proofs
5
+ * in tests. Returns the hex-encoded private and public keys so the caller
6
+ * can use the public half as the ShareData's `creationPublicKey` and the
7
+ * private half to mint real signed proofs.
8
+ *
9
+ * Test-only helper — not exported from the package barrel. Real signing
10
+ * keys must come from a key manager in production.
11
+ */
12
+ export declare const generateTestSigningKey: (curve?: EllipticalCurvesSigning) => {
13
+ privateKey: string;
14
+ publicKey: string;
15
+ };
16
+ /**
17
+ * Build a `(purpose, shareData) => IShareDataCryptoProof` callback that
18
+ * signs each requested proof with `privateKey`. On the very first call for
19
+ * a given `shareData`, initializes its crypto chain (matches
20
+ * `buildEllipticalCurvesProofFor` in `@degenerate/shareblock` — the two
21
+ * helpers serve the same role at different layers).
22
+ *
23
+ * Test-only helper. Production signing flows should use
24
+ * `buildEllipticalCurvesProofFor` from `@degenerate/shareblock` which
25
+ * handles the same plumbing through a documented public API.
26
+ */
27
+ export declare const createTestProofFor: (privateKey: string, curve?: EllipticalCurvesSigning) => (purpose: string, shareData: ShareData) => IShareDataCryptoProof;
28
+ /**
29
+ * Build a `(proposedState, functionId, shareData) => IShareDataCryptoProof`
30
+ * callback that mints a *transaction* proposal proof (binds the proposed
31
+ * state + functionId, see `createTransactionProposalProof`). Use this for the
32
+ * runtime mutation path — `ShareData.addTransaction` /
33
+ * `ShareDataManager.applyTransaction` / realtime `propose` — where the proof
34
+ * must authorize one exact state change, unlike the structural proofs minted
35
+ * by {@link createTestProofFor}.
36
+ *
37
+ * Test-only helper. Production flows mint these from a key manager.
38
+ */
39
+ export declare const createTestTransactionProofFor: (privateKey: string, curve?: EllipticalCurvesSigning) => (proposedState: IShareData, functionId: string, shareData: ShareData) => IShareDataCryptoProof;
40
+ /**
41
+ * Convenience wrapper: generate a fresh signing keypair AND return a
42
+ * matching proof signer in one call. Returns both so the test can use the
43
+ * public key when constructing the ShareData under test. `proofFor` mints
44
+ * structural proofs (addFunction/addRule); `transactionProofFor` mints
45
+ * runtime transaction proposal proofs.
46
+ */
47
+ export declare const generateTestSigner: (curve?: EllipticalCurvesSigning) => {
48
+ privateKey: string;
49
+ publicKey: string;
50
+ proofFor: ReturnType<typeof createTestProofFor>;
51
+ transactionProofFor: ReturnType<typeof createTestTransactionProofFor>;
52
+ };
53
+ //# sourceMappingURL=test-proof-signer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-proof-signer.d.ts","sourceRoot":"","sources":["../../../../src/share-data/proofs/testing/test-proof-signer.ts"],"names":[],"mappings":"AAEA,OAAO,EACH,uBAAuB,EACvB,UAAU,EACV,qBAAqB,EACxB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAK7C;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,GAC/B,QAAO,uBAA4D,KACpE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAOzC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,kBAAkB,GAC3B,YAAY,MAAM,EAClB,QAAO,uBAA4D,MAE3D,SAAS,MAAM,EAAE,WAAW,SAAS,KAAG,qBAYnD,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,6BAA6B,GACtC,YAAY,MAAM,EAClB,QAAO,uBAA4D,MAG/D,eAAe,UAAU,EACzB,YAAY,MAAM,EAClB,WAAW,SAAS,KACrB,qBAEN,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,GAC3B,QAAO,uBAA4D,KACpE;IACC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC;IAChD,mBAAmB,EAAE,UAAU,CAAC,OAAO,6BAA6B,CAAC,CAAC;CASzE,CAAC"}
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.generateTestSigner = exports.createTestTransactionProofFor = exports.createTestProofFor = exports.generateTestSigningKey = void 0;
37
+ /* eslint-disable new-cap */
38
+ const elliptic = __importStar(require("elliptic"));
39
+ const generic_1 = require("@degenerate/generic");
40
+ const create_share_data_initial_crypto_1 = require("../../creation/create-share-data-initial-crypto");
41
+ const create_share_data_proposal_proof_1 = require("../creation/create-share-data-proposal-proof");
42
+ const create_transaction_proposal_proof_1 = require("../creation/create-transaction-proposal-proof");
43
+ /**
44
+ * Generate a fresh elliptic keypair suitable for signing ShareData proofs
45
+ * in tests. Returns the hex-encoded private and public keys so the caller
46
+ * can use the public half as the ShareData's `creationPublicKey` and the
47
+ * private half to mint real signed proofs.
48
+ *
49
+ * Test-only helper — not exported from the package barrel. Real signing
50
+ * keys must come from a key manager in production.
51
+ */
52
+ const generateTestSigningKey = (curve = generic_1.EllipticalCurvesSigning.Curve25519) => {
53
+ const ec = new elliptic.ec(curve);
54
+ const keyPair = ec.genKeyPair();
55
+ return {
56
+ privateKey: keyPair.getPrivate('hex'),
57
+ publicKey: keyPair.getPublic('hex'),
58
+ };
59
+ };
60
+ exports.generateTestSigningKey = generateTestSigningKey;
61
+ /**
62
+ * Build a `(purpose, shareData) => IShareDataCryptoProof` callback that
63
+ * signs each requested proof with `privateKey`. On the very first call for
64
+ * a given `shareData`, initializes its crypto chain (matches
65
+ * `buildEllipticalCurvesProofFor` in `@degenerate/shareblock` — the two
66
+ * helpers serve the same role at different layers).
67
+ *
68
+ * Test-only helper. Production signing flows should use
69
+ * `buildEllipticalCurvesProofFor` from `@degenerate/shareblock` which
70
+ * handles the same plumbing through a documented public API.
71
+ */
72
+ const createTestProofFor = (privateKey, curve = generic_1.EllipticalCurvesSigning.Curve25519) => {
73
+ return (purpose, shareData) => {
74
+ if (!shareData.creationHash && shareData.structuralProofs.length === 0) {
75
+ const initialCrypto = (0, create_share_data_initial_crypto_1.createShareDataInitialCrypto)(privateKey, shareData, curve);
76
+ shareData.initializeCrypto(initialCrypto);
77
+ }
78
+ return (0, create_share_data_proposal_proof_1.createShareDataProposalProof)(privateKey, shareData, { purpose }, curve);
79
+ };
80
+ };
81
+ exports.createTestProofFor = createTestProofFor;
82
+ /**
83
+ * Build a `(proposedState, functionId, shareData) => IShareDataCryptoProof`
84
+ * callback that mints a *transaction* proposal proof (binds the proposed
85
+ * state + functionId, see `createTransactionProposalProof`). Use this for the
86
+ * runtime mutation path — `ShareData.addTransaction` /
87
+ * `ShareDataManager.applyTransaction` / realtime `propose` — where the proof
88
+ * must authorize one exact state change, unlike the structural proofs minted
89
+ * by {@link createTestProofFor}.
90
+ *
91
+ * Test-only helper. Production flows mint these from a key manager.
92
+ */
93
+ const createTestTransactionProofFor = (privateKey, curve = generic_1.EllipticalCurvesSigning.Curve25519) => {
94
+ return (proposedState, functionId, shareData) => (0, create_transaction_proposal_proof_1.createTransactionProposalProof)(privateKey, shareData, proposedState, functionId, curve);
95
+ };
96
+ exports.createTestTransactionProofFor = createTestTransactionProofFor;
97
+ /**
98
+ * Convenience wrapper: generate a fresh signing keypair AND return a
99
+ * matching proof signer in one call. Returns both so the test can use the
100
+ * public key when constructing the ShareData under test. `proofFor` mints
101
+ * structural proofs (addFunction/addRule); `transactionProofFor` mints
102
+ * runtime transaction proposal proofs.
103
+ */
104
+ const generateTestSigner = (curve = generic_1.EllipticalCurvesSigning.Curve25519) => {
105
+ const { privateKey, publicKey } = (0, exports.generateTestSigningKey)(curve);
106
+ return {
107
+ privateKey,
108
+ publicKey,
109
+ proofFor: (0, exports.createTestProofFor)(privateKey, curve),
110
+ transactionProofFor: (0, exports.createTestTransactionProofFor)(privateKey, curve),
111
+ };
112
+ };
113
+ exports.generateTestSigner = generateTestSigner;
@@ -0,0 +1,40 @@
1
+ import { EllipticalCurvesSigning, IShareDataCryptoProof } from '@degenerate/generic';
2
+ import { ShareData } from '../../share-data';
3
+ /**
4
+ * Verifies that an `IShareDataCryptoProof` is a faithful attestation of the
5
+ * supplied `shareData`'s structural state. Returns `true` on success; throws
6
+ * {@link ShareDataStructuralProofFailedError} on any failure.
7
+ *
8
+ * The `purpose` to verify under is read from `proof.purpose` — proofs are
9
+ * self-describing so callers don't need to remember which purpose to verify
10
+ * with. This also means an attacker can't shift a proof's purpose to bypass
11
+ * verification (they'd need a fresh signature for the new purpose, which
12
+ * requires the private key).
13
+ *
14
+ * Synchronous on purpose — `addFunction` / `addRule` are synchronous and we
15
+ * don't want to cascade-async every caller in the codebase.
16
+ * `elliptic.ec().keyFromPublic().verify()` is itself synchronous; the
17
+ * project's existing `verifyCryptoSignatureByHash` wrapper is `async` only
18
+ * cosmetically.
19
+ *
20
+ * Verification proceeds in this order:
21
+ * 1. Recompute the canonical share-data string + hash, folding in
22
+ * `proof.purpose`. If the proof's `shareDataHash` doesn't match,
23
+ * reject. (Catches "proof signed against different state.")
24
+ * 2. Recompute the previous hash from the chain. If the proof's
25
+ * `shareDataPreviousHash` doesn't match, reject. (Catches "proof claims
26
+ * a different chain position.")
27
+ * 3. Reconstruct the signed string from the proof's now-validated hash,
28
+ * previousHash, and timestamp, and verify the signature against the
29
+ * proof's `publicKey`. (Catches "signature was tampered or signed with
30
+ * a different key.")
31
+ *
32
+ * The order matters: skipping step 1 or 2 and going straight to signature
33
+ * verification would accept an attacker-crafted proof that claims to attest
34
+ * to one state while the actual share-data has a different state — the
35
+ * signature alone only proves the publicKey holder signed the
36
+ * `(hash, previousHash, timestamp)` triple, not that the hash matches
37
+ * anything real.
38
+ */
39
+ export declare const verifyShareDataProposalProof: (proof: IShareDataCryptoProof, shareData: ShareData, ellipticalCurve?: EllipticalCurvesSigning) => true;
40
+ //# sourceMappingURL=verify-share-data-proposal-proof.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-share-data-proposal-proof.d.ts","sourceRoot":"","sources":["../../../../src/share-data/proofs/verification/verify-share-data-proposal-proof.ts"],"names":[],"mappings":"AACA,OAAO,EAEH,uBAAuB,EACvB,qBAAqB,EAExB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAI7C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,eAAO,MAAM,4BAA4B,GACrC,OAAO,qBAAqB,EAC5B,WAAW,SAAS,EACpB,kBAAiB,uBAA4D,KAC9E,IAoDF,CAAC"}
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.verifyShareDataProposalProof = void 0;
37
+ const elliptic = __importStar(require("elliptic"));
38
+ const generic_1 = require("@degenerate/generic");
39
+ const calculate_share_data_string_1 = require("../../helpers/calculate-share-data-string");
40
+ const get_previous_hash_from_share_data_1 = require("../helpers/get-previous-hash-from-share-data");
41
+ const create_share_data_string_to_sign_1 = require("../helpers/create-share-data-string-to-sign");
42
+ /**
43
+ * Verifies that an `IShareDataCryptoProof` is a faithful attestation of the
44
+ * supplied `shareData`'s structural state. Returns `true` on success; throws
45
+ * {@link ShareDataStructuralProofFailedError} on any failure.
46
+ *
47
+ * The `purpose` to verify under is read from `proof.purpose` — proofs are
48
+ * self-describing so callers don't need to remember which purpose to verify
49
+ * with. This also means an attacker can't shift a proof's purpose to bypass
50
+ * verification (they'd need a fresh signature for the new purpose, which
51
+ * requires the private key).
52
+ *
53
+ * Synchronous on purpose — `addFunction` / `addRule` are synchronous and we
54
+ * don't want to cascade-async every caller in the codebase.
55
+ * `elliptic.ec().keyFromPublic().verify()` is itself synchronous; the
56
+ * project's existing `verifyCryptoSignatureByHash` wrapper is `async` only
57
+ * cosmetically.
58
+ *
59
+ * Verification proceeds in this order:
60
+ * 1. Recompute the canonical share-data string + hash, folding in
61
+ * `proof.purpose`. If the proof's `shareDataHash` doesn't match,
62
+ * reject. (Catches "proof signed against different state.")
63
+ * 2. Recompute the previous hash from the chain. If the proof's
64
+ * `shareDataPreviousHash` doesn't match, reject. (Catches "proof claims
65
+ * a different chain position.")
66
+ * 3. Reconstruct the signed string from the proof's now-validated hash,
67
+ * previousHash, and timestamp, and verify the signature against the
68
+ * proof's `publicKey`. (Catches "signature was tampered or signed with
69
+ * a different key.")
70
+ *
71
+ * The order matters: skipping step 1 or 2 and going straight to signature
72
+ * verification would accept an attacker-crafted proof that claims to attest
73
+ * to one state while the actual share-data has a different state — the
74
+ * signature alone only proves the publicKey holder signed the
75
+ * `(hash, previousHash, timestamp)` triple, not that the hash matches
76
+ * anything real.
77
+ */
78
+ const verifyShareDataProposalProof = (proof, shareData, ellipticalCurve = generic_1.EllipticalCurvesSigning.Curve25519) => {
79
+ // Step 1: hash of current state matches what the proof claims. The
80
+ // purpose comes from the proof itself, so a tampered purpose produces
81
+ // a different hash and gets caught here.
82
+ const shareDataString = (0, calculate_share_data_string_1.calculateShareDataString)(shareData, undefined, { purpose: proof.purpose });
83
+ const recomputedHash = (0, generic_1.calculateHash)(shareDataString);
84
+ if (recomputedHash !== proof.shareDataHash) {
85
+ throw new generic_1.ShareDataStructuralProofFailedError(shareData.id);
86
+ }
87
+ // Step 2: previous-hash matches the chain.
88
+ let recomputedPreviousHash;
89
+ try {
90
+ recomputedPreviousHash = (0, get_previous_hash_from_share_data_1.getPreviousHashFromShareData)(shareData);
91
+ }
92
+ catch {
93
+ // ShareDataPreviousHashNotAvailableError — chain is in a state
94
+ // where no previous hash exists. The proof should not be claiming
95
+ // one either.
96
+ throw new generic_1.ShareDataStructuralProofFailedError(shareData.id);
97
+ }
98
+ if (recomputedPreviousHash !== proof.shareDataPreviousHash) {
99
+ throw new generic_1.ShareDataStructuralProofFailedError(shareData.id);
100
+ }
101
+ // Step 3: signature verifies against the proof's publicKey for the
102
+ // (now-validated) hash + previousHash + timestamp triple.
103
+ const signedString = (0, create_share_data_string_to_sign_1.createShareDataStringToSign)(proof.shareDataHash, proof.shareDataPreviousHash, proof.timestamp);
104
+ let signatureValid;
105
+ try {
106
+ // eslint-disable-next-line new-cap
107
+ const key = new elliptic.ec(ellipticalCurve).keyFromPublic(proof.publicKey, 'hex');
108
+ // Mirror the hash-before-sign step in `createEllipticalCurveSignature`
109
+ // so the verifier sees the same fixed-size 256-bit digest the signer
110
+ // operated on. Without this, elliptic's ECDSA on ed25519 silently
111
+ // truncates inputs longer than ~253 bits and the signature stops
112
+ // binding the trailing bytes (timestamp, tail of previousHash).
113
+ const digest = (0, generic_1.calculateHash)(signedString);
114
+ signatureValid = key.verify(digest, proof.shareDataSignature);
115
+ }
116
+ catch {
117
+ // elliptic throws on malformed signature/key strings rather than
118
+ // returning false — normalize to a single rejection mode.
119
+ throw new generic_1.ShareDataStructuralProofFailedError(shareData.id);
120
+ }
121
+ if (!signatureValid) {
122
+ throw new generic_1.ShareDataStructuralProofFailedError(shareData.id);
123
+ }
124
+ return true;
125
+ };
126
+ exports.verifyShareDataProposalProof = verifyShareDataProposalProof;
@@ -0,0 +1,37 @@
1
+ import { EllipticalCurvesSigning, IShareData, IShareDataCryptoProof } from '@degenerate/generic';
2
+ import { ShareData } from '../../share-data';
3
+ /**
4
+ * Verify a transaction proposal proof against the live `shareData` and the
5
+ * `proposedState` the caller intends to apply. Returns `true`; throws
6
+ * {@link ShareDataTransactionProofFailedError} on any mismatch.
7
+ *
8
+ * This is the runtime counterpart to `verifyShareDataProposalProof`. The
9
+ * critical extra step over the structural verifier is step 2: it recomputes
10
+ * the hash of the *proposed* state the caller is about to apply and folds it
11
+ * into the reconstructed signed string. A proof minted for one proposed state
12
+ * therefore fails for any other — the runtime replay hole is closed here, at
13
+ * the verification boundary, not by trusting the transport.
14
+ *
15
+ * Verification order:
16
+ * 1. Recompute the current-state hash (purpose = `proof.purpose` =
17
+ * functionId); it must equal `proof.shareDataHash`. (Catches "proof
18
+ * signed against a different current state.")
19
+ * 2. Recompute the proposed-state hash from `proposedState`. (Binds the
20
+ * exact state being applied.)
21
+ * 3. Recompute the previous hash from the chain; it must equal
22
+ * `proof.shareDataPreviousHash`. (Catches "proof claims a different
23
+ * chain position.")
24
+ * 4. Reconstruct the transaction signed string from the validated current
25
+ * hash, the recomputed proposed hash, the function id, the previous
26
+ * hash, and the timestamp, and verify the signature against
27
+ * `proof.publicKey`.
28
+ *
29
+ * Because the reconstructed string carries the `tx:` prefix and the proposed
30
+ * hash, a structural proof's signature can never satisfy this check — the two
31
+ * proof kinds are non-interchangeable.
32
+ *
33
+ * Synchronous to match the rest of the proof pipeline; elliptic's `verify`
34
+ * is itself synchronous.
35
+ */
36
+ export declare const verifyTransactionProposalProof: (proof: IShareDataCryptoProof, shareData: ShareData, proposedState: IShareData, ellipticalCurve?: EllipticalCurvesSigning) => true;
37
+ //# sourceMappingURL=verify-transaction-proposal-proof.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-transaction-proposal-proof.d.ts","sourceRoot":"","sources":["../../../../src/share-data/proofs/verification/verify-transaction-proposal-proof.ts"],"names":[],"mappings":"AACA,OAAO,EAEH,uBAAuB,EACvB,UAAU,EACV,qBAAqB,EAExB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAK7C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,eAAO,MAAM,8BAA8B,GACvC,OAAO,qBAAqB,EAC5B,WAAW,SAAS,EACpB,eAAe,UAAU,EACzB,kBAAiB,uBAA4D,KAC9E,IAwDF,CAAC"}
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.verifyTransactionProposalProof = void 0;
37
+ const elliptic = __importStar(require("elliptic"));
38
+ const generic_1 = require("@degenerate/generic");
39
+ const calculate_share_data_string_1 = require("../../helpers/calculate-share-data-string");
40
+ const get_previous_hash_from_share_data_1 = require("../helpers/get-previous-hash-from-share-data");
41
+ const create_transaction_proposal_string_to_sign_1 = require("../helpers/create-transaction-proposal-string-to-sign");
42
+ const hash_proposed_state_1 = require("../helpers/hash-proposed-state");
43
+ /**
44
+ * Verify a transaction proposal proof against the live `shareData` and the
45
+ * `proposedState` the caller intends to apply. Returns `true`; throws
46
+ * {@link ShareDataTransactionProofFailedError} on any mismatch.
47
+ *
48
+ * This is the runtime counterpart to `verifyShareDataProposalProof`. The
49
+ * critical extra step over the structural verifier is step 2: it recomputes
50
+ * the hash of the *proposed* state the caller is about to apply and folds it
51
+ * into the reconstructed signed string. A proof minted for one proposed state
52
+ * therefore fails for any other — the runtime replay hole is closed here, at
53
+ * the verification boundary, not by trusting the transport.
54
+ *
55
+ * Verification order:
56
+ * 1. Recompute the current-state hash (purpose = `proof.purpose` =
57
+ * functionId); it must equal `proof.shareDataHash`. (Catches "proof
58
+ * signed against a different current state.")
59
+ * 2. Recompute the proposed-state hash from `proposedState`. (Binds the
60
+ * exact state being applied.)
61
+ * 3. Recompute the previous hash from the chain; it must equal
62
+ * `proof.shareDataPreviousHash`. (Catches "proof claims a different
63
+ * chain position.")
64
+ * 4. Reconstruct the transaction signed string from the validated current
65
+ * hash, the recomputed proposed hash, the function id, the previous
66
+ * hash, and the timestamp, and verify the signature against
67
+ * `proof.publicKey`.
68
+ *
69
+ * Because the reconstructed string carries the `tx:` prefix and the proposed
70
+ * hash, a structural proof's signature can never satisfy this check — the two
71
+ * proof kinds are non-interchangeable.
72
+ *
73
+ * Synchronous to match the rest of the proof pipeline; elliptic's `verify`
74
+ * is itself synchronous.
75
+ */
76
+ const verifyTransactionProposalProof = (proof, shareData, proposedState, ellipticalCurve = generic_1.EllipticalCurvesSigning.Curve25519) => {
77
+ // Step 1: current-state hash matches what the proof claims. The purpose
78
+ // (functionId) comes from the proof itself, so a tampered purpose
79
+ // produces a different hash and is caught here.
80
+ const currentString = (0, calculate_share_data_string_1.calculateShareDataString)(shareData, undefined, { purpose: proof.purpose });
81
+ const recomputedCurrentHash = (0, generic_1.calculateHash)(currentString);
82
+ if (recomputedCurrentHash !== proof.shareDataHash) {
83
+ throw new generic_1.ShareDataTransactionProofFailedError(shareData.id);
84
+ }
85
+ // Step 2: hash the proposed state being applied so it can be folded into
86
+ // the reconstructed signature payload.
87
+ const proposedStateHash = (0, hash_proposed_state_1.hashProposedState)(proposedState);
88
+ // Step 3: previous-hash matches the chain.
89
+ let recomputedPreviousHash;
90
+ try {
91
+ recomputedPreviousHash = (0, get_previous_hash_from_share_data_1.getPreviousHashFromShareData)(shareData);
92
+ }
93
+ catch {
94
+ // ShareDataPreviousHashNotAvailableError — chain has no previous hash;
95
+ // the proof should not be claiming one either.
96
+ throw new generic_1.ShareDataTransactionProofFailedError(shareData.id);
97
+ }
98
+ if (recomputedPreviousHash !== proof.shareDataPreviousHash) {
99
+ throw new generic_1.ShareDataTransactionProofFailedError(shareData.id);
100
+ }
101
+ // Step 4: signature verifies over the full transaction payload (which
102
+ // includes the proposed-state hash and the `tx:` discriminator).
103
+ const signedString = (0, create_transaction_proposal_string_to_sign_1.createTransactionProposalStringToSign)(proof.shareDataHash, proposedStateHash, proof.purpose, proof.shareDataPreviousHash, proof.timestamp);
104
+ let signatureValid;
105
+ try {
106
+ // eslint-disable-next-line new-cap
107
+ const key = new elliptic.ec(ellipticalCurve).keyFromPublic(proof.publicKey, 'hex');
108
+ // Mirror the hash-before-sign step in `createEllipticalCurveSignature`
109
+ // so the verifier operates on the same fixed-size digest the signer
110
+ // did. Without this, elliptic's ECDSA on ed25519 silently truncates
111
+ // long inputs and stops binding the trailing bytes.
112
+ const digest = (0, generic_1.calculateHash)(signedString);
113
+ signatureValid = key.verify(digest, proof.shareDataSignature);
114
+ }
115
+ catch {
116
+ // elliptic throws on malformed signature/key strings rather than
117
+ // returning false — normalize to a single rejection mode.
118
+ throw new generic_1.ShareDataTransactionProofFailedError(shareData.id);
119
+ }
120
+ if (!signatureValid) {
121
+ throw new generic_1.ShareDataTransactionProofFailedError(shareData.id);
122
+ }
123
+ return true;
124
+ };
125
+ exports.verifyTransactionProposalProof = verifyTransactionProposalProof;