@mcsherrylabs/evolver-client 0.8.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 (59) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +42 -0
  3. package/dist/api.d.ts +172 -0
  4. package/dist/api.d.ts.map +1 -0
  5. package/dist/api.js +508 -0
  6. package/dist/api.js.map +1 -0
  7. package/dist/bodies.d.ts +86 -0
  8. package/dist/bodies.d.ts.map +1 -0
  9. package/dist/bodies.js +145 -0
  10. package/dist/bodies.js.map +1 -0
  11. package/dist/crypto/auth.d.ts +25 -0
  12. package/dist/crypto/auth.d.ts.map +1 -0
  13. package/dist/crypto/auth.js +71 -0
  14. package/dist/crypto/auth.js.map +1 -0
  15. package/dist/crypto/canonical.d.ts +21 -0
  16. package/dist/crypto/canonical.d.ts.map +1 -0
  17. package/dist/crypto/canonical.js +68 -0
  18. package/dist/crypto/canonical.js.map +1 -0
  19. package/dist/crypto/group.d.ts +29 -0
  20. package/dist/crypto/group.d.ts.map +1 -0
  21. package/dist/crypto/group.js +107 -0
  22. package/dist/crypto/group.js.map +1 -0
  23. package/dist/crypto/hash.d.ts +7 -0
  24. package/dist/crypto/hash.d.ts.map +1 -0
  25. package/dist/crypto/hash.js +34 -0
  26. package/dist/crypto/hash.js.map +1 -0
  27. package/dist/crypto/stream.d.ts +27 -0
  28. package/dist/crypto/stream.d.ts.map +1 -0
  29. package/dist/crypto/stream.js +186 -0
  30. package/dist/crypto/stream.js.map +1 -0
  31. package/dist/envelope.d.ts +28 -0
  32. package/dist/envelope.d.ts.map +1 -0
  33. package/dist/envelope.js +68 -0
  34. package/dist/envelope.js.map +1 -0
  35. package/dist/generated/codecs.d.ts +145 -0
  36. package/dist/generated/codecs.d.ts.map +1 -0
  37. package/dist/generated/codecs.js +240 -0
  38. package/dist/generated/codecs.js.map +1 -0
  39. package/dist/identity.d.ts +17 -0
  40. package/dist/identity.d.ts.map +1 -0
  41. package/dist/identity.js +52 -0
  42. package/dist/identity.js.map +1 -0
  43. package/dist/index.d.ts +13 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +17 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/signers.d.ts +52 -0
  48. package/dist/signers.d.ts.map +1 -0
  49. package/dist/signers.js +75 -0
  50. package/dist/signers.js.map +1 -0
  51. package/dist/types.d.ts +103 -0
  52. package/dist/types.d.ts.map +1 -0
  53. package/dist/types.js +44 -0
  54. package/dist/types.js.map +1 -0
  55. package/dist/wire.d.ts +13 -0
  56. package/dist/wire.d.ts.map +1 -0
  57. package/dist/wire.js +71 -0
  58. package/dist/wire.js.map +1 -0
  59. package/package.json +41 -0
