@sig-net/midnight 0.0.5 → 0.0.7

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 (58) hide show
  1. package/README.md +8 -0
  2. package/dist/constants.d.ts +4 -16
  3. package/dist/constants.d.ts.map +1 -1
  4. package/dist/constants.js +4 -16
  5. package/dist/constants.js.map +1 -1
  6. package/dist/ecdsa-attestation.d.ts +79 -0
  7. package/dist/ecdsa-attestation.d.ts.map +1 -0
  8. package/dist/ecdsa-attestation.js +140 -0
  9. package/dist/ecdsa-attestation.js.map +1 -0
  10. package/dist/epsilon-derivation.d.ts +60 -0
  11. package/dist/epsilon-derivation.d.ts.map +1 -1
  12. package/dist/epsilon-derivation.js +106 -5
  13. package/dist/epsilon-derivation.js.map +1 -1
  14. package/dist/index.d.ts +9 -7
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +9 -7
  17. package/dist/index.js.map +1 -1
  18. package/dist/managed/compiler/contract-info.json +70 -95
  19. package/dist/managed/compiler/contract-manifest.json +8 -8
  20. package/dist/managed/contract/index.d.ts +38 -42
  21. package/dist/managed/contract/index.js +225 -478
  22. package/dist/managed/contract/index.js.map +2 -2
  23. package/dist/signature-requests-state-reader.d.ts +14 -13
  24. package/dist/signature-requests-state-reader.d.ts.map +1 -1
  25. package/dist/signature-requests-state-reader.js +31 -20
  26. package/dist/signature-requests-state-reader.js.map +1 -1
  27. package/dist/signature-response-verification.d.ts +5 -5
  28. package/dist/signature-response-verification.d.ts.map +1 -1
  29. package/dist/signature-response-verification.js +4 -4
  30. package/dist/signature-response-verification.js.map +1 -1
  31. package/dist/signet-contract-state-reader.d.ts +102 -109
  32. package/dist/signet-contract-state-reader.d.ts.map +1 -1
  33. package/dist/signet-contract-state-reader.js +125 -119
  34. package/dist/signet-contract-state-reader.js.map +1 -1
  35. package/dist/signet-request-feed.d.ts +4 -3
  36. package/dist/signet-request-feed.d.ts.map +1 -1
  37. package/dist/signet-request-feed.js +9 -8
  38. package/dist/signet-request-feed.js.map +1 -1
  39. package/dist/signet-request-resolver.d.ts +6 -4
  40. package/dist/signet-request-resolver.d.ts.map +1 -1
  41. package/dist/signet-request-resolver.js +8 -6
  42. package/dist/signet-request-resolver.js.map +1 -1
  43. package/dist/signet-request-response-reader.d.ts +21 -20
  44. package/dist/signet-request-response-reader.d.ts.map +1 -1
  45. package/dist/signet-request-response-reader.js +35 -23
  46. package/dist/signet-request-response-reader.js.map +1 -1
  47. package/dist/signet-requests.d.ts +93 -59
  48. package/dist/signet-requests.d.ts.map +1 -1
  49. package/dist/signet-requests.js +84 -67
  50. package/dist/signet-requests.js.map +1 -1
  51. package/package.json +2 -2
  52. package/src/Signet.compact +275 -413
  53. package/src/circuits.compact +24 -25
  54. package/dist/schnorr.d.ts +0 -100
  55. package/dist/schnorr.d.ts.map +0 -1
  56. package/dist/schnorr.js +0 -144
  57. package/dist/schnorr.js.map +0 -1
  58. package/src/Schnorr.compact +0 -63
package/README.md CHANGED
@@ -15,6 +15,14 @@ The client-agnostic [Sig Network](https://sig.network) protocol library for the
15
15
 
16
16
  Where signet.js already covers something (for example EVM transaction preparation or address derivation), import it from there; only what is Midnight-specific lives here.
17
17
 
18
+ ## Derived keys
19
+
20
+ Every key the MPC signs with is scoped by the requesting contract:
21
+
22
+ `derivedSigningKey = f(mpcRootKey[keyVersion], contractAddress, path)`
23
+
24
+ The path is 32 opaque bytes of the contract's choosing (a fixed literal for a contract-owned account, a hash of a caller's secret for per-user accounts). There are no format requirements. The contract address is always part of the derivation, so no contract can reach another contract's derived keys.
25
+
18
26
  ## Install
19
27
 
