@sig-net/midnight 0.13.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -12
- package/dist/ecdsa-attestation.d.ts +29 -1
- package/dist/ecdsa-attestation.d.ts.map +1 -1
- package/dist/ecdsa-attestation.js +55 -0
- package/dist/ecdsa-attestation.js.map +1 -1
- package/dist/managed/compiler/contract-info.json +12 -8
- package/dist/managed/compiler/contract-manifest.json +8 -8
- package/dist/managed/contract/index.d.ts +10 -10
- package/dist/managed/contract/index.js +92 -84
- package/dist/managed/contract/index.js.map +1 -1
- package/dist/signature-requests-state-reader.d.ts +6 -5
- package/dist/signature-requests-state-reader.d.ts.map +1 -1
- package/dist/signature-requests-state-reader.js +17 -16
- package/dist/signature-requests-state-reader.js.map +1 -1
- package/dist/signature-state-reading.d.ts +17 -25
- package/dist/signature-state-reading.d.ts.map +1 -1
- package/dist/signature-state-reading.js +37 -57
- package/dist/signature-state-reading.js.map +1 -1
- package/dist/signet-contract-state-reader.d.ts +24 -18
- package/dist/signet-contract-state-reader.d.ts.map +1 -1
- package/dist/signet-contract-state-reader.js +42 -32
- package/dist/signet-contract-state-reader.js.map +1 -1
- package/dist/signet-request-resolver.d.ts +1 -1
- package/dist/signet-request-resolver.js +2 -2
- package/dist/signet-request-resolver.js.map +1 -1
- package/dist/signet-request-response-reader.d.ts +39 -14
- package/dist/signet-request-response-reader.d.ts.map +1 -1
- package/dist/signet-request-response-reader.js +38 -10
- package/dist/signet-request-response-reader.js.map +1 -1
- package/package.json +2 -2
- package/src/Signet.compact +102 -70
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ The client-agnostic [Sig Network](https://sig.network) protocol library for the
|
|
|
13
13
|
```compact
|
|
14
14
|
import "@sig-net/midnight/src/Signet";
|
|
15
15
|
```
|
|
16
|
-
- **Compiled pure circuits** (`pureCircuits`): the executable reference implementation of the client-agnostic circuits (the deploy-time key pin, the notification packer, the ABI word builders and readers). Off-chain code calls these compiled artefacts, so it always agrees with what the contracts prove. The attestation digest and response verification are not among them: their compiled circuits are fixed-width oracles used only by this package's tests, and the sanctioned off-chain path is the TypeScript twin (`calculateSignetAttestationDigest`
|
|
16
|
+
- **Compiled pure circuits** (`pureCircuits`): the executable reference implementation of the client-agnostic circuits (the deploy-time key pin, the notification packer, the ABI word builders and readers). Off-chain code calls these compiled artefacts, so it always agrees with what the contracts prove. The attestation digest and response verification are not among them: their compiled circuits are fixed-width oracles used only by this package's tests, and the sanctioned off-chain path is the TypeScript twin (`calculateSignetAttestationDigest`, and `verifyRespondBidirectionalSignature` for ordinary ECDSA verification against the expected MPC response key), which those tests pin against the oracles: byte-for-byte for the digest, verdict-for-verdict for the verification.
|
|
17
17
|
- **TypeScript twins of the wire structs** and signet request-id computation.
|
|
18
18
|
- **State readers, request feed and resolver**: poll the signet contract for pending requests and their signature / remote-execution responses.
|
|
19
19
|
- **Crypto helpers**: epsilon derivation and ECDSA attestation verification.
|
|
@@ -33,8 +33,10 @@ The flow comprises 5 steps:
|
|
|
33
33
|
1. Client calls a contract on Midnight which requests a signature for a transaction destined for a foreign chain. The signature is made with a key derived for the requesting contract (see [Derived keys](#derived-keys)).
|
|
34
34
|
2. The Sig Network MPC honours the request, generating the transaction signature and posting it back to Midnight.
|
|
35
35
|
3. Client extracts the signature, using it to submit the signed transaction to the foreign chain.
|
|
36
|
-
4. The Sig Network MPC observes the foreign transaction and posts an attestation of the execution back to Midnight: the attestation digest `keccak256(requestId || serializedOutput)
|
|
37
|
-
5. Client obtains the execution output off chain (it broadcast the transaction in step 3, so it can read the result), extracts the posted attestation and submits both back to the Midnight contract, which recomputes the digest from the output bytes and verifies the MPC's signature in-circuit against the contract's own response key (see [Derived keys](#derived-keys)), completing the foreign transaction execution.
|
|
36
|
+
4. The Sig Network MPC observes the foreign transaction and posts an attestation of the execution back to Midnight: its ECDSA signature over the attestation digest `keccak256(requestId || serializedOutput)`. Both the digest and the output itself travel off chain.
|
|
37
|
+
5. Client obtains the execution output off chain (see the output recovery note below: it broadcast the transaction in step 3, so it can read the result), extracts the posted attestation and submits both back to the Midnight contract, which recomputes the digest from the output bytes and verifies the MPC's signature in-circuit against the contract's own response key (see [Derived keys](#derived-keys)), completing the foreign transaction execution.
|
|
38
|
+
|
|
39
|
+
> **Output recovery:** how the client reads the execution output is chain-specific. For EVM chains it is the mined call's return data, extracted with `debug_traceTransaction` (callTracer, top call frame), the same RPC method the MPC observes executions with. Clients without trace access can fetch the raw output from the fakenet responder's helper API at `GET /responses/{requestId}` (served by [`ResponsesApi.ts`](https://github.com/sig-net/solana-signet-program/blob/fakenet-v0.8.0/fakenet-signer/src/server/ResponsesApi.ts), port 3040 in the local stack). The fetched bytes are untrusted until step 5's in-circuit signature verification.
|
|
38
40
|
|
|
39
41
|
## Derived keys
|
|
40
42
|
|
|
@@ -81,7 +83,7 @@ Set up your contract for integration with the Sig Network MPC's sign bidirection
|
|
|
81
83
|
|
|
82
84
|
Compile with the pinned toolchain (currently `compact update 0.33.0-rc.2`) and always pass `--feature-zkir-v3`: compiled output without it is not compatible with the ledger-9 matched stack (node, indexer, proof server).
|
|
83
85
|
|
|
84
|
-
2. Declare the required Sig Network protocol state in your ledger (plus recommended deployer identity and initialisation state). The event map can sit at ANY ledger field: each notification your contract registers
|
|
86
|
+
2. Declare the required Sig Network protocol state in your ledger (plus recommended deployer identity and initialisation state). The event map can sit at ANY ledger field: each notification your contract registers carries the map's resolved ledger-tree path (see [The request map's ledger-tree path](#the-request-maps-ledger-tree-path)), and the MPC reads the authenticated request from there.
|
|
85
87
|
|
|
86
88
|
```compact
|
|
87
89
|
// Required: Map of SignBidirectionalEvent signature requests, configured by transaction type.
|
|
@@ -139,6 +141,22 @@ Set up your contract for integration with the Sig Network MPC's sign bidirection
|
|
|
139
141
|
}
|
|
140
142
|
```
|
|
141
143
|
|
|
144
|
+
### The request map's ledger-tree path
|
|
145
|
+
|
|
146
|
+
Each notification must tell the MPC where your `signBidirectionalEventMap` sits in your contract's compiled on-chain state, so the MPC can read the authenticated request out of raw contract state. The location is a path in the state tree, passed to `constructSignBidirectionalEventNotificationV1` as two arguments:
|
|
147
|
+
|
|
148
|
+
- `requestsPathDepth`: the number of meaningful entries in the path (1 to 4).
|
|
149
|
+
- `requestsPath`: the path itself, zero padded to 4 entries.
|
|
150
|
+
|
|
151
|
+
The path shape comes from how compactc lays out state. The compiler packs a contract's public ledger fields into a tree whose array nodes hold at most 15 entries. With 15 or fewer fields, field N sits directly in the root array, at path `[N]` (depth 1). With more than 15 fields, the compiler groups the fields into segments of at most 15 (the remainder segment first) and the root array holds the segments. Each grouping adds one level to the tree and one entry to every field's path. A 20-field contract splits 5 + 15: field 4 sits at `[0, 4]` and field 19 sits at `[1, 14]` (depth 2).
|
|
152
|
+
|
|
153
|
+
Do not derive the path by hand: the compiler records it in your compiled artifacts. Compile your contract, then look up your map's `"index"` in `managed/<contract>/compiler/contract-info.json` (a bare number `4` means path `[4]`). The generated `managed/<contract>/contract/index.js` accessors walk the same indices, for example `state.asArray()[1].asArray()[14]` for a map recorded at `[1, 14]`. That path packs as `requestsPathDepth = 2` and `requestsPath = [1, 14, 0, 0]`.
|
|
154
|
+
|
|
155
|
+
The two caller contracts in the [sig-net/midnight-integration](https://github.com/sig-net/midnight-integration) repository are worked examples of each case:
|
|
156
|
+
|
|
157
|
+
- [`test-caller-contract`](https://github.com/sig-net/midnight-integration/tree/main/packages/test-caller-contract): the flat case, where its 8-field ledger stores the map at field 4, so notifications carry depth `1` and path `[4, 0, 0, 0]`.
|
|
158
|
+
- [`test-caller-contract-20-field`](https://github.com/sig-net/midnight-integration/tree/main/packages/test-caller-contract-20-field): the chunked case, where its 20 fields split 5 + 15, so the map at field 19 packs as depth `2` and path `[1, 14, 0, 0]`.
|
|
159
|
+
|
|
142
160
|
### Runtime
|
|
143
161
|
|
|
144
162
|
Each interaction with your contract that executes a transaction on a foreign chain runs these 5 steps.
|
|
@@ -156,8 +174,8 @@ const reader = new SignetRequestResponseReader({
|
|
|
156
174
|
// Address of YOUR deployed contract
|
|
157
175
|
requesterContractAddress: myContractAddress,
|
|
158
176
|
|
|
159
|
-
// signBidirectionalEventMap's
|
|
160
|
-
|
|
177
|
+
// signBidirectionalEventMap's ledger-tree path (see The request map's ledger-tree path)
|
|
178
|
+
requesterRequestsPath: [0],
|
|
161
179
|
|
|
162
180
|
// Address of the Signet singleton contract
|
|
163
181
|
signetContractAddress,
|
|
@@ -184,10 +202,15 @@ const expectedSigner = deriveEvmAddress(mpcRootPublicKey, myContractAddress, "my
|
|
|
184
202
|
signBidirectionalEventMap.insert(requestId, disclose(request));
|
|
185
203
|
|
|
186
204
|
// Notify the MPC of the SignBidirectionalEvent and the location of your signBidirectionalEventMap.
|
|
187
|
-
// The
|
|
205
|
+
// The map is at ledger field 0 (Setup step 2), so its path is [0] at depth 1
|
|
206
|
+
// (see The request map's ledger-tree path).
|
|
188
207
|
signetSigner.signBidirectional(
|
|
189
208
|
requestId,
|
|
190
|
-
constructSignBidirectionalEventNotificationV1(
|
|
209
|
+
constructSignBidirectionalEventNotificationV1(
|
|
210
|
+
kernel.self(),
|
|
211
|
+
1 as Uint<8>, // requestsPathDepth
|
|
212
|
+
[0, 0, 0, 0] as Vector<4, Uint<8>>, // requestsPath, zero padded
|
|
213
|
+
),
|
|
191
214
|
);
|
|
192
215
|
```
|
|
193
216
|
|
|
@@ -209,11 +232,15 @@ const expectedSigner = deriveEvmAddress(mpcRootPublicKey, myContractAddress, "my
|
|
|
209
232
|
await new JsonRpcProvider(foreignChainRpcUrl).broadcastTransaction(signedTx.serialized);
|
|
210
233
|
```
|
|
211
234
|
|
|
212
|
-
4. Poll the Signet singleton for the MPC's attestation of the remote execution output (posted once the MPC observes the transaction execute on the foreign chain). The event carries
|
|
235
|
+
4. Poll the Signet singleton for the MPC's attestation of the remote execution output (posted once the MPC observes the transaction execute on the foreign chain). The event carries the MPC's signature alone: both the attestation digest and the serialised output itself travel off chain (you broadcast the transaction in step 3, so you can read its result). The log is unauthenticated, so use the verifying getter, as in step 2: it recomputes the digest over the output you present and returns only a post whose signature verifies against your contract's response key.
|
|
213
236
|
|
|
214
237
|
```ts
|
|
215
|
-
const
|
|
216
|
-
|
|
238
|
+
const respondBidirectionalEvent = await reader.getVerifiedRespondBidirectionalEvent(
|
|
239
|
+
requestId,
|
|
240
|
+
serializedOutput,
|
|
241
|
+
mpcResponseKey,
|
|
242
|
+
);
|
|
243
|
+
// undefined: no attestation of that output posted yet, poll again.
|
|
217
244
|
```
|
|
218
245
|
|
|
219
246
|
5. Deliver the response and the serialised output to your contract, which recomputes the attestation digest, verifies the event in-circuit against the response key pinned in Setup step 3, and consumes the request. The width argument is the exact packed size of your respond serialisation schema (a single bool packs to 1 byte):
|
|
@@ -268,7 +295,7 @@ const calldata = EvmCalldata<2> {
|
|
|
268
295
|
};
|
|
269
296
|
```
|
|
270
297
|
|
|
271
|
-
The readers run the same rules in the other direction, rejecting any non-canonical word outright (no silent truncation or coercion). Note that the builders and readers apply to CALLDATA words only. The serialised output a settle circuit verifies (the explicit `serializedOutput` argument `verifyRespondBidirectionalEvent`
|
|
298
|
+
The readers run the same rules in the other direction, rejecting any non-canonical word outright (no silent truncation or coercion). Note that the builders and readers apply to CALLDATA words only. The serialised output a settle circuit verifies (the explicit `serializedOutput` argument `verifyRespondBidirectionalEvent` recomputes the attestation digest from) is NOT ABI words: it is the packed respond payload produced from the request's respond serialisation schema (a bool packs to 1 byte). The circuit reads it with a single stdlib `deserialize<T, N>` call, where `T` is a struct mirroring the schema and `N` is the schema's packed size. For an ERC20 `transfer`'s `bool` return under a one-field bool schema:
|
|
272
299
|
|
|
273
300
|
```compact
|
|
274
301
|
struct TransferResult {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Secp256k1Point } from "@midnight-ntwrk/compact-runtime";
|
|
2
2
|
import type { RequestId } from "./signet-requests.ts";
|
|
3
|
-
import type { MpcSignature } from "./signet-contract-state-reader.ts";
|
|
3
|
+
import type { MpcSignature, RespondBidirectionalEvent } from "./signet-contract-state-reader.ts";
|
|
4
4
|
export type { Secp256k1Point } from "@midnight-ntwrk/compact-runtime";
|
|
5
5
|
/** secp256k1 curve (group) order n. */
|
|
6
6
|
export declare const SECP256K1_ORDER: bigint;
|
|
@@ -148,4 +148,32 @@ export declare function secp256k1PublicKeyOf(secretKey: Uint8Array): Secp256k1Po
|
|
|
148
148
|
* @returns The 32-byte attestation digest.
|
|
149
149
|
*/
|
|
150
150
|
export declare function calculateSignetAttestationDigest(requestId: RequestId, serializedOutput: Uint8Array): Uint8Array;
|
|
151
|
+
/**
|
|
152
|
+
* Off-chain check of a posted respond-bidirectional attestation: recompute
|
|
153
|
+
* the attestation digest of `(requestId, serializedOutput)` and verify the
|
|
154
|
+
* event's ECDSA signature over it against `mpcResponseKey`.
|
|
155
|
+
*
|
|
156
|
+
* The event carries the signature alone, so this check is the ONLY way to
|
|
157
|
+
* tell a genuine post from garbage: the signet contract's log is
|
|
158
|
+
* unauthenticated and every post is stored unverified. Use it to sift the
|
|
159
|
+
* candidates {@link SignetRequestResponseReader.getRespondBidirectionalEvents}
|
|
160
|
+
* returns before handing one to a contract. It is the off-chain counterpart
|
|
161
|
+
* of the in-circuit `verifyRespondBidirectionalEvent` and answers the same
|
|
162
|
+
* question, so a post this accepts is the post that proves at claim time.
|
|
163
|
+
*
|
|
164
|
+
* Malformed records are garbage, not faults: a signature whose components
|
|
165
|
+
* have the wrong width, whose `r` is off-curve, or which simply does not
|
|
166
|
+
* verify all return `false` rather than throwing. High-`s` signatures are
|
|
167
|
+
* accepted, matching the in-circuit verification (which enforces no low-`s`
|
|
168
|
+
* policy) rather than the signer's own normalisation.
|
|
169
|
+
*
|
|
170
|
+
* @param requestId - The 32-byte request id the response answers.
|
|
171
|
+
* @param serializedOutput - The serialised execution output, exact unpadded bytes.
|
|
172
|
+
* @param event - The posted record to check, as read off the ledger.
|
|
173
|
+
* @param mpcResponseKey - The response key the requesting contract pinned:
|
|
174
|
+
* the MPC key derived for its address and the fixed "midnight response key"
|
|
175
|
+
* path (see {@link deriveMidnightResponseKey}).
|
|
176
|
+
* @returns Whether the post is a genuine attestation of that output.
|
|
177
|
+
*/
|
|
178
|
+
export declare function verifyRespondBidirectionalSignature(requestId: RequestId, serializedOutput: Uint8Array, event: RespondBidirectionalEvent, mpcResponseKey: Secp256k1Point): boolean;
|
|
151
179
|
//# sourceMappingURL=ecdsa-attestation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ecdsa-attestation.d.ts","sourceRoot":"","sources":["../src/ecdsa-attestation.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"ecdsa-attestation.d.ts","sourceRoot":"","sources":["../src/ecdsa-attestation.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,KAAK,EACV,YAAY,EACZ,yBAAyB,EAC1B,MAAM,mCAAmC,CAAC;AAI3C,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,CAQvD;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,UAAU,CAQrD;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAMzD;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAW3D;AAED;;;;;;GAMG;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;;;;;;;;;;;;;GAaG;AACH,wBAAgB,4BAA4B,CAAC,SAAS,EAAE,cAAc,GAAG,YAAY,CAmBpF;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,4BAA4B,CAAC,SAAS,EAAE,YAAY,GAAG,cAAc,CAapF;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;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,gCAAgC,CAC9C,SAAS,EAAE,SAAS,EACpB,gBAAgB,EAAE,UAAU,GAC3B,UAAU,CAIZ;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,mCAAmC,CACjD,SAAS,EAAE,SAAS,EACpB,gBAAgB,EAAE,UAAU,EAC5B,KAAK,EAAE,yBAAyB,EAChC,cAAc,EAAE,cAAc,GAC7B,OAAO,CAyBT"}
|
|
@@ -256,4 +256,59 @@ export function secp256k1PublicKeyOf(secretKey) {
|
|
|
256
256
|
export function calculateSignetAttestationDigest(requestId, serializedOutput) {
|
|
257
257
|
return ethers.getBytes(ethers.keccak256(ethers.concat([requestId, serializedOutput])));
|
|
258
258
|
}
|
|
259
|
+
/**
|
|
260
|
+
* Off-chain check of a posted respond-bidirectional attestation: recompute
|
|
261
|
+
* the attestation digest of `(requestId, serializedOutput)` and verify the
|
|
262
|
+
* event's ECDSA signature over it against `mpcResponseKey`.
|
|
263
|
+
*
|
|
264
|
+
* The event carries the signature alone, so this check is the ONLY way to
|
|
265
|
+
* tell a genuine post from garbage: the signet contract's log is
|
|
266
|
+
* unauthenticated and every post is stored unverified. Use it to sift the
|
|
267
|
+
* candidates {@link SignetRequestResponseReader.getRespondBidirectionalEvents}
|
|
268
|
+
* returns before handing one to a contract. It is the off-chain counterpart
|
|
269
|
+
* of the in-circuit `verifyRespondBidirectionalEvent` and answers the same
|
|
270
|
+
* question, so a post this accepts is the post that proves at claim time.
|
|
271
|
+
*
|
|
272
|
+
* Malformed records are garbage, not faults: a signature whose components
|
|
273
|
+
* have the wrong width, whose `r` is off-curve, or which simply does not
|
|
274
|
+
* verify all return `false` rather than throwing. High-`s` signatures are
|
|
275
|
+
* accepted, matching the in-circuit verification (which enforces no low-`s`
|
|
276
|
+
* policy) rather than the signer's own normalisation.
|
|
277
|
+
*
|
|
278
|
+
* @param requestId - The 32-byte request id the response answers.
|
|
279
|
+
* @param serializedOutput - The serialised execution output, exact unpadded bytes.
|
|
280
|
+
* @param event - The posted record to check, as read off the ledger.
|
|
281
|
+
* @param mpcResponseKey - The response key the requesting contract pinned:
|
|
282
|
+
* the MPC key derived for its address and the fixed "midnight response key"
|
|
283
|
+
* path (see {@link deriveMidnightResponseKey}).
|
|
284
|
+
* @returns Whether the post is a genuine attestation of that output.
|
|
285
|
+
*/
|
|
286
|
+
export function verifyRespondBidirectionalSignature(requestId, serializedOutput, event, mpcResponseKey) {
|
|
287
|
+
let signature;
|
|
288
|
+
try {
|
|
289
|
+
signature = mpcSignatureToEcdsaSignature(event.signature);
|
|
290
|
+
}
|
|
291
|
+
catch {
|
|
292
|
+
return false;
|
|
293
|
+
}
|
|
294
|
+
const digest = calculateSignetAttestationDigest(requestId, serializedOutput);
|
|
295
|
+
// Compact form the verifier takes: r || s big-endian, and the key as
|
|
296
|
+
// uncompressed SEC1 (0x04 || x || y).
|
|
297
|
+
const compactSignature = new Uint8Array(64);
|
|
298
|
+
compactSignature.set(bigintToBytes32BE(signature.r), 0);
|
|
299
|
+
compactSignature.set(bigintToBytes32BE(signature.s), 32);
|
|
300
|
+
const publicKey = new Uint8Array(65);
|
|
301
|
+
publicKey[0] = 0x04;
|
|
302
|
+
publicKey.set(bigintToBytes32BE(mpcResponseKey.x), 1);
|
|
303
|
+
publicKey.set(bigintToBytes32BE(mpcResponseKey.y), 33);
|
|
304
|
+
try {
|
|
305
|
+
return secp256k1.verify(compactSignature, digest, publicKey, {
|
|
306
|
+
prehash: false,
|
|
307
|
+
lowS: false,
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
catch {
|
|
311
|
+
return false;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
259
314
|
//# sourceMappingURL=ecdsa-attestation.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ecdsa-attestation.js","sourceRoot":"","sources":["../src/ecdsa-attestation.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,sEAAsE;AACtE,kEAAkE;AAClE,uEAAuE;AACvE,2EAA2E;AAC3E,kEAAkE;AAClE,6EAA6E;AAC7E,8EAA8E;AAC9E,2EAA2E;AAC3E,oEAAoE;AACpE,4DAA4D;AAC5D,oCAAoC;AACpC,EAAE;AACF,wEAAwE;AACxE,8BAA8B;AAE9B,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"ecdsa-attestation.js","sourceRoot":"","sources":["../src/ecdsa-attestation.ts"],"names":[],"mappings":"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"}
|
|
@@ -25,11 +25,22 @@
|
|
|
25
25
|
}
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
|
-
"name": "
|
|
28
|
+
"name": "requestsPathDepth",
|
|
29
29
|
"type": {
|
|
30
30
|
"type-name": "Uint",
|
|
31
31
|
"maxval": 255
|
|
32
32
|
}
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"name": "requestsPath",
|
|
36
|
+
"type": {
|
|
37
|
+
"type-name": "Vector",
|
|
38
|
+
"length": 4,
|
|
39
|
+
"type": {
|
|
40
|
+
"type-name": "Uint",
|
|
41
|
+
"maxval": 255
|
|
42
|
+
}
|
|
43
|
+
}
|
|
33
44
|
}
|
|
34
45
|
],
|
|
35
46
|
"result-type": {
|
|
@@ -279,13 +290,6 @@
|
|
|
279
290
|
"type-name": "Struct",
|
|
280
291
|
"name": "RespondBidirectionalEvent",
|
|
281
292
|
"elements": [
|
|
282
|
-
{
|
|
283
|
-
"name": "attestationDigest",
|
|
284
|
-
"type": {
|
|
285
|
-
"type-name": "Bytes",
|
|
286
|
-
"length": 32
|
|
287
|
-
}
|
|
288
|
-
},
|
|
289
293
|
{
|
|
290
294
|
"name": "signature",
|
|
291
295
|
"type": {
|
|
@@ -7,26 +7,26 @@
|
|
|
7
7
|
"type": "directory",
|
|
8
8
|
"contract-info.json": {
|
|
9
9
|
"type": "file",
|
|
10
|
-
"size":
|
|
11
|
-
"hash": "
|
|
10
|
+
"size": 8200,
|
|
11
|
+
"hash": "07a63a0b166c651d4f9eb662029bacc81b0825311959ac67405d3996c064a84c"
|
|
12
12
|
}
|
|
13
13
|
},
|
|
14
14
|
"contract": {
|
|
15
15
|
"type": "directory",
|
|
16
16
|
"index.d.ts": {
|
|
17
17
|
"type": "file",
|
|
18
|
-
"size":
|
|
19
|
-
"hash": "
|
|
18
|
+
"size": 6518,
|
|
19
|
+
"hash": "9c63efc21d21c87c4a1989454c35158c8d783fd86131a5697edfd5e8f9db4bba"
|
|
20
20
|
},
|
|
21
21
|
"index.js": {
|
|
22
22
|
"type": "file",
|
|
23
|
-
"size":
|
|
24
|
-
"hash": "
|
|
23
|
+
"size": 49867,
|
|
24
|
+
"hash": "63808b43f8f0f7674971b1fe67ed6ef933004094fe48571969839dcdbbe1c589"
|
|
25
25
|
},
|
|
26
26
|
"index.js.map": {
|
|
27
27
|
"type": "file",
|
|
28
|
-
"size":
|
|
29
|
-
"hash": "
|
|
28
|
+
"size": 4763,
|
|
29
|
+
"hash": "f4f3622ea5f12911ee4ff19ffccf1b03d35f1c07a49ce0a48c1768d7903fc2d7"
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
}
|
|
@@ -12,9 +12,10 @@ export type ProvableCircuits<PS> = {
|
|
|
12
12
|
export type PureCircuits = {
|
|
13
13
|
constructSignBidirectionalEventNotificationV1(callerAddress_0: { bytes: Uint8Array
|
|
14
14
|
},
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
requestsPathDepth_0: bigint,
|
|
16
|
+
requestsPath_0: bigint[]): { version: bigint,
|
|
17
|
+
payload: Uint8Array
|
|
18
|
+
};
|
|
18
19
|
signetKeyHash(pk_0: __compactRuntime.Secp256k1Point): Uint8Array;
|
|
19
20
|
evmAddressAbiWord(addr_0: Uint8Array): Uint8Array;
|
|
20
21
|
numericAbiWord(value_0: bigint): Uint8Array;
|
|
@@ -29,8 +30,7 @@ export type PureCircuits = {
|
|
|
29
30
|
serializedOutput_0: Uint8Array): Uint8Array;
|
|
30
31
|
verifyRespondBidirectionalEvent32(requestId_0: Uint8Array,
|
|
31
32
|
serializedOutput_0: Uint8Array,
|
|
32
|
-
respondBidirectionalEvent_0: {
|
|
33
|
-
signature: { bigR: { x: Uint8Array,
|
|
33
|
+
respondBidirectionalEvent_0: { signature: { bigR: { x: Uint8Array,
|
|
34
34
|
y: Uint8Array
|
|
35
35
|
},
|
|
36
36
|
s: Uint8Array,
|
|
@@ -44,9 +44,10 @@ export type Circuits<PS> = {
|
|
|
44
44
|
constructSignBidirectionalEventNotificationV1(context: __compactRuntime.CircuitContext<PS>,
|
|
45
45
|
callerAddress_0: { bytes: Uint8Array
|
|
46
46
|
},
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
requestsPathDepth_0: bigint,
|
|
48
|
+
requestsPath_0: bigint[]): Promise<__compactRuntime.CircuitResults<PS, { version: bigint,
|
|
49
|
+
payload: Uint8Array
|
|
50
|
+
}>>;
|
|
50
51
|
signetKeyHash(context: __compactRuntime.CircuitContext<PS>,
|
|
51
52
|
pk_0: __compactRuntime.Secp256k1Point): Promise<__compactRuntime.CircuitResults<PS, Uint8Array>>;
|
|
52
53
|
evmAddressAbiWord(context: __compactRuntime.CircuitContext<PS>,
|
|
@@ -68,8 +69,7 @@ export type Circuits<PS> = {
|
|
|
68
69
|
verifyRespondBidirectionalEvent32(context: __compactRuntime.CircuitContext<PS>,
|
|
69
70
|
requestId_0: Uint8Array,
|
|
70
71
|
serializedOutput_0: Uint8Array,
|
|
71
|
-
respondBidirectionalEvent_0: {
|
|
72
|
-
signature: { bigR: { x: Uint8Array,
|
|
72
|
+
respondBidirectionalEvent_0: { signature: { bigR: { x: Uint8Array,
|
|
73
73
|
y: Uint8Array
|
|
74
74
|
},
|
|
75
75
|
s: Uint8Array,
|