package/dist/bodies.js ADDED
@@ -0,0 +1,145 @@
1
+ // Tx-body builders for the core ledgers + channel messages.
2
+ //
3
+ // Each builder returns the serialized OUTER oneof message (the tx_body bytes)
4
+ // ready to pass to buildSignedTx. Field numbers per
5
+ // src/main/protobuf/evolver/ledger/{identity,group,owners}.proto.
6
+ //
7
+ // A CHANNEL message tx_body is the raw application payload bytes — the ledger
8
+ // has no core handler, the body is opaque.
9
+ import { fString, fBytes, fMessage, fVarint, concat } from "./wire.js";
10
+ export const LEDGER = {
11
+ identity: "ce.evolver.ledger.identity",
12
+ groups: "ce.evolver.ledger.groups",
13
+ owners: "ce.evolver.ledger.owners",
14
+ };
15
+ // ── Identity ledger ──────────────────────────────────────────────────────────
16
+ // TxBody.body oneof: 1 create_identity | 3 add_key | 4 replace_key | 5 delete_key
17
+ // KeyEntryWithPoP: 1 key_type | 2 public_key | 3 pop_signature | 4 key_label
18
+ function encodeKeyEntry(k, withPoP) {
19
+ return [
20
+ ...fString(1, k.keyType),
21
+ ...fBytes(2, k.publicKey),
22
+ ...(withPoP && k.popSig ? fBytes(3, k.popSig) : []),
23
+ ...fString(4, k.keyLabel),
24
+ ];
25
+ }
26
+ /**
27
+ * Inner CreateIdentityTxBody — the PROTO body that goes on the wire.
28
+ *
29
+ * ⚠️ 148: this is NO LONGER the PoP preimage. Proof of possession uses the canonical field
30
+ * encoding (`popCreateIdentity` in ./generated/codecs), not a hash of these proto bytes. The two
31
+ * were the same function before, which is why `withPoP` existed; the wire body still needs proto,
32
+ * so the function stays — it just no longer serves double duty.
33
+ */
34
+ export function createIdentityInner(nodeId, initialCredit, keys, withPoP) {
35
+ // CreateIdentityTxBody: 1 node_id | 2 initial_credit | 3 keys (repeated)
36
+ return concat(fString(1, nodeId), fVarint(2, initialCredit), ...keys.map((k) => fMessage(3, concat(encodeKeyEntry(k, withPoP)))));
37
+ }
38
+ /** Wrap a CreateIdentityTxBody as the tx_body (TxBody.create_identity = 1). */
39
+ export function createIdentityBody(inner) {
40
+ return concat(fMessage(1, inner));
41
+ }
42
+ /** Inner AddKeyTxBody: 1 public_key | 2 key_type | 3 key_label | 5 pop_signature (omit when empty).
43
+ *
44
+ * ⚠️ This is NOT the PoP preimage and has not been since 148 — that is `popAddKey` in
45
+ * ./generated/codecs. This comment claimed otherwise for two features, which is the exact reason
46
+ * a recipe is now stated once, as data, instead of in prose beside each function that touches it. */
47
+ export function addKeyInner(args) {
48
+ return concat(fBytes(1, args.publicKey), fString(2, args.keyType), fString(3, args.keyLabel), args.popSignature.length > 0 ? fBytes(5, args.popSignature) : []);
49
+ }
50
+ export function addKeyBody(args) {
51
+ return concat(fMessage(3, addKeyInner(args))); // TxBody.add_key = 3
52
+ }
53
+ /** Inner ReplaceKeyTxBody: 1 public_key | 2 key_type | 3 key_label | 5 pop_signature (omit when empty).
54
+ * Mirrors AddKeyTxBody exactly on the wire. The PoP preimage is `popReplaceKey` in
55
+ * ./generated/codecs — a DIFFERENT digest from AddKey's despite the identical layout, because the
56
+ * two descriptions carry different tags. */
57
+ export function replaceKeyInner(args) {
58
+ return concat(fBytes(1, args.publicKey), fString(2, args.keyType), fString(3, args.keyLabel), args.popSignature.length > 0 ? fBytes(5, args.popSignature) : []);
59
+ }
60
+ export function replaceKeyBody(args) {
61
+ return concat(fMessage(4, replaceKeyInner(args))); // TxBody.replace_key = 4
62
+ }
63
+ export function deleteKeyBody(args) {
64
+ // DeleteKeyTxBody: 1 key_type | 2 key_label
65
+ const inner = concat(fString(1, args.keyType), fString(2, args.keyLabel));
66
+ return concat(fMessage(5, inner)); // TxBody.delete_key = 5
67
+ }
68
+ /**
69
+ * Credit transfer (154): move credit from the signing identity to 1..20 recipients.
70
+ *
71
+ * TransferTxBody{ 1 transfers (repeated) }, TransferEntry{ 1 recipient, 2 amount },
72
+ * TxBody.transfer = 6.
73
+ *
74
+ * The entries are encoded IN THE ORDER GIVEN and nothing here sorts, merges or
75
+ * deduplicates them — the order is part of the meaning, because it decides which
76
+ * transfers survive if the sender runs short at apply time. The node's own rules
77
+ * (1..20 entries, amounts >= 1, distinct recipients, none of them the sender,
78
+ * every recipient an existing identity) are enforced there and refused at submit;
79
+ * this function encodes what it is given.
80
+ */
81
+ export function transferBody(entries) {
82
+ const inner = concat(...entries.map((e) => fMessage(1, concat(fString(1, e.recipient), fVarint(2, e.amount)))));
83
+ return concat(fMessage(6, inner)); // TxBody.transfer = 6
84
+ }
85
+ // ── Groups ledger ────────────────────────────────────────────────────────────
86
+ // GroupTxBody.tx oneof: 1 create_group | 2 add_member | 3 remove_member
87
+ export function createGroupBody(name) {
88
+ return concat(fMessage(1, concat(fString(1, name)))); // CreateGroupTxBody{ name = 1 }
89
+ }
90
+ export function addMemberBody(groupName, memberNodeId) {
91
+ return concat(fMessage(2, concat(fString(1, groupName), fString(2, memberNodeId))));
92
+ }
93
+ export function removeMemberBody(groupName, memberNodeId) {
94
+ return concat(fMessage(3, concat(fString(1, groupName), fString(2, memberNodeId))));
95
+ }
96
+ // ── Owners ledger ────────────────────────────────────────────────────────────
97
+ // OwnersTxBody.tx oneof: 1 claim | 2 remove
98
+ // ClaimTxBody: 1 ledger_id | 3 group_owner | 4 da_group (string) | 5 da_threshold_m (uint32)
99
+ // (#7 removed field 2 co_owners — multi-owner ledgers are group-owned only.
100
+ // 097 retired the old `bool da_managed` field 4 — DA is now a named DA group +
101
+ // threshold m; absence of a da_group ⇒ not DA-managed.)
102
+ export function claimBody(args) {
103
+ const parts = [...fString(1, args.ledgerId)];
104
+ if (args.groupOwner)
105
+ parts.push(...fString(3, args.groupOwner));
106
+ if (args.daGroup)
107
+ parts.push(...fString(4, args.daGroup));
108
+ if (args.daThresholdM)
109
+ parts.push(...fVarint(5, args.daThresholdM)); // proto3: omit 0 (default)
110
+ if (args.tollAmount && BigInt(args.tollAmount) !== 0n)
111
+ parts.push(...fVarint(6, args.tollAmount));
112
+ if (args.tollRecipient)
113
+ parts.push(...fString(7, args.tollRecipient));
114
+ return concat(fMessage(1, concat(parts))); // OwnersTxBody.claim = 1
115
+ }
116
+ export function removeOwnerBody(ledgerId) {
117
+ return concat(fMessage(2, concat(fString(1, ledgerId)))); // OwnersTxBody.remove = 2
118
+ }
119
+ // 153 — UpdateChannelTollTxBody: 1 ledger_id | 2 toll_amount (int64) | 3 toll_recipient.
120
+ // OwnersTxBody.update_channel_toll = 5. toll_amount 0 / omitted ⇒ REMOVE the toll.
121
+ export function updateChannelTollBody(args) {
122
+ const parts = [...fString(1, args.ledgerId)];
123
+ if (args.tollAmount && BigInt(args.tollAmount) !== 0n)
124
+ parts.push(...fVarint(2, args.tollAmount));
125
+ if (args.tollRecipient)
126
+ parts.push(...fString(3, args.tollRecipient));
127
+ return concat(fMessage(5, concat(parts))); // OwnersTxBody.update_channel_toll = 5
128
+ }
129
+ // ── Channel (ledger_id = the channel id) ─────────────────────────────────────
130
+ // The tx_body IS the raw payload bytes — opaque, no wrapper.
131
+ export function channelBody(payload) {
132
+ return payload;
133
+ }
134
+ // ── proof-of-possession digests ──────────────────────────────────────────────
135
+ //
136
+ // ⚠️ 149 — THEY ARE NOT WRITTEN HERE ANY MORE. `popCreateIdentityDigest` / `popAddKeyDigest` /
137
+ // `popReplaceKeyDigest` were hand-composed twins of `PoPSignable.scala`, and this file is where
138
+ // the drift that reached regression stage 62 lived: 148 moved the Scala half to the canonical
139
+ // encoding and this half stayed on hand-rolled proto3, with `npm test` green throughout.
140
+ //
141
+ // Import `popCreateIdentity` / `popAddKey` / `popReplaceKey` from ./generated/codecs instead —
142
+ // emitted from the node's own descriptions, so there is no second half to forget. The three tags
143
+ // (AddKey and ReplaceKey have identical field layouts, so one shared tag made a proof gathered for
144
+ // an AddKey valid for a ReplaceKey) are now a property of the descriptions, not of this file.
145
+ //# sourceMappingURL=bodies.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bodies.js","sourceRoot":"","sources":["../src/bodies.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ export declare const BLS_DST = "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_";
2
+ export interface BlsKeypair {
3
+ priv: Uint8Array;
4
+ pub: Uint8Array;
5
+ }
6
+ export interface EdKeypair {
7
+ priv: Uint8Array;
8
+ pub: Uint8Array;
9
+ }
10
+ export declare function genBls(): BlsKeypair;
11
+ /** Sign raw message bytes (hash-to-curve absorbs them) → 96-byte compressed G2. */
12
+ export declare function blsSign(msg: Uint8Array, priv: Uint8Array): Uint8Array;
13
+ export declare function genEd(): EdKeypair;
14
+ export declare function edSign(msg: Uint8Array, priv: Uint8Array): Uint8Array;
15
+ /** Verify an Ed25519 signature over `msg` against a raw 32-byte public key.
16
+ * 138: used by the remote-key enrollment to re-verify the phone-produced
17
+ * AddKey PoP before the outer tx is signed (never sign blind). */
18
+ export declare function edVerify(msg: Uint8Array, sig: Uint8Array, pub32: Uint8Array): boolean;
19
+ export declare function edPubToSpki(raw32: Uint8Array): Uint8Array;
20
+ /** Raw 32-byte Ed25519 pubkey from either a raw key or an X.509 SPKI-wrapped one
21
+ * (the on-chain `node_keys` form). The key is always the last 32 bytes. */
22
+ export declare function edSpkiToRaw(spkiOrRaw: Uint8Array): Uint8Array;
23
+ /** X25519 public key from an Ed25519 public key (raw 32 or SPKI). */
24
+ export declare function edToX25519Pub(edPub: Uint8Array): Uint8Array;
25
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/crypto/auth.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,OAAO,gDAAgD,CAAC;AAErE,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,UAAU,CAAC;IACjB,GAAG,EAAE,UAAU,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,UAAU,CAAC;IACjB,GAAG,EAAE,UAAU,CAAC;CACjB;AAID,wBAAgB,MAAM,IAAI,UAAU,CAGnC;AAED,mFAAmF;AACnF,wBAAgB,OAAO,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,GAAG,UAAU,CAIrE;AAID,wBAAgB,KAAK,IAAI,SAAS,CAGjC;AAED,wBAAgB,MAAM,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,GAAG,UAAU,CAEpE;AAED;;mEAEmE;AACnE,wBAAgB,QAAQ,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAMrF;AAQD,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAGzD;AAED;4EAC4E;AAC5E,wBAAgB,WAAW,CAAC,SAAS,EAAE,UAAU,GAAG,UAAU,CAE7D;AAcD,qEAAqE;AACrE,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAE3D"}
@@ -0,0 +1,71 @@
1
+ // On-chain AUTH keys: BLS12-381-G1 (G2 signatures, G1 public keys) + Ed25519.
2
+ // These authenticate WHO sent a tx. Distinct from the app-level ENCRYPTION keys
3
+ // in ./group.ts. Isomorphic (@noble/curves is pure JS).
4
+ //
5
+ // The BLS DST must be byte-identical to BLSOperations.DST on the server; it is
6
+ // shared by both proof-of-possession and ledger-auth (TxAuth) signatures.
7
+ import { bls12_381 } from "@noble/curves/bls12-381";
8
+ import { ed25519, edwardsToMontgomeryPub } from "@noble/curves/ed25519";
9
+ import { concatBytes } from "./hash.js";
10
+ export const BLS_DST = "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_";
11
+ // ── BLS12-381 ──────────────────────────────────────────────────────────────
12
+ export function genBls() {
13
+ const priv = bls12_381.utils.randomPrivateKey();
14
+ return { priv, pub: bls12_381.getPublicKey(priv) };
15
+ }
16
+ /** Sign raw message bytes (hash-to-curve absorbs them) → 96-byte compressed G2. */
17
+ export function blsSign(msg, priv) {
18
+ const point = bls12_381.longSignatures.hash(msg, BLS_DST);
19
+ const sig = bls12_381.longSignatures.sign(point, priv);
20
+ return bls12_381.longSignatures.Signature.toBytes(sig);
21
+ }
22
+ // ── Ed25519 ────────────────────────────────────────────────────────────────
23
+ export function genEd() {
24
+ const priv = ed25519.utils.randomPrivateKey();
25
+ return { priv, pub: ed25519.getPublicKey(priv) };
26
+ }
27
+ export function edSign(msg, priv) {
28
+ return ed25519.sign(msg, priv);
29
+ }
30
+ /** Verify an Ed25519 signature over `msg` against a raw 32-byte public key.
31
+ * 138: used by the remote-key enrollment to re-verify the phone-produced
32
+ * AddKey PoP before the outer tx is signed (never sign blind). */
33
+ export function edVerify(msg, sig, pub32) {
34
+ try {
35
+ return ed25519.verify(sig, msg, pub32);
36
+ }
37
+ catch {
38
+ return false;
39
+ }
40
+ }
41
+ // Wrap a raw 32-byte Ed25519 public key as X.509 SubjectPublicKeyInfo — the wire
42
+ // form expected in KeyEntryWithPoP.public_key for Ed25519.
43
+ const ED_SPKI_PREFIX = Uint8Array.from([
44
+ 0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70, 0x03, 0x21, 0x00,
45
+ ]);
46
+ export function edPubToSpki(raw32) {
47
+ if (raw32.length !== 32)
48
+ throw new Error("expected 32-byte ed25519 public key");
49
+ return concatBytes(ED_SPKI_PREFIX, raw32);
50
+ }
51
+ /** Raw 32-byte Ed25519 pubkey from either a raw key or an X.509 SPKI-wrapped one
52
+ * (the on-chain `node_keys` form). The key is always the last 32 bytes. */
53
+ export function edSpkiToRaw(spkiOrRaw) {
54
+ return spkiOrRaw.length === 32 ? spkiOrRaw : spkiOrRaw.subarray(spkiOrRaw.length - 32);
55
+ }
56
+ // ── Ed25519 → X25519 (derive the key-agreement key from the identity key) ──────
57
+ // Lets a member's existing on-chain Ed25519 identity key double as the ECDH key for
58
+ // group-key wrapping — no separate X25519 key to generate, store, or publish.
59
+ //
60
+ // Only the PUBLIC derivation lives here, because public material is meant to travel:
61
+ // wrapping a group key to a member needs nothing but their on-chain key. The PRIVATE
62
+ // derivation is deliberately NOT here and NOT exported anywhere — it is a module-private
63
+ // helper of ./group.ts, reachable only by constructing a GroupKeyUnwrapper. Signing has
64
+ // worked that way since the Signer trait; decryption now does too, so no raw scalar
65
+ // crosses a module boundary. (See issue #53 for the remaining question: whether a
66
+ // phone-held identity key should be able to decrypt at all.)
67
+ /** X25519 public key from an Ed25519 public key (raw 32 or SPKI). */
68
+ export function edToX25519Pub(edPub) {
69
+ return edwardsToMontgomeryPub(edSpkiToRaw(edPub));
70
+ }
71
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/crypto/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /** 4-byte big-endian length prefix, then the bytes. */
2
+ export declare function lengthPrefixed(field: Uint8Array): Uint8Array;
3
+ /** A UTF-8 string as a length-prefixed field. Never normalised (rule 8). */
4
+ export declare function lpString(s: string): Uint8Array;
5
+ /** The purpose tag: length-prefixed, written first. */
6
+ export declare function dst(tag: string): Uint8Array;
7
+ /** 4-byte big-endian integer. */
8
+ export declare function int32BE(v: number | bigint): Uint8Array;
9
+ /**
10
+ * 8-byte big-endian integer.
11
+ *
12
+ * ⚠️ BIG-endian. The pre-148 transaction digest used LITTLE-endian for `ttl_round` — the codebase's
13
+ * lone outlier — and a byte-swapped value produces a digest wrong in only 8 bytes, which fails at
14
+ * the far end with no clue why. The vectors carry a non-palindromic value precisely to catch it.
15
+ */
16
+ export declare function int64BE(v: number | bigint): Uint8Array;
17
+ /** The element count of a variable-length list (rule 5). */
18
+ export declare function count(n: number): Uint8Array;
19
+ /** Concatenate encoded parts. */
20
+ export declare function encoded(...parts: Uint8Array[]): Uint8Array;
21
+ //# sourceMappingURL=canonical.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonical.d.ts","sourceRoot":"","sources":["../../src/crypto/canonical.ts"],"names":[],"mappings":"AAqBA,uDAAuD;AACvD,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAK5D;AAED,4EAA4E;AAC5E,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,UAAU,CAE9C;AAED,uDAAuD;AACvD,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAE3C;AAED,iCAAiC;AACjC,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,UAAU,CAItD;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,UAAU,CAItD;AAED,4DAA4D;AAC5D,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,UAAU,CAE3C;AAED,iCAAiC;AACjC,wBAAgB,OAAO,CAAC,GAAG,KAAK,EAAE,UAAU,EAAE,GAAG,UAAU,CAS1D"}
@@ -0,0 +1,68 @@
1
+ // 148 — the canonical field encoding, TypeScript side.
2
+ //
3
+ // The node's `Hashing.Builder` / `CanonicalBytes` apply these same rules. Both languages are
4
+ // pinned to the SAME golden vectors under `src/test/resources/vectors/`, so neither can be
5
+ // updated alone — which matters here because these two implementations have drifted before, and
6
+ // the only symptom was signatures that silently failed to verify.
7
+ //
8
+ // Rules: specs/148-canonical-signing-encoding/contracts/encoding-contract.md
9
+ // 1. purpose tag first, length-prefixed
10
+ // 2. every variable-length field length-prefixed (4-byte BIG-endian length)
11
+ // 3. fixed-width fields bare
12
+ // 4. every field always written — empty is length 0, never omitted
13
+ // 5. lists carry a count
14
+ // 7. integers fixed-width BIG-endian at a declared width
15
+ //
16
+ // ⚠️ Integers are `bigint`, never `number` (Constitution VIII). `Number()`/`parseInt` on any of
17
+ // these values is prohibited: epoch millis and balances exceed 2^53, and a float round-trip is
18
+ // silent — correct in every test case except the one that matters.
19
+ const enc = new TextEncoder();
20
+ /** 4-byte big-endian length prefix, then the bytes. */
21
+ export function lengthPrefixed(field) {
22
+ const out = new Uint8Array(4 + field.length);
23
+ new DataView(out.buffer).setUint32(0, field.length, false); // false = BIG-endian
24
+ out.set(field, 4);
25
+ return out;
26
+ }
27
+ /** A UTF-8 string as a length-prefixed field. Never normalised (rule 8). */
28
+ export function lpString(s) {
29
+ return lengthPrefixed(enc.encode(s));
30
+ }
31
+ /** The purpose tag: length-prefixed, written first. */
32
+ export function dst(tag) {
33
+ return lpString(tag);
34
+ }
35
+ /** 4-byte big-endian integer. */
36
+ export function int32BE(v) {
37
+ const out = new Uint8Array(4);
38
+ new DataView(out.buffer).setInt32(0, Number(v), false);
39
+ return out;
40
+ }
41
+ /**
42
+ * 8-byte big-endian integer.
43
+ *
44
+ * ⚠️ BIG-endian. The pre-148 transaction digest used LITTLE-endian for `ttl_round` — the codebase's
45
+ * lone outlier — and a byte-swapped value produces a digest wrong in only 8 bytes, which fails at
46
+ * the far end with no clue why. The vectors carry a non-palindromic value precisely to catch it.
47
+ */
48
+ export function int64BE(v) {
49
+ const out = new Uint8Array(8);
50
+ new DataView(out.buffer).setBigInt64(0, BigInt(v), false);
51
+ return out;
52
+ }
53
+ /** The element count of a variable-length list (rule 5). */
54
+ export function count(n) {
55
+ return int32BE(n);
56
+ }
57
+ /** Concatenate encoded parts. */
58
+ export function encoded(...parts) {
59
+ const total = parts.reduce((n, p) => n + p.length, 0);
60
+ const out = new Uint8Array(total);
61
+ let off = 0;
62
+ for (const p of parts) {
63
+ out.set(p, off);
64
+ off += p.length;
65
+ }
66
+ return out;
67
+ }
68
+ //# sourceMappingURL=canonical.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonical.js","sourceRoot":"","sources":["../../src/crypto/canonical.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,EAAE;AACF,6FAA6F;AAC7F,2FAA2F;AAC3F,gGAAgG;AAChG,kEAAkE;AAClE,EAAE;AACF,6EAA6E;AAC7E,0CAA0C;AAC1C,8EAA8E;AAC9E,+BAA+B;AAC/B,qEAAqE;AACrE,2BAA2B;AAC3B,2DAA2D;AAC3D,EAAE;AACF,gGAAgG;AAChG,+FAA+F;AAC/F,mEAAmE;AAEnE,MAAM,GAAG,GAAG,IAAI,WAAW,EAAE,CAAC;AAE9B,uDAAuD;AACvD,MAAM,UAAU,cAAc,CAAC,KAAiB;IAC9C,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7C,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,qBAAqB;IACjF,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAClB,OAAO,GAAG,CAAC;AACb,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,QAAQ,CAAC,CAAS;IAChC,OAAO,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AACvC,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,GAAG,CAAC,GAAW;IAC7B,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC;AACvB,CAAC;AAED,iCAAiC;AACjC,MAAM,UAAU,OAAO,CAAC,CAAkB;IACxC,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;IAC9B,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACvD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,OAAO,CAAC,CAAkB;IACxC,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;IAC9B,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAC1D,OAAO,GAAG,CAAC;AACb,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,KAAK,CAAC,CAAS;IAC7B,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC;AAED,iCAAiC;AACjC,MAAM,UAAU,OAAO,CAAC,GAAG,KAAmB;IAC5C,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACtD,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC;IAClC,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAChB,GAAG,IAAI,CAAC,CAAC,MAAM,CAAC;IAClB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,29 @@
1
+ import type { GroupKeyUnwrapper, WrappedKey } from "../types.js";
2
+ export interface X25519Keypair {
3
+ priv: Uint8Array;
4
+ pub: Uint8Array;
5
+ }
6
+ export declare function genX25519(): X25519Keypair;
7
+ export declare function randomGroupKey(): Uint8Array;
8
+ /** Wrap the group key to a member's X25519 public key (ephemeral-sender ECIES). */
9
+ export declare function wrapGroupKey(groupKey: Uint8Array, recipientPub: Uint8Array): Promise<WrappedKey>;
10
+ /**
11
+ * An unwrapper over a NATIVE X25519 private key — the shape a separately registered
12
+ * encryption key would use (issue #53). The scalar lives only in this closure.
13
+ */
14
+ export declare function x25519GroupKeyUnwrapper(priv: Uint8Array): GroupKeyUnwrapper;
15
+ /**
16
+ * An unwrapper over an Ed25519 IDENTITY key: derives the key-agreement scalar once, at
17
+ * construction, and keeps it in this closure. This is what every member uses today —
18
+ * their on-chain Ed25519 key IS their encryption key.
19
+ *
20
+ * Pass the identity's 32-byte Ed25519 seed. Nothing else in the SDK or any application
21
+ * can obtain the derived scalar, which is the point: decryption is now reached through a
22
+ * handle, exactly as signing is reached through a Signer.
23
+ */
24
+ export declare function edGroupKeyUnwrapper(edPriv: Uint8Array): GroupKeyUnwrapper;
25
+ /** Encrypt a message under the group key (this is the opaque channel tx_body). */
26
+ export declare function encryptMessage(groupKey: Uint8Array, plaintext: Uint8Array): Promise<Uint8Array>;
27
+ /** Decrypt a message with the group key. */
28
+ export declare function decryptMessage(groupKey: Uint8Array, blob: Uint8Array): Promise<Uint8Array>;
29
+ //# sourceMappingURL=group.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"group.d.ts","sourceRoot":"","sources":["../../src/crypto/group.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEjE,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,UAAU,CAAC;IACjB,GAAG,EAAE,UAAU,CAAC;CACjB;AAED,wBAAgB,SAAS,IAAI,aAAa,CAGzC;AAED,wBAAgB,cAAc,IAAI,UAAU,CAI3C;AAuBD,mFAAmF;AACnF,wBAAsB,YAAY,CAAC,QAAQ,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAKtG;AAmBD;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,UAAU,GAAG,iBAAiB,CAG3E;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,UAAU,GAAG,iBAAiB,CAGzE;AAED,kFAAkF;AAClF,wBAAgB,cAAc,CAAC,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAE/F;AAED,4CAA4C;AAC5C,wBAAgB,cAAc,CAAC,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAE1F"}
@@ -0,0 +1,107 @@
1
+ // App-level "encrypted to the group" crypto. The chain sees only opaque ciphertext.
2
+ // X25519 keys here decide WHO CAN READ a message; the on-chain auth keys decide WHO SENT
3
+ // it. They are not independent: a member's key-agreement key is DERIVED from their
4
+ // Ed25519 identity key (edwardsToMontgomery), so there is no separate encryption key to
5
+ // generate, publish or look up — the on-chain identity key is the one source of truth for
6
+ // both. (This comment used to claim the two were SEPARATE. They stopped being separate
7
+ // when the derivation landed, and the consequences are issue #53: the same key both signs
8
+ // and agrees, and a phone-held identity key cannot decrypt because a remote signer offers
9
+ // signing but no ECDH.)
10
+ //
11
+ // The private half NEVER leaves this module. Callers hold a GroupKeyUnwrapper, whose
12
+ // implementation closes over the scalar — the same discipline the Signer trait applies to
13
+ // signing. That is also the seam for later: remote (phone-side) key agreement, or a
14
+ // separately registered X25519 key, becomes one more implementation of this interface
15
+ // rather than a change at every call site.
16
+ //
17
+ // Scheme (wire-compatible with examples/group-chat's original node:crypto impl):
18
+ // - a random 32-byte symmetric GROUP KEY encrypts messages (AES-256-GCM).
19
+ // - the group key is WRAPPED to each member's X25519 public key, ECIES-style:
20
+ // ephemeral X25519 → ECDH → HKDF-SHA256(salt = recipientPub) → AES-256-GCM.
21
+ // - AES framing: iv(12) ‖ ciphertext ‖ tag(16).
22
+ //
23
+ // Isomorphic: X25519 + HKDF via @noble, AES-256-GCM + RNG via Web Crypto (global
24
+ // `crypto`, present in browsers and Node 16+). AES ops are therefore async.
25
+ import { x25519, edwardsToMontgomeryPriv } from "@noble/curves/ed25519";
26
+ import { hkdf } from "@noble/hashes/hkdf";
27
+ import { sha256 } from "@noble/hashes/sha256";
28
+ export function genX25519() {
29
+ const priv = x25519.utils.randomPrivateKey();
30
+ return { priv, pub: x25519.getPublicKey(priv) };
31
+ }
32
+ export function randomGroupKey() {
33
+ const k = new Uint8Array(32);
34
+ crypto.getRandomValues(k);
35
+ return k;
36
+ }
37
+ const KEK_INFO = new TextEncoder().encode("evolver-group-chat/kek/v1");
38
+ async function aesGcmEncrypt(key, plaintext) {
39
+ const iv = new Uint8Array(12);
40
+ crypto.getRandomValues(iv);
41
+ const ck = await crypto.subtle.importKey("raw", key, "AES-GCM", false, ["encrypt"]);
42
+ const ct = new Uint8Array(await crypto.subtle.encrypt({ name: "AES-GCM", iv }, ck, plaintext));
43
+ const out = new Uint8Array(iv.length + ct.length); // subtle appends the 16-byte tag to ct
44
+ out.set(iv, 0);
45
+ out.set(ct, iv.length);
46
+ return out;
47
+ }
48
+ async function aesGcmDecrypt(key, blob) {
49
+ if (blob.length < 12 + 16)
50
+ throw new Error("ciphertext too short");
51
+ const iv = blob.subarray(0, 12);
52
+ const ctTag = blob.subarray(12);
53
+ const ck = await crypto.subtle.importKey("raw", key, "AES-GCM", false, ["decrypt"]);
54
+ return new Uint8Array(await crypto.subtle.decrypt({ name: "AES-GCM", iv: iv }, ck, ctTag));
55
+ }
56
+ /** Wrap the group key to a member's X25519 public key (ephemeral-sender ECIES). */
57
+ export async function wrapGroupKey(groupKey, recipientPub) {
58
+ const eph = genX25519();
59
+ const shared = x25519.getSharedSecret(eph.priv, recipientPub);
60
+ const kek = hkdf(sha256, shared, recipientPub, KEK_INFO, 32);
61
+ return { ephPub: eph.pub, blob: await aesGcmEncrypt(kek, groupKey) };
62
+ }
63
+ /** Recover the group key with the member's X25519 private key. MODULE-PRIVATE on purpose:
64
+ * the only way to reach it is a [[GroupKeyUnwrapper]] built by one of the factories
65
+ * below, so a raw key-agreement scalar never crosses a module boundary. */
66
+ async function unwrapRaw(w, recipientPriv) {
67
+ const recipientPub = x25519.getPublicKey(recipientPriv);
68
+ const shared = x25519.getSharedSecret(recipientPriv, w.ephPub);
69
+ const kek = hkdf(sha256, shared, recipientPub, KEK_INFO, 32);
70
+ return aesGcmDecrypt(kek, w.blob);
71
+ }
72
+ /** X25519 private derived from an Ed25519 seed. Module-private: see the header — this is
73
+ * the one derivation of the PRIVATE half in the SDK, and only the factory below calls it.
74
+ * (`edToX25519Pub` is public, in ./auth.ts — public material is meant to travel.) */
75
+ function edToX25519Priv(edPriv) {
76
+ return edwardsToMontgomeryPriv(edPriv);
77
+ }
78
+ /**
79
+ * An unwrapper over a NATIVE X25519 private key — the shape a separately registered
80
+ * encryption key would use (issue #53). The scalar lives only in this closure.
81
+ */
82
+ export function x25519GroupKeyUnwrapper(priv) {
83
+ const held = priv;
84
+ return { keyType: "X25519", unwrap: (w) => unwrapRaw(w, held) };
85
+ }
86
+ /**
87
+ * An unwrapper over an Ed25519 IDENTITY key: derives the key-agreement scalar once, at
88
+ * construction, and keeps it in this closure. This is what every member uses today —
89
+ * their on-chain Ed25519 key IS their encryption key.
90
+ *
91
+ * Pass the identity's 32-byte Ed25519 seed. Nothing else in the SDK or any application
92
+ * can obtain the derived scalar, which is the point: decryption is now reached through a
93
+ * handle, exactly as signing is reached through a Signer.
94
+ */
95
+ export function edGroupKeyUnwrapper(edPriv) {
96
+ const held = edToX25519Priv(edPriv);
97
+ return { keyType: "X25519 (from Ed25519 identity)", unwrap: (w) => unwrapRaw(w, held) };
98
+ }
99
+ /** Encrypt a message under the group key (this is the opaque channel tx_body). */
100
+ export function encryptMessage(groupKey, plaintext) {
101
+ return aesGcmEncrypt(groupKey, plaintext);
102
+ }
103
+ /** Decrypt a message with the group key. */
104
+ export function decryptMessage(groupKey, blob) {
105
+ return aesGcmDecrypt(groupKey, blob);
106
+ }
107
+ //# sourceMappingURL=group.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"group.js","sourceRoot":"","sources":["../../src/crypto/group.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,yFAAyF;AACzF,mFAAmF;AACnF,wFAAwF;AACxF,0FAA0F;AAC1F,uFAAuF;AACvF,0FAA0F;AAC1F,0FAA0F;AAC1F,wBAAwB;AACxB,EAAE;AACF,qFAAqF;AACrF,0FAA0F;AAC1F,oFAAoF;AACpF,sFAAsF;AACtF,2CAA2C;AAC3C,EAAE;AACF,iFAAiF;AACjF,4EAA4E;AAC5E,gFAAgF;AAChF,gFAAgF;AAChF,kDAAkD;AAClD,EAAE;AACF,iFAAiF;AACjF,4EAA4E;AAE5E,OAAO,EAAE,MAAM,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AACxE,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAQ9C,MAAM,UAAU,SAAS;IACvB,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,gBAAgB,EAAE,CAAC;IAC7C,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,MAAM,CAAC,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;IAC7B,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAC1B,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,QAAQ,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,2BAA2B,CAAC,CAAC;AAEvE,KAAK,UAAU,aAAa,CAAC,GAAe,EAAE,SAAqB;IACjE,MAAM,EAAE,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;IAC9B,MAAM,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;IAC3B,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,GAAmB,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;IACpG,MAAM,EAAE,GAAG,IAAI,UAAU,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,SAAyB,CAAC,CAAC,CAAC;IAC/G,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,MAAM,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,uCAAuC;IAC1F,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IACf,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;IACvB,OAAO,GAAG,CAAC;AACb,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,GAAe,EAAE,IAAgB;IAC5D,IAAI,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IACnE,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAChC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAChC,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,GAAmB,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;IACpG,OAAO,IAAI,UAAU,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,EAAkB,EAAE,EAAE,EAAE,EAAE,KAAqB,CAAC,CAAC,CAAC;AAC7H,CAAC;AAED,mFAAmF;AACnF,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAoB,EAAE,YAAwB;IAC/E,MAAM,GAAG,GAAG,SAAS,EAAE,CAAC;IACxB,MAAM,MAAM,GAAG,MAAM,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IAC9D,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;IAC7D,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,CAAC;AACvE,CAAC;AAED;;4EAE4E;AAC5E,KAAK,UAAU,SAAS,CAAC,CAAa,EAAE,aAAyB;IAC/D,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;IACxD,MAAM,MAAM,GAAG,MAAM,CAAC,eAAe,CAAC,aAAa,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;IAC/D,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;IAC7D,OAAO,aAAa,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACpC,CAAC;AAED;;sFAEsF;AACtF,SAAS,cAAc,CAAC,MAAkB;IACxC,OAAO,uBAAuB,CAAC,MAAM,CAAC,CAAC;AACzC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAAgB;IACtD,MAAM,IAAI,GAAG,IAAI,CAAC;IAClB,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC;AAClE,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAkB;IACpD,MAAM,IAAI,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IACpC,OAAO,EAAE,OAAO,EAAE,gCAAgC,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC;AAC1F,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,cAAc,CAAC,QAAoB,EAAE,SAAqB;IACxE,OAAO,aAAa,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;AAC5C,CAAC;AAED,4CAA4C;AAC5C,MAAM,UAAU,cAAc,CAAC,QAAoB,EAAE,IAAgB;IACnE,OAAO,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AACvC,CAAC"}
@@ -0,0 +1,7 @@
1
+ export declare function sha256(b: Uint8Array): Uint8Array;
2
+ /** Alias used where the call site means "the body hash". */
3
+ export declare const hash256: typeof sha256;
4
+ export declare function concatBytes(...arrays: Uint8Array[]): Uint8Array;
5
+ export declare function bytesToHex(bytes: Uint8Array): string;
6
+ export declare function hexToBytes(hex: string): Uint8Array;
7
+ //# sourceMappingURL=hash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../src/crypto/hash.ts"],"names":[],"mappings":"AAIA,wBAAgB,MAAM,CAAC,CAAC,EAAE,UAAU,GAAG,UAAU,CAEhD;AAED,4DAA4D;AAC5D,eAAO,MAAM,OAAO,eAAS,CAAC;AAE9B,wBAAgB,WAAW,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,GAAG,UAAU,CAU/D;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAIpD;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAKlD"}
@@ -0,0 +1,34 @@
1
+ // SHA-256 + byte utilities. Isomorphic (@noble/hashes is pure JS).
2
+ import { sha256 as nobleSha256 } from "@noble/hashes/sha256";
3
+ export function sha256(b) {
4
+ return nobleSha256(b);
5
+ }
6
+ /** Alias used where the call site means "the body hash". */
7
+ export const hash256 = sha256;
8
+ export function concatBytes(...arrays) {
9
+ let len = 0;
10
+ for (const a of arrays)
11
+ len += a.length;
12
+ const out = new Uint8Array(len);
13
+ let i = 0;
14
+ for (const a of arrays) {
15
+ out.set(a, i);
16
+ i += a.length;
17
+ }
18
+ return out;
19
+ }
20
+ export function bytesToHex(bytes) {
21
+ let s = "";
22
+ for (const b of bytes)
23
+ s += b.toString(16).padStart(2, "0");
24
+ return s;
25
+ }
26
+ export function hexToBytes(hex) {
27
+ if (hex.length % 2 !== 0)
28
+ throw new Error("invalid hex string");
29
+ const out = new Uint8Array(hex.length / 2);
30
+ for (let i = 0; i < out.length; i++)
31
+ out[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
32
+ return out;
33
+ }
34
+ //# sourceMappingURL=hash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.js","sourceRoot":"","sources":["../../src/crypto/hash.ts"],"names":[],"mappings":"AAAA,mEAAmE;AAEnE,OAAO,EAAE,MAAM,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAE7D,MAAM,UAAU,MAAM,CAAC,CAAa;IAClC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC;AACxB,CAAC;AAED,4DAA4D;AAC5D,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,CAAC;AAE9B,MAAM,UAAU,WAAW,CAAC,GAAG,MAAoB;IACjD,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,MAAM,CAAC,IAAI,MAAM;QAAE,GAAG,IAAI,CAAC,CAAC,MAAM,CAAC;IACxC,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;IAChC,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACd,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;IAChB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAiB;IAC1C,IAAI,CAAC,GAAG,EAAE,CAAC;IACX,KAAK,MAAM,CAAC,IAAI,KAAK;QAAE,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC5D,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;IAChE,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE;QAAE,GAAG,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACxF,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,27 @@
1
+ export declare const SEG_BYTES = 1048576;
2
+ /** Exact ciphertext length for a known plaintext length. */
3
+ export declare function ctSize(plaintextBytes: number): number;
4
+ /** Plaintext → v2 envelope. Buffers ≤ one segment.
5
+ *
6
+ * `noncePrefix` is injectable so format vectors are reproducible. IV uniqueness
7
+ * rests on (key, prefix) being used for exactly ONE file: reusing a key across
8
+ * files REQUIRES a distinct random prefix per file, and reusing a prefix
9
+ * REQUIRES a fresh key. Breaking that reuses an IV under one key, which forfeits
10
+ * both confidentiality and authenticity for every affected segment. The default
11
+ * (random prefix, and a fresh per-attachment key from the caller) satisfies it
12
+ * structurally — pass this only where both halves are known-fresh. */
13
+ export declare function encryptStream(key: Uint8Array, opts?: {
14
+ noncePrefix?: Uint8Array;
15
+ }): {
16
+ transform: TransformStream<Uint8Array, Uint8Array>;
17
+ };
18
+ /** v2 envelope → plaintext. Errors on ANY decrypt-obligation violation; only
19
+ * verified segments are emitted. rangeMode: the stream carries header+prefix
20
+ * followed by segments starting at firstSegIndex; ONLY the terminal-flag
21
+ * obligation is relaxed (an interior range cannot observe finality). */
22
+ export declare function decryptStream(key: Uint8Array, opts?: {
23
+ rangeMode?: {
24
+ firstSegIndex: number;
25
+ };
26
+ }): TransformStream<Uint8Array, Uint8Array>;
27
+ //# sourceMappingURL=stream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../src/crypto/stream.ts"],"names":[],"mappings":"AAkBA,eAAO,MAAM,SAAS,UAAY,CAAC;AAEnC,4DAA4D;AAC5D,wBAAgB,MAAM,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAGrD;AA6CD;;;;;;;;uEAQuE;AACvE,wBAAgB,aAAa,CAC3B,GAAG,EAAE,UAAU,EACf,IAAI,CAAC,EAAE;IAAE,WAAW,CAAC,EAAE,UAAU,CAAA;CAAE,GAClC;IAAE,SAAS,EAAE,eAAe,CAAC,UAAU,EAAE,UAAU,CAAC,CAAA;CAAE,CAkCxD;AAED;;;yEAGyE;AACzE,wBAAgB,aAAa,CAC3B,GAAG,EAAE,UAAU,EACf,IAAI,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE;QAAE,aAAa,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAC/C,eAAe,CAAC,UAAU,EAAE,UAAU,CAAC,CAsDzC"}