20
28
  ```sh
@@ -1,18 +1,10 @@
1
- /** Width of `SignBidirectionalRequest.caip2Id` (`Bytes<32>`). */
1
+ /** Width of `SignBidirectionalEvent.caip2Id` (`Bytes<32>`). */
2
2
  export declare const CAIP2_ID_BYTES = 32;
3
- /** Width of `SignBidirectionalRequest.algo` (`Bytes<32>`). */
4
- export declare const ALGO_BYTES = 32;
5
- /** Width of `SignBidirectionalRequest.dest` (`Bytes<32>`). */
6
- export declare const DEST_BYTES = 32;
7
- /** Width of `SignBidirectionalRequest.params` (`Bytes<64>`). */
3
+ /** Width of `SignBidirectionalEvent.params` (`Bytes<64>`). */
8
4
  export declare const MPC_PARAMS_BYTES = 64;
9
- /** Width of `SignBidirectionalRequest.outputDeserializationSchema` (`Bytes<128>`). */
10
- export declare const OUTPUT_DESERIALIZATION_SCHEMA_BYTES = 128;
11
- /** Width of `SignBidirectionalRequest.respondSerializationSchema` (`Bytes<128>`). */
12
- export declare const RESPOND_SERIALIZATION_SCHEMA_BYTES = 128;
13
5
  /** Width of `EVMCalldata.selector` (`Bytes<4>`) — the literal first 4 calldata bytes. */
14
6
  export declare const SELECTOR_BYTES = 4;
15
- /** Width of `RespondBidirectional.serializedOutput` (`Bytes<128>`). */
7
+ /** Width of `RespondBidirectionalEvent.serializedOutput` (`Bytes<128>`). */
16
8
  export declare const SERIALIZED_OUTPUT_BYTES = 128;
17
9
  /**
18
10
  * The MPC's error sentinel: `serializedOutput` beginning with these four
@@ -38,14 +30,10 @@ export declare function executionSucceeded(serializedOutput: Uint8Array): boolea
38
30
  * @returns `true` when the MPC reported an execution error.
39
31
  */
40
32
  export declare function isExecutionError(serializedOutput: Uint8Array): boolean;
41
- /** Signature algorithm the MPC uses for EVM chains (`algo` field value). */
42
- export declare const SIGNET_ALGO_ECDSA = "ecdsa";
43
- /** Destination chain family for EVM requests (`dest` field value). */
44
- export declare const SIGNET_DEST_ETHEREUM = "ethereum";
45
33
  /**
46
34
  * Default MPC key version (`keyVersion` field value). Version 0 is the
47
35
  * unsupported legacy format — the canonical MPC (and
48
- * `constructSignBidirectionalRequest`) requires `keyVersion >= 1`.
36
+ * `constructSignBidirectionalEvent`) requires `keyVersion >= 1`.
49
37
  */
50
38
  export declare const SIGNET_DEFAULT_KEY_VERSION = 1n;
51
39
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAUA,iEAAiE;AACjE,eAAO,MAAM,cAAc,KAAK,CAAC;AAEjC,8DAA8D;AAC9D,eAAO,MAAM,UAAU,KAAK,CAAC;AAE7B,8DAA8D;AAC9D,eAAO,MAAM,UAAU,KAAK,CAAC;AAE7B,gEAAgE;AAChE,eAAO,MAAM,gBAAgB,KAAK,CAAC;AAEnC,sFAAsF;AACtF,eAAO,MAAM,mCAAmC,MAAM,CAAC;AAEvD,qFAAqF;AACrF,eAAO,MAAM,kCAAkC,MAAM,CAAC;AAEtD,yFAAyF;AACzF,eAAO,MAAM,cAAc,IAAI,CAAC;AAEhC,uEAAuE;AACvE,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAE3C;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,yBAA2C,CAAC;AAE3E;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,gBAAgB,EAAE,UAAU,GAAG,OAAO,CAExE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,gBAAgB,EAAE,UAAU,GAAG,OAAO,CAEtE;AAED,4EAA4E;AAC5E,eAAO,MAAM,iBAAiB,UAAU,CAAC;AAEzC,sEAAsE;AACtE,eAAO,MAAM,oBAAoB,aAAa,CAAC;AAE/C;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAE7C;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU,CAQpE"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAUA,+DAA+D;AAC/D,eAAO,MAAM,cAAc,KAAK,CAAC;AAEjC,8DAA8D;AAC9D,eAAO,MAAM,gBAAgB,KAAK,CAAC;AAEnC,yFAAyF;AACzF,eAAO,MAAM,cAAc,IAAI,CAAC;AAEhC,4EAA4E;AAC5E,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAE3C;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,yBAA2C,CAAC;AAE3E;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,gBAAgB,EAAE,UAAU,GAAG,OAAO,CAExE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,gBAAgB,EAAE,UAAU,GAAG,OAAO,CAEtE;AAED;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAE7C;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU,CAQpE"}
package/dist/constants.js CHANGED
@@ -7,21 +7,13 @@
7
7
  //
8
8
  // The routing constants belong in github.com/sig-net/signet.js — kept here
9
9
  // until upstreamed.
10
- /** Width of `SignBidirectionalRequest.caip2Id` (`Bytes<32>`). */
10
+ /** Width of `SignBidirectionalEvent.caip2Id` (`Bytes<32>`). */
11
11
  export const CAIP2_ID_BYTES = 32;
12
- /** Width of `SignBidirectionalRequest.algo` (`Bytes<32>`). */
13
- export const ALGO_BYTES = 32;
14
- /** Width of `SignBidirectionalRequest.dest` (`Bytes<32>`). */
15
- export const DEST_BYTES = 32;
16
- /** Width of `SignBidirectionalRequest.params` (`Bytes<64>`). */
12
+ /** Width of `SignBidirectionalEvent.params` (`Bytes<64>`). */
17
13
  export const MPC_PARAMS_BYTES = 64;
18
- /** Width of `SignBidirectionalRequest.outputDeserializationSchema` (`Bytes<128>`). */
19
- export const OUTPUT_DESERIALIZATION_SCHEMA_BYTES = 128;
20
- /** Width of `SignBidirectionalRequest.respondSerializationSchema` (`Bytes<128>`). */
21
- export const RESPOND_SERIALIZATION_SCHEMA_BYTES = 128;
22
14
  /** Width of `EVMCalldata.selector` (`Bytes<4>`) — the literal first 4 calldata bytes. */
23
15
  export const SELECTOR_BYTES = 4;
24
- /** Width of `RespondBidirectional.serializedOutput` (`Bytes<128>`). */
16
+ /** Width of `RespondBidirectionalEvent.serializedOutput` (`Bytes<128>`). */
25
17
  export const SERIALIZED_OUTPUT_BYTES = 128;
26
18
  /**
27
19
  * The MPC's error sentinel: `serializedOutput` beginning with these four
@@ -51,14 +43,10 @@ export function executionSucceeded(serializedOutput) {
51
43
  export function isExecutionError(serializedOutput) {
52
44
  return MPC_ERROR_SENTINEL.every((byte, index) => serializedOutput[index] === byte);
53
45
  }
54
- /** Signature algorithm the MPC uses for EVM chains (`algo` field value). */
55
- export const SIGNET_ALGO_ECDSA = "ecdsa";
56
- /** Destination chain family for EVM requests (`dest` field value). */
57
- export const SIGNET_DEST_ETHEREUM = "ethereum";
58
46
  /**
59
47
  * Default MPC key version (`keyVersion` field value). Version 0 is the
60
48
  * unsupported legacy format — the canonical MPC (and
61
- * `constructSignBidirectionalRequest`) requires `keyVersion >= 1`.
49
+ * `constructSignBidirectionalEvent`) requires `keyVersion >= 1`.
62
50
  */
63
51
  export const SIGNET_DEFAULT_KEY_VERSION = 1n;
64
52
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,iEAAiE;AACjE,yEAAyE;AACzE,6EAA6E;AAC7E,4EAA4E;AAC5E,kEAAkE;AAClE,EAAE;AACF,2EAA2E;AAC3E,oBAAoB;AAEpB,iEAAiE;AACjE,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,CAAC;AAEjC,8DAA8D;AAC9D,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,CAAC;AAE7B,8DAA8D;AAC9D,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,CAAC;AAE7B,gEAAgE;AAChE,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAEnC,sFAAsF;AACtF,MAAM,CAAC,MAAM,mCAAmC,GAAG,GAAG,CAAC;AAEvD,qFAAqF;AACrF,MAAM,CAAC,MAAM,kCAAkC,GAAG,GAAG,CAAC;AAEtD,yFAAyF;AACzF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC;AAEhC,uEAAuE;AACvE,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAG,CAAC;AAE3C;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,UAAU,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;AAE3E;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAAC,gBAA4B;IAC7D,OAAO,gBAAgB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;AACnC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,gBAA4B;IAC3D,OAAO,kBAAkB,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC;AACrF,CAAC;AAED,4EAA4E;AAC5E,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAC;AAEzC,sEAAsE;AACtE,MAAM,CAAC,MAAM,oBAAoB,GAAG,UAAU,CAAC;AAE/C;;;;GAIG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,EAAE,CAAC;AAE7C;;;;;;;;;GASG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,MAAc;IACtD,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC/C,IAAI,OAAO,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,IAAI,IAAI,QAAQ,OAAO,CAAC,MAAM,6BAA6B,MAAM,aAAa,CAAC,CAAC;IAClG,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;IACnC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACjB,OAAO,GAAG,CAAC;AACb,CAAC"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,iEAAiE;AACjE,yEAAyE;AACzE,6EAA6E;AAC7E,4EAA4E;AAC5E,kEAAkE;AAClE,EAAE;AACF,2EAA2E;AAC3E,oBAAoB;AAEpB,+DAA+D;AAC/D,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,CAAC;AAEjC,8DAA8D;AAC9D,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAEnC,yFAAyF;AACzF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC;AAEhC,4EAA4E;AAC5E,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAG,CAAC;AAE3C;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,UAAU,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;AAE3E;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAAC,gBAA4B;IAC7D,OAAO,gBAAgB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;AACnC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,gBAA4B;IAC3D,OAAO,kBAAkB,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC;AACrF,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,EAAE,CAAC;AAE7C;;;;;;;;;GASG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,MAAc;IACtD,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC/C,IAAI,OAAO,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,IAAI,IAAI,QAAQ,OAAO,CAAC,MAAM,6BAA6B,MAAM,aAAa,CAAC,CAAC;IAClG,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;IACnC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACjB,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,79 @@
1
+ import type { Secp256k1Point } from "@midnight-ntwrk/compact-runtime";
2
+ export type { Secp256k1Point } from "@midnight-ntwrk/compact-runtime";
3
+ /** secp256k1 curve (group) order n. */
4
+ export declare const SECP256K1_ORDER: bigint;
5
+ /** BLS12-381 scalar field order (the Compact `Field` type modulus). */
6
+ export declare const BLS_ORDER = 52435875175126190479447740508185965837690552500527637822603658699938581184513n;
7
+ /**
8
+ * Convert little-endian bytes to a bigint. Matches Compact's
9
+ * `Bytes<32> as Field` / `Bytes<32> as Secp256k1Scalar` interpretation (both
10
+ * casts are little-endian).
11
+ *
12
+ * @param bytes - Little-endian byte array.
13
+ * @returns The decoded non-negative integer.
14
+ */
15
+ export declare function bytesToBigint(bytes: Uint8Array): bigint;
16
+ /**
17
+ * Convert a bigint to exactly 32 little-endian bytes. Matches Compact's
18
+ * `Field as Bytes<32>` / `Secp256k1Scalar as Bytes<32>` encoding (the inverse
19
+ * of {@link bytesToBigint}); negative inputs are interpreted in the BLS
20
+ * scalar field.
21
+ *
22
+ * @param n - The integer to encode.
23
+ * @returns The 32-byte little-endian encoding.
24
+ */
25
+ export declare function bigintToBytes32(n: bigint): Uint8Array;
26
+ /**
27
+ * An ECDSA signature over the attestation digest, in the MPC's canonical
28
+ * `Signature { big_r, s, recovery_id }` spirit with `r` already reduced to
29
+ * the scalar `big_r.x mod n` — the form Compact's `Secp256k1EcdsaSignature`
30
+ * takes.
31
+ */
32
+ export interface EcdsaSignature {
33
+ /** Signature scalar r (= R.x mod n). */
34
+ r: bigint;
35
+ /** Signature scalar s (low-s normalised by the signer). */
36
+ s: bigint;
37
+ /** Recovery id (parity of R.y): 0 or 1. */
38
+ recoveryId: number;
39
+ }
40
+ /**
41
+ * ECDSA-sign a 32-byte digest with a secp256k1 secret key, exactly as the
42
+ * MPC signs the attestation digest: RFC 6979 deterministic, low-s, the digest
43
+ * interpreted big-endian with NO extra hashing (`prehash: false`) — the same
44
+ * convention `secp256k1EcdsaVerify` checks in-circuit.
45
+ *
46
+ * @param digest - The 32-byte digest to sign (e.g. the compiled
47
+ * `pureCircuits.signetAttestationDigest` output).
48
+ * @param secretKey - The 32-byte secp256k1 secret key.
49
+ * @returns The signature with its recovery id.
50
+ */
51
+ export declare function signAttestationDigest(digest: Uint8Array, secretKey: Uint8Array): EcdsaSignature;
52
+ /**
53
+ * Parse a secp256k1 public key from SEC1 hex (compressed or uncompressed,
54
+ * optional `0x` prefix) into the Compact runtime's `Secp256k1Point` shape —
55
+ * how deploys receive the MPC response key to pin.
56
+ *
57
+ * @param value - The SEC1 hex public key.
58
+ * @returns The parsed point.
59
+ * @throws Error if the value is not a valid secp256k1 public key.
60
+ */
61
+ export declare function parseSecp256k1PublicKey(value: string): Secp256k1Point;
62
+ /**
63
+ * Format a secp256k1 public key point as uncompressed SEC1 hex (with `0x`
64
+ * prefix) — the round-trip inverse of {@link parseSecp256k1PublicKey}, for
65
+ * handing a response key to deploys via env/config.
66
+ *
67
+ * @param point - The point to format.
68
+ * @returns The `0x04…` uncompressed SEC1 hex string.
69
+ */
70
+ export declare function formatSecp256k1PublicKey(point: Secp256k1Point): string;
71
+ /**
72
+ * Derive the `Secp256k1Point` of a secret key — convenience for tests and
73
+ * signers that hold key material as raw bytes.
74
+ *
75
+ * @param secretKey - The 32-byte secp256k1 secret key.
76
+ * @returns The public key point.
77
+ */
78
+ export declare function secp256k1PublicKeyOf(secretKey: Uint8Array): Secp256k1Point;
79
+ //# sourceMappingURL=ecdsa-attestation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ecdsa-attestation.d.ts","sourceRoot":"","sources":["../src/ecdsa-attestation.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAItE,YAAY,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAEtE,uCAAuC;AACvC,eAAO,MAAM,eAAe,QAA2B,CAAC;AAExD,uEAAuE;AACvE,eAAO,MAAM,SAAS,iFAAiF,CAAC;AAExG;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAMvD;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,UAAU,CAQrD;AAWD;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,wCAAwC;IACxC,CAAC,EAAE,MAAM,CAAC;IACV,2DAA2D;IAC3D,CAAC,EAAE,MAAM,CAAC;IACV,2CAA2C;IAC3C,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE,UAAU,GACpB,cAAc,CAiBhB;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,CAcrE;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAGtE;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,UAAU,GAAG,cAAc,CAO1E"}
@@ -0,0 +1,140 @@
1
+ // secp256k1 ECDSA helpers: the TS side of the respond-bidirectional
2
+ // attestation flow in Signet.compact — SIGNING (which needs the secret
3
+ // scalar, so it cannot be a circuit), key parsing/formatting, and the
4
+ // byte-order conversions between noble's bigints and the ledger-stored
5
+ // little-endian scalar bytes. Everything provable stays in Compact: the
6
+ // attestation digest is the COMPILED `pureCircuits.signetAttestationDigest`,
7
+ // verification is `pureCircuits.verifyRespondBidirectionalEvent` (the same
8
+ // check client contracts run in-circuit), and the deploy-time key pin is
9
+ // `pureCircuits.signetKeyHash` — this file never re-implements any of them.
10
+ //
11
+ // This belongs in github.com/sig-net/signet.js as its Midnight adapter —
12
+ // kept here until upstreamed.
13
+ import { secp256k1 } from "@noble/curves/secp256k1.js";
14
+ /** secp256k1 curve (group) order n. */
15
+ export const SECP256K1_ORDER = secp256k1.Point.Fn.ORDER;
16
+ /** BLS12-381 scalar field order (the Compact `Field` type modulus). */
17
+ export const BLS_ORDER = 52435875175126190479447740508185965837690552500527637822603658699938581184513n;
18
+ /**
19
+ * Convert little-endian bytes to a bigint. Matches Compact's
20
+ * `Bytes<32> as Field` / `Bytes<32> as Secp256k1Scalar` interpretation (both
21
+ * casts are little-endian).
22
+ *
23
+ * @param bytes - Little-endian byte array.
24
+ * @returns The decoded non-negative integer.
25
+ */
26
+ export function bytesToBigint(bytes) {
27
+ let result = 0n;
28
+ for (let i = bytes.length - 1; i >= 0; i--) {
29
+ result = (result << 8n) | BigInt(bytes[i]);
30
+ }
31
+ return result;
32
+ }
33
+ /**
34
+ * Convert a bigint to exactly 32 little-endian bytes. Matches Compact's
35
+ * `Field as Bytes<32>` / `Secp256k1Scalar as Bytes<32>` encoding (the inverse
36
+ * of {@link bytesToBigint}); negative inputs are interpreted in the BLS
37
+ * scalar field.
38
+ *
39
+ * @param n - The integer to encode.
40
+ * @returns The 32-byte little-endian encoding.
41
+ */
42
+ export function bigintToBytes32(n) {
43
+ const buf = new Uint8Array(32);
44
+ let v = n < 0n ? n + BLS_ORDER : n;
45
+ for (let i = 0; i < 32; i++) {
46
+ buf[i] = Number(v & 0xffn);
47
+ v >>= 8n;
48
+ }
49
+ return buf;
50
+ }
51
+ /** Convert big-endian bytes to a bigint (SEC1 coordinate order). */
52
+ function bytesToBigintBE(bytes) {
53
+ let value = 0n;
54
+ for (const byte of bytes) {
55
+ value = (value << 8n) | BigInt(byte);
56
+ }
57
+ return value;
58
+ }
59
+ /**
60
+ * ECDSA-sign a 32-byte digest with a secp256k1 secret key, exactly as the
61
+ * MPC signs the attestation digest: RFC 6979 deterministic, low-s, the digest
62
+ * interpreted big-endian with NO extra hashing (`prehash: false`) — the same
63
+ * convention `secp256k1EcdsaVerify` checks in-circuit.
64
+ *
65
+ * @param digest - The 32-byte digest to sign (e.g. the compiled
66
+ * `pureCircuits.signetAttestationDigest` output).
67
+ * @param secretKey - The 32-byte secp256k1 secret key.
68
+ * @returns The signature with its recovery id.
69
+ */
70
+ export function signAttestationDigest(digest, secretKey) {
71
+ const sigBytes = secp256k1.sign(digest, secretKey, { prehash: false });
72
+ const sig = secp256k1.Signature.fromBytes(sigBytes, "compact");
73
+ // Recover the id by trying both parities against the actual public key.
74
+ const pk = secp256k1.getPublicKey(secretKey, false);
75
+ const pkHex = Buffer.from(pk).toString("hex");
76
+ for (const recoveryId of [0, 1]) {
77
+ const recovered = sig
78
+ .addRecoveryBit(recoveryId)
79
+ .recoverPublicKey(digest)
80
+ .toHex(false);
81
+ if (recovered === pkHex) {
82
+ return { r: sig.r, s: sig.s, recoveryId };
83
+ }
84
+ }
85
+ /* v8 ignore next: unreachable for a signature this function just produced */
86
+ throw new Error("signature does not recover to its own public key");
87
+ }
88
+ /**
89
+ * Parse a secp256k1 public key from SEC1 hex (compressed or uncompressed,
90
+ * optional `0x` prefix) into the Compact runtime's `Secp256k1Point` shape —
91
+ * how deploys receive the MPC response key to pin.
92
+ *
93
+ * @param value - The SEC1 hex public key.
94
+ * @returns The parsed point.
95
+ * @throws Error if the value is not a valid secp256k1 public key.
96
+ */
97
+ export function parseSecp256k1PublicKey(value) {
98
+ const hex = value.startsWith("0x") || value.startsWith("0X") ? value.slice(2) : value;
99
+ let point;
100
+ try {
101
+ point = secp256k1.Point.fromHex(hex);
102
+ }
103
+ catch (error) {
104
+ throw new Error(`not a secp256k1 public key in SEC1 hex: "${value}" (${String(error)})`);
105
+ }
106
+ const uncompressed = point.toBytes(false); // 0x04 || x || y
107
+ return {
108
+ x: bytesToBigintBE(uncompressed.slice(1, 33)),
109
+ y: bytesToBigintBE(uncompressed.slice(33, 65)),
110
+ identity: false,
111
+ };
112
+ }
113
+ /**
114
+ * Format a secp256k1 public key point as uncompressed SEC1 hex (with `0x`
115
+ * prefix) — the round-trip inverse of {@link parseSecp256k1PublicKey}, for
116
+ * handing a response key to deploys via env/config.
117
+ *
118
+ * @param point - The point to format.
119
+ * @returns The `0x04…` uncompressed SEC1 hex string.
120
+ */
121
+ export function formatSecp256k1PublicKey(point) {
122
+ const toBE32 = (v) => v.toString(16).padStart(64, "0");
123
+ return `0x04${toBE32(point.x)}${toBE32(point.y)}`;
124
+ }
125
+ /**
126
+ * Derive the `Secp256k1Point` of a secret key — convenience for tests and
127
+ * signers that hold key material as raw bytes.
128
+ *
129
+ * @param secretKey - The 32-byte secp256k1 secret key.
130
+ * @returns The public key point.
131
+ */
132
+ export function secp256k1PublicKeyOf(secretKey) {
133
+ const uncompressed = secp256k1.getPublicKey(secretKey, false);
134
+ return {
135
+ x: bytesToBigintBE(uncompressed.slice(1, 33)),
136
+ y: bytesToBigintBE(uncompressed.slice(33, 65)),
137
+ identity: false,
138
+ };
139
+ }
140
+ //# sourceMappingURL=ecdsa-attestation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ecdsa-attestation.js","sourceRoot":"","sources":["../src/ecdsa-attestation.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { type Secp256k1Point } from "./ecdsa-attestation.ts";
1
2
  /**
2
3
  * Domain prefix of the sig-net v1.0.0 epsilon derivation scheme, as used by
3
4
  * the live response server. The full derivation string is
@@ -9,6 +10,24 @@ export declare const EPSILON_DERIVATION_PREFIX = "sig.network v1.0.0 epsilon der
9
10
  * from Midnight contracts.
10
11
  */
11
12
  export declare const MIDNIGHT_TESTNET_CHAIN_ID = "midnight:testnet";
13
+ /**
14
+ * The FIXED derivation path of the MPC's respond-bidirectional RESPONSE key
15
+ * for Midnight client contracts (mirrors the MPC's per-chain
16
+ * `<chain> response key` convention, sig-net/mpc
17
+ * chain-signatures/node/src/respond_bidirectional.rs). The response key is
18
+ * derived from (the SIGNET SINGLETON contract address, this path): it is not
19
+ * the MPC root key and not the key that signs the requested transaction.
20
+ * Client contracts pin its hash at deploy time and verify
21
+ * RespondBidirectionalEvents against it.
22
+ *
23
+ * Why the SIGNET address and not the client contract's own address: the pin
24
+ * is sealed in the client's CONSTRUCTOR, and a Midnight contract address is
25
+ * a hash over the deploy (constructor arguments included), so a key derived
26
+ * from the client's own address could never be known at the moment it must
27
+ * be sealed. The signet singleton deploys first, so its address is available
28
+ * to every client deploy, and the key stays scoped per signet deployment.
29
+ */
30
+ export declare const MIDNIGHT_RESPOND_BIDIRECTIONAL_PATH = "midnight response key";
12
31
  /**
13
32
  * Derive the EVM address the MPC network signs from for a given Midnight
14
33
  * contract and derivation path, using the sig-net v1.0.0 epsilon scheme:
@@ -29,4 +48,45 @@ export declare const MIDNIGHT_TESTNET_CHAIN_ID = "midnight:testnet";
29
48
  * @returns The derived EVM address as a 0x-prefixed EIP-55 checksummed string.
30
49
  */
31
50
  export declare function deriveEvmAddress(mpcSecp256k1PubkeyHex: string, contractAddress: string, path: string, chainId?: string): string;
51
+ /**
52
+ * The epsilon scalar of the sig-net v1.0.0 derivation scheme:
53
+ * `keccak256("<prefix>,<chainId>,<requester>,<path>")` reduced mod the
54
+ * secp256k1 curve order. Child keys are `root + epsilon` (secret side) and
55
+ * `rootPubKey + epsilon * G` (public side).
56
+ *
57
+ * @param requester - The requester component of the derivation string,
58
+ * verbatim (no normalisation: callers must agree on the exact rendering).
59
+ * @param path - The derivation path string.
60
+ * @param chainId - CAIP-2 chain id component of the derivation string.
61
+ * @returns The epsilon scalar, in `[0, n)`.
62
+ */
63
+ export declare function deriveEpsilon(requester: string, path: string, chainId?: string): bigint;
64
+ /**
65
+ * Derive the MPC's respond-bidirectional RESPONSE key for a signet
66
+ * deployment, public side: what client-contract deploys pin
67
+ * (`MPC_RESPONSE_KEY`) and what response verification checks against. See
68
+ * {@link MIDNIGHT_RESPOND_BIDIRECTIONAL_PATH} for the scheme and why the
69
+ * requester is the signet singleton's address.
70
+ *
71
+ * @param mpcSecp256k1PubkeyHex - The MPC root secp256k1 public key as 0x-hex
72
+ * (compressed or uncompressed).
73
+ * @param signetContractAddress - The signet singleton's Midnight contract
74
+ * address (`0x` prefix optional, case-insensitive).
75
+ * @returns The response public key as a Compact-runtime `Secp256k1Point`.
76
+ */
77
+ export declare function deriveMidnightResponseKey(mpcSecp256k1PubkeyHex: string, signetContractAddress: string): Secp256k1Point;
78
+ /**
79
+ * Derive the MPC's respond-bidirectional RESPONSE key for a signet
80
+ * deployment, secret side: `(rootSecret + epsilon) mod n`. MPC-side only
81
+ * (the fakenet signer, test harnesses): a real client never holds the root
82
+ * key. The result feeds `signAttestationDigest` directly.
83
+ *
84
+ * @param mpcRootSecretKey - The 32-byte MPC root secret key (big-endian, the
85
+ * standard secp256k1 encoding).
86
+ * @param signetContractAddress - The signet singleton's Midnight contract
87
+ * address (`0x` prefix optional, case-insensitive).
88
+ * @returns The 32-byte response secret key (big-endian).
89
+ * @throws Error if the root key is not 32 bytes or the derived scalar is 0.
90
+ */
91
+ export declare function deriveMidnightResponseSecretKey(mpcRootSecretKey: Uint8Array, signetContractAddress: string): Uint8Array;
32
92
  //# sourceMappingURL=epsilon-derivation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"epsilon-derivation.d.ts","sourceRoot":"","sources":["../src/epsilon-derivation.ts"],"names":[],"mappings":"AAeA;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,0CAA0C,CAAC;AAEjF;;;GAGG;AACH,eAAO,MAAM,yBAAyB,qBAAqB,CAAC;AAE5D;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,gBAAgB,CAC9B,qBAAqB,EAAE,MAAM,EAC7B,eAAe,EAAE,MAAM,EACvB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,MAAkC,GAC1C,MAAM,CASR"}
1
+ {"version":3,"file":"epsilon-derivation.d.ts","sourceRoot":"","sources":["../src/epsilon-derivation.ts"],"names":[],"mappings":"AAeA,OAAO,EAAmB,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE9E;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,0CAA0C,CAAC;AAEjF;;;GAGG;AACH,eAAO,MAAM,yBAAyB,qBAAqB,CAAC;AAE5D;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,mCAAmC,0BAA0B,CAAC;AAE3E;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,gBAAgB,CAC9B,qBAAqB,EAAE,MAAM,EAC7B,eAAe,EAAE,MAAM,EACvB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,MAAkC,GAC1C,MAAM,CAGR;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,MAAkC,GAC1C,MAAM,CAKR;AA6BD;;;;;;;;;;;;GAYG;AACH,wBAAgB,yBAAyB,CACvC,qBAAqB,EAAE,MAAM,EAC7B,qBAAqB,EAAE,MAAM,GAC5B,cAAc,CAQhB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,+BAA+B,CAC7C,gBAAgB,EAAE,UAAU,EAC5B,qBAAqB,EAAE,MAAM,GAC5B,UAAU,CAwBZ"}
@@ -11,6 +11,7 @@
11
11
  // matches the server.
12
12
  import { secp256k1 } from "@noble/curves/secp256k1.js";
13
13
  import { computeAddress, keccak256, SigningKey, toUtf8Bytes } from "ethers";
14
+ import { SECP256K1_ORDER } from "./ecdsa-attestation.js";
14
15
  /**
15
16
  * Domain prefix of the sig-net v1.0.0 epsilon derivation scheme, as used by
16
17
  * the live response server. The full derivation string is
@@ -22,6 +23,24 @@ export const EPSILON_DERIVATION_PREFIX = "sig.network v1.0.0 epsilon derivation"
22
23
  * from Midnight contracts.
23
24
  */
24
25
  export const MIDNIGHT_TESTNET_CHAIN_ID = "midnight:testnet";
26
+ /**
27
+ * The FIXED derivation path of the MPC's respond-bidirectional RESPONSE key
28
+ * for Midnight client contracts (mirrors the MPC's per-chain
29
+ * `<chain> response key` convention, sig-net/mpc
30
+ * chain-signatures/node/src/respond_bidirectional.rs). The response key is
31
+ * derived from (the SIGNET SINGLETON contract address, this path): it is not
32
+ * the MPC root key and not the key that signs the requested transaction.
33
+ * Client contracts pin its hash at deploy time and verify
34
+ * RespondBidirectionalEvents against it.
35
+ *
36
+ * Why the SIGNET address and not the client contract's own address: the pin
37
+ * is sealed in the client's CONSTRUCTOR, and a Midnight contract address is
38
+ * a hash over the deploy (constructor arguments included), so a key derived
39
+ * from the client's own address could never be known at the moment it must
40
+ * be sealed. The signet singleton deploys first, so its address is available
41
+ * to every client deploy, and the key stays scoped per signet deployment.
42
+ */
43
+ export const MIDNIGHT_RESPOND_BIDIRECTIONAL_PATH = "midnight response key";
25
44
  /**
26
45
  * Derive the EVM address the MPC network signs from for a given Midnight
27
46
  * contract and derivation path, using the sig-net v1.0.0 epsilon scheme:
@@ -42,13 +61,95 @@ export const MIDNIGHT_TESTNET_CHAIN_ID = "midnight:testnet";
42
61
  * @returns The derived EVM address as a 0x-prefixed EIP-55 checksummed string.
43
62
  */
44
63
  export function deriveEvmAddress(mpcSecp256k1PubkeyHex, contractAddress, path, chainId = MIDNIGHT_TESTNET_CHAIN_ID) {
45
- const fullPath = `${EPSILON_DERIVATION_PREFIX},${chainId},${contractAddress},${path}`;
46
- // Reduce mod n before multiplying: noble throws on scalars >= n, whereas the
64
+ const derivedPoint = deriveChildPoint(mpcSecp256k1PubkeyHex, contractAddress, path, chainId);
65
+ return computeAddress(`0x${derivedPoint.toHex(false)}`);
66
+ }
67
+ /**
68
+ * The epsilon scalar of the sig-net v1.0.0 derivation scheme:
69
+ * `keccak256("<prefix>,<chainId>,<requester>,<path>")` reduced mod the
70
+ * secp256k1 curve order. Child keys are `root + epsilon` (secret side) and
71
+ * `rootPubKey + epsilon * G` (public side).
72
+ *
73
+ * @param requester - The requester component of the derivation string,
74
+ * verbatim (no normalisation: callers must agree on the exact rendering).
75
+ * @param path - The derivation path string.
76
+ * @param chainId - CAIP-2 chain id component of the derivation string.
77
+ * @returns The epsilon scalar, in `[0, n)`.
78
+ */
79
+ export function deriveEpsilon(requester, path, chainId = MIDNIGHT_TESTNET_CHAIN_ID) {
80
+ const fullPath = `${EPSILON_DERIVATION_PREFIX},${chainId},${requester},${path}`;
81
+ // Reduce mod n before using: noble throws on scalars >= n, whereas the
47
82
  // server's scalar arithmetic reduces implicitly.
48
- const epsilon = BigInt(keccak256(toUtf8Bytes(fullPath))) % secp256k1.Point.Fn.ORDER;
83
+ return BigInt(keccak256(toUtf8Bytes(fullPath))) % SECP256K1_ORDER;
84
+ }
85
+ /** Derive the child public key as a noble curve point (internal shape). */
86
+ function deriveChildPoint(mpcSecp256k1PubkeyHex, requester, path, chainId) {
87
+ const epsilon = deriveEpsilon(requester, path, chainId);
49
88
  const rootPubKeyHex = SigningKey.computePublicKey(mpcSecp256k1PubkeyHex, false);
50
89
  const rootPoint = secp256k1.Point.fromHex(rootPubKeyHex.slice(2));
51
- const derivedPoint = epsilon === 0n ? rootPoint : rootPoint.add(secp256k1.Point.BASE.multiply(epsilon));
52
- return computeAddress(`0x${derivedPoint.toHex(false)}`);
90
+ return epsilon === 0n ? rootPoint : rootPoint.add(secp256k1.Point.BASE.multiply(epsilon));
91
+ }
92
+ /**
93
+ * Normalise a Midnight contract address for use as the requester component
94
+ * of the derivation string: strip an optional `0x` prefix and lowercase.
95
+ * Both sides of the protocol (the deploy pinning a key and the MPC signing
96
+ * with it) derive through this, so the rendering always agrees.
97
+ */
98
+ function normaliseRequesterAddress(contractAddress) {
99
+ const hex = contractAddress.startsWith("0x") || contractAddress.startsWith("0X")
100
+ ? contractAddress.slice(2)
101
+ : contractAddress;
102
+ return hex.toLowerCase();
103
+ }
104
+ /**
105
+ * Derive the MPC's respond-bidirectional RESPONSE key for a signet
106
+ * deployment, public side: what client-contract deploys pin
107
+ * (`MPC_RESPONSE_KEY`) and what response verification checks against. See
108
+ * {@link MIDNIGHT_RESPOND_BIDIRECTIONAL_PATH} for the scheme and why the
109
+ * requester is the signet singleton's address.
110
+ *
111
+ * @param mpcSecp256k1PubkeyHex - The MPC root secp256k1 public key as 0x-hex
112
+ * (compressed or uncompressed).
113
+ * @param signetContractAddress - The signet singleton's Midnight contract
114
+ * address (`0x` prefix optional, case-insensitive).
115
+ * @returns The response public key as a Compact-runtime `Secp256k1Point`.
116
+ */
117
+ export function deriveMidnightResponseKey(mpcSecp256k1PubkeyHex, signetContractAddress) {
118
+ const point = deriveChildPoint(mpcSecp256k1PubkeyHex, normaliseRequesterAddress(signetContractAddress), MIDNIGHT_RESPOND_BIDIRECTIONAL_PATH, MIDNIGHT_TESTNET_CHAIN_ID);
119
+ return { x: point.x, y: point.y, identity: false };
120
+ }
121
+ /**
122
+ * Derive the MPC's respond-bidirectional RESPONSE key for a signet
123
+ * deployment, secret side: `(rootSecret + epsilon) mod n`. MPC-side only
124
+ * (the fakenet signer, test harnesses): a real client never holds the root
125
+ * key. The result feeds `signAttestationDigest` directly.
126
+ *
127
+ * @param mpcRootSecretKey - The 32-byte MPC root secret key (big-endian, the
128
+ * standard secp256k1 encoding).
129
+ * @param signetContractAddress - The signet singleton's Midnight contract
130
+ * address (`0x` prefix optional, case-insensitive).
131
+ * @returns The 32-byte response secret key (big-endian).
132
+ * @throws Error if the root key is not 32 bytes or the derived scalar is 0.
133
+ */
134
+ export function deriveMidnightResponseSecretKey(mpcRootSecretKey, signetContractAddress) {
135
+ if (mpcRootSecretKey.length !== 32) {
136
+ throw new Error(`MPC root secret key must be 32 bytes, got ${mpcRootSecretKey.length}`);
137
+ }
138
+ let root = 0n;
139
+ for (const byte of mpcRootSecretKey) {
140
+ root = (root << 8n) | BigInt(byte);
141
+ }
142
+ const epsilon = deriveEpsilon(normaliseRequesterAddress(signetContractAddress), MIDNIGHT_RESPOND_BIDIRECTIONAL_PATH, MIDNIGHT_TESTNET_CHAIN_ID);
143
+ const child = (root + epsilon) % SECP256K1_ORDER;
144
+ if (child === 0n) {
145
+ throw new Error("derived response secret key is zero (invalid scalar)");
146
+ }
147
+ const out = new Uint8Array(32);
148
+ let value = child;
149
+ for (let i = 31; i >= 0; i--) {
150
+ out[i] = Number(value & 0xffn);
151
+ value >>= 8n;
152
+ }
153
+ return out;
53
154
  }
54
155
  //# sourceMappingURL=epsilon-derivation.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"epsilon-derivation.js","sourceRoot":"","sources":["../src/epsilon-derivation.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,EAAE;AACF,6EAA6E;AAC7E,+EAA+E;AAC/E,uDAAuD;AACvD,0EAA0E;AAC1E,uEAAuE;AACvE,oDAAoD;AACpD,4EAA4E;AAC5E,yEAAyE;AACzE,sBAAsB;AAEtB,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAE5E;;;;GAIG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,uCAAuC,CAAC;AAEjF;;;GAGG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,kBAAkB,CAAC;AAE5D;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,gBAAgB,CAC9B,qBAA6B,EAC7B,eAAuB,EACvB,IAAY,EACZ,UAAkB,yBAAyB;IAE3C,MAAM,QAAQ,GAAG,GAAG,yBAAyB,IAAI,OAAO,IAAI,eAAe,IAAI,IAAI,EAAE,CAAC;IACtF,6EAA6E;IAC7E,iDAAiD;IACjD,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC;IACpF,MAAM,aAAa,GAAG,UAAU,CAAC,gBAAgB,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;IAChF,MAAM,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAClE,MAAM,YAAY,GAAG,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;IACxG,OAAO,cAAc,CAAC,KAAK,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;AAC1D,CAAC"}
1
+ {"version":3,"file":"epsilon-derivation.js","sourceRoot":"","sources":["../src/epsilon-derivation.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -8,16 +8,18 @@ export * from "./signet-request-resolver.ts";
8
8
  export * from "./signet-request-feed.ts";
9
9
  export * from "./constants.ts";
10
10
  export * from "./epsilon-derivation.ts";
11
- export * from "./schnorr.ts";
11
+ export * from "./ecdsa-attestation.ts";
12
12
  /**
13
13
  * Compiled pure circuits of Signet.compact (run `yarn compile` first): the
14
14
  * executable reference implementation of the client-agnostic circuits —
15
- * path<->identity checks, the attestation message, the notification packer
16
- * (`constructSignBidirectionalNotificationV1`), and the Schnorr challenge.
17
- * Off-chain code MUST use these instead of re-porting the algorithms — they
18
- * are the same compiled logic the contracts prove. The generic request
19
- * circuits cannot be compiled here (type-parameterized): request construction
20
- * is contract-only, and request-id hashing has a documented-deviation TS twin
15
+ * the attestation digest (`signetAttestationDigest`), response verification
16
+ * (`verifyRespondBidirectionalEvent`), the deploy-time key pin
17
+ * (`signetKeyHash`), and the notification packer
18
+ * (`constructSignBidirectionalEventNotificationV1`). Off-chain code MUST use
19
+ * these instead of re-porting the algorithms — they are the same compiled
20
+ * logic the contracts prove. The generic request circuits cannot be compiled
21
+ * here (type-parameterized): request construction is contract-only, and
22
+ * request-id hashing has a documented-deviation TS twin
21
23
  * (`calculateRequestId` in signet-requests.ts).
22
24
  */
23
25
  export { pureCircuits, type PureCircuits } from "./managed/contract/index.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,cAAc,sBAAsB,CAAC;AACrC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sCAAsC,CAAC;AACrD,cAAc,mCAAmC,CAAC;AAClD,cAAc,sCAAsC,CAAC;AACrD,cAAc,qCAAqC,CAAC;AACpD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,0BAA0B,CAAC;AACzC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,yBAAyB,CAAC;AACxC,cAAc,cAAc,CAAC;AAE7B;;;;;;;;;;GAUG;AACH,OAAO,EAAE,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,cAAc,sBAAsB,CAAC;AACrC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sCAAsC,CAAC;AACrD,cAAc,mCAAmC,CAAC;AAClD,cAAc,sCAAsC,CAAC;AACrD,cAAc,qCAAqC,CAAC;AACpD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,0BAA0B,CAAC;AACzC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AAEvC;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,6BAA6B,CAAC"}
package/dist/index.js CHANGED
@@ -11,16 +11,18 @@ export * from "./signet-request-resolver.js";
11
11
  export * from "./signet-request-feed.js";
12
12
  export * from "./constants.js";
13
13
  export * from "./epsilon-derivation.js";
14
- export * from "./schnorr.js";
14
+ export * from "./ecdsa-attestation.js";
15
15
  /**
16
16
  * Compiled pure circuits of Signet.compact (run `yarn compile` first): the
17
17
  * executable reference implementation of the client-agnostic circuits —
18
- * path<->identity checks, the attestation message, the notification packer
19
- * (`constructSignBidirectionalNotificationV1`), and the Schnorr challenge.
20
- * Off-chain code MUST use these instead of re-porting the algorithms — they
21
- * are the same compiled logic the contracts prove. The generic request
22
- * circuits cannot be compiled here (type-parameterized): request construction
23
- * is contract-only, and request-id hashing has a documented-deviation TS twin
18
+ * the attestation digest (`signetAttestationDigest`), response verification
19
+ * (`verifyRespondBidirectionalEvent`), the deploy-time key pin
20
+ * (`signetKeyHash`), and the notification packer
21
+ * (`constructSignBidirectionalEventNotificationV1`). Off-chain code MUST use
22
+ * these instead of re-porting the algorithms — they are the same compiled
23
+ * logic the contracts prove. The generic request circuits cannot be compiled
24
+ * here (type-parameterized): request construction is contract-only, and
25
+ * request-id hashing has a documented-deviation TS twin
24
26
  * (`calculateRequestId` in signet-requests.ts).
25
27
  */
26
28
  export { pureCircuits } from "./managed/contract/index.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,4EAA4E;AAC5E,2DAA2D;AAE3D,cAAc,sBAAsB,CAAC;AACrC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sCAAsC,CAAC;AACrD,cAAc,mCAAmC,CAAC;AAClD,cAAc,sCAAsC,CAAC;AACrD,cAAc,qCAAqC,CAAC;AACpD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,0BAA0B,CAAC;AACzC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,yBAAyB,CAAC;AACxC,cAAc,cAAc,CAAC;AAE7B;;;;;;;;;;GAUG;AACH,OAAO,EAAE,YAAY,EAAqB,MAAM,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,4EAA4E;AAC5E,2DAA2D;AAE3D,cAAc,sBAAsB,CAAC;AACrC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sCAAsC,CAAC;AACrD,cAAc,mCAAmC,CAAC;AAClD,cAAc,sCAAsC,CAAC;AACrD,cAAc,qCAAqC,CAAC;AACpD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,0BAA0B,CAAC;AACzC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AAEvC;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,YAAY,EAAqB,MAAM,6BAA6B,CAAC"}