@derec-alliance/nodejs 0.0.2 → 0.0.4
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 +49 -1
- package/derec_descriptor.bin +0 -0
- package/derec_library.d.ts +74 -14
- package/derec_library.js +118 -22
- package/derec_library_bg.wasm +0 -0
- package/derec_library_bg.wasm.d.ts +34 -31
- package/index.d.ts +439 -52
- package/index.js +67 -1
- package/package.json +3 -1
- package/proto/committedderecshare.proto +79 -0
- package/proto/communicationinfo.proto +104 -0
- package/proto/contact.proto +264 -0
- package/proto/derecmessage.proto +213 -0
- package/proto/derecsecret.proto +163 -0
- package/proto/derectransport.proto +38 -0
- package/proto/error.proto +60 -0
- package/proto/getshare.proto +194 -0
- package/proto/pair.proto +284 -0
- package/proto/parameterrange.proto +36 -0
- package/proto/prepair.proto +177 -0
- package/proto/result.proto +194 -0
- package/proto/secretidsversions.proto +209 -0
- package/proto/storeshare.proto +274 -0
- package/proto/transportprotocol.proto +100 -0
- package/proto/unpair.proto +140 -0
- package/proto/updatechannelinfo.proto +129 -0
- package/proto/verify.proto +170 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) DeRec Alliance and its Contributors.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
syntax = "proto3";
|
|
7
|
+
|
|
8
|
+
package org.derecalliance.derec.protobuf;
|
|
9
|
+
|
|
10
|
+
// Result represents the outcome of processing a DeRec protocol request.
|
|
11
|
+
//
|
|
12
|
+
// # Purpose
|
|
13
|
+
//
|
|
14
|
+
// This message is included in response messages to communicate:
|
|
15
|
+
//
|
|
16
|
+
// - whether a request was successfully processed
|
|
17
|
+
// - the type of failure (if any)
|
|
18
|
+
// - optional human-readable context for debugging or user display
|
|
19
|
+
//
|
|
20
|
+
// # Semantics
|
|
21
|
+
//
|
|
22
|
+
// A Result consists of:
|
|
23
|
+
//
|
|
24
|
+
// - a machine-readable `status` code
|
|
25
|
+
// - an optional `memo` providing additional context
|
|
26
|
+
//
|
|
27
|
+
// The `status` field MUST be used by implementations to determine
|
|
28
|
+
// protocol behavior. The `memo` field is informational only.
|
|
29
|
+
//
|
|
30
|
+
// # Usage
|
|
31
|
+
//
|
|
32
|
+
// - Every response message that can fail SHOULD include a Result
|
|
33
|
+
// - Senders MUST inspect the `status` field to determine next steps
|
|
34
|
+
// - The `memo` field MAY be displayed to users or logged for diagnostics
|
|
35
|
+
//
|
|
36
|
+
// # Security Considerations
|
|
37
|
+
//
|
|
38
|
+
// - The `memo` field SHOULD NOT include sensitive internal details
|
|
39
|
+
// - Only high-level or user-safe information should be exposed
|
|
40
|
+
//
|
|
41
|
+
// # Idempotency
|
|
42
|
+
//
|
|
43
|
+
// The Result reflects the outcome of a specific request. Repeated identical
|
|
44
|
+
// requests SHOULD produce consistent Result values unless system state changes.
|
|
45
|
+
message DeRecResult {
|
|
46
|
+
// Status code indicating the outcome of the request.
|
|
47
|
+
StatusEnum status = 1;
|
|
48
|
+
|
|
49
|
+
// Optional human-readable description providing additional details.
|
|
50
|
+
//
|
|
51
|
+
// This field is intended for debugging, logging, or user display.
|
|
52
|
+
// It MUST NOT be relied upon for programmatic decision-making.
|
|
53
|
+
string memo = 2;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// StatusEnum defines the set of possible outcomes for processing
|
|
57
|
+
// DeRec protocol requests.
|
|
58
|
+
//
|
|
59
|
+
// # Semantics
|
|
60
|
+
//
|
|
61
|
+
// These values are used across all response messages to provide a consistent
|
|
62
|
+
// interpretation of success and failure conditions.
|
|
63
|
+
//
|
|
64
|
+
// Implementations MUST handle all known values and SHOULD safely ignore
|
|
65
|
+
// unknown values for forward compatibility.
|
|
66
|
+
enum StatusEnum {
|
|
67
|
+
|
|
68
|
+
// The request was successfully handled.
|
|
69
|
+
//
|
|
70
|
+
// No further action is required by the sender.
|
|
71
|
+
OK = 0;
|
|
72
|
+
|
|
73
|
+
// The request was partially fulfilled.
|
|
74
|
+
//
|
|
75
|
+
// The `memo` field SHOULD provide additional context explaining which
|
|
76
|
+
// parts succeeded and which did not.
|
|
77
|
+
PARTIAL = 1;
|
|
78
|
+
|
|
79
|
+
// The request failed for a generic or unspecified reason.
|
|
80
|
+
//
|
|
81
|
+
// The `memo` field MAY provide additional details.
|
|
82
|
+
FAIL = 2;
|
|
83
|
+
|
|
84
|
+
// The request failed because it would exceed the allowed storage limit
|
|
85
|
+
// for this sharer and secret ID.
|
|
86
|
+
//
|
|
87
|
+
// This typically applies to share storage operations.
|
|
88
|
+
SIZE_LIMIT_EXCEEDED = 3;
|
|
89
|
+
|
|
90
|
+
// The request was ignored because it exceeded the allowed frequency.
|
|
91
|
+
//
|
|
92
|
+
// This may be used for rate limiting to prevent abuse or excessive load.
|
|
93
|
+
TOO_FREQUENT = 4;
|
|
94
|
+
|
|
95
|
+
// The specified secret ID is not recognized by the Helper.
|
|
96
|
+
//
|
|
97
|
+
// This may occur during recovery or share retrieval.
|
|
98
|
+
UNKNOWN_SECRET_ID = 5;
|
|
99
|
+
|
|
100
|
+
// The specified share version does not exist for the given secret ID.
|
|
101
|
+
//
|
|
102
|
+
// This may occur if the version was never stored or has been deleted.
|
|
103
|
+
UNKNOWN_SHARE_VERSION = 6;
|
|
104
|
+
|
|
105
|
+
// The message could not be decrypted successfully.
|
|
106
|
+
//
|
|
107
|
+
// This indicates a failure in the cryptographic layer, such as:
|
|
108
|
+
//
|
|
109
|
+
// - incorrect key material
|
|
110
|
+
// - corrupted ciphertext
|
|
111
|
+
DECRYPTION_FAILED = 7;
|
|
112
|
+
|
|
113
|
+
// The message signature or authentication could not be verified.
|
|
114
|
+
//
|
|
115
|
+
// This indicates that the message integrity or authenticity check failed.
|
|
116
|
+
VERIFICATION_FAILED = 8;
|
|
117
|
+
|
|
118
|
+
// The message format is invalid.
|
|
119
|
+
//
|
|
120
|
+
// This includes errors such as:
|
|
121
|
+
//
|
|
122
|
+
// - protobuf parsing failures
|
|
123
|
+
// - missing required fields
|
|
124
|
+
// - structurally invalid messages
|
|
125
|
+
FORMAT_ERROR = 9;
|
|
126
|
+
|
|
127
|
+
// The request was rejected by the counter-party
|
|
128
|
+
//
|
|
129
|
+
// This might be used to indicate the user or system that received the
|
|
130
|
+
// requested rejected it.
|
|
131
|
+
REJECTED = 10;
|
|
132
|
+
|
|
133
|
+
// The pair handshake failed because the two parties' advertised
|
|
134
|
+
// `ParameterRange` values do not overlap on at least one field
|
|
135
|
+
// (e.g. local `minShareSize` exceeds peer `maxShareSize`).
|
|
136
|
+
//
|
|
137
|
+
// Sent on a `PairResponseMessage`; the `memo` field SHOULD describe
|
|
138
|
+
// the offending field and the two `(min, max)` pairs so the
|
|
139
|
+
// initiator can surface a useful diagnostic.
|
|
140
|
+
INCOMPATIBLE_PARAMETER_RANGE = 11;
|
|
141
|
+
|
|
142
|
+
// The announced transport protocol is one the recipient cannot serve.
|
|
143
|
+
//
|
|
144
|
+
// Returned only for a transport change on an **already-established**
|
|
145
|
+
// channel — an `UpdateChannelInfo` announcing a switch the recipient
|
|
146
|
+
// cannot follow. The recipient still holds the peer's previous working
|
|
147
|
+
// endpoint, which is what makes this refusal deliverable at all.
|
|
148
|
+
//
|
|
149
|
+
// It is deliberately **not** used during pairing. Delivery is push-only,
|
|
150
|
+
// so a party that cannot reach a peer also cannot deliver a rejection to
|
|
151
|
+
// it; pairing incompatibility surfaces locally to the application
|
|
152
|
+
// instead.
|
|
153
|
+
UNSUPPORTED_TRANSPORT_PROTOCOL = 12;
|
|
154
|
+
|
|
155
|
+
// A share already exists for this (secretId, version) with different
|
|
156
|
+
// content, so the write was refused.
|
|
157
|
+
//
|
|
158
|
+
// Exactly one writer owns a version. A recipient stores the first write
|
|
159
|
+
// it sees at a version; a later write carrying different bytes is
|
|
160
|
+
// rejected with this status rather than overwriting or coexisting. A
|
|
161
|
+
// byte-identical re-send is an idempotent retry and returns `OK`.
|
|
162
|
+
//
|
|
163
|
+
// Because a single writer always derives `version` as
|
|
164
|
+
// `latest_version + 1`, it can never rewrite a version with different
|
|
165
|
+
// content. Receiving this status therefore means a *second* writer
|
|
166
|
+
// published concurrently — typically the same user acting on two
|
|
167
|
+
// devices at once. Resolution is the application's responsibility: the
|
|
168
|
+
// round has failed and should be republished at a new version.
|
|
169
|
+
VERSION_CONFLICT = 13;
|
|
170
|
+
|
|
171
|
+
// A replica pairing named a `replicaId` that is already in use by another
|
|
172
|
+
// member of the group — including the recipient itself.
|
|
173
|
+
//
|
|
174
|
+
// Every member of a group must be uniquely identified: the roster is keyed
|
|
175
|
+
// by `replicaId`, and messages between members are attributed by it. Two
|
|
176
|
+
// members sharing an id would overwrite each other's roster row and make
|
|
177
|
+
// every acknowledgement ambiguous.
|
|
178
|
+
//
|
|
179
|
+
// `replicaId` is assigned by the application, so a collision is a
|
|
180
|
+
// configuration fault — most often the same identity reused on two devices,
|
|
181
|
+
// such as a cloned device image. Resolution is the application's: assign a
|
|
182
|
+
// distinct id and pair again. The protocol cannot pick one, because it
|
|
183
|
+
// cannot know which device is meant to keep the original.
|
|
184
|
+
//
|
|
185
|
+
// Reported before fingerprint verification: there is no point asking a user
|
|
186
|
+
// to confirm a pairing that cannot be completed.
|
|
187
|
+
REPLICA_ID_CONFLICT = 14;
|
|
188
|
+
|
|
189
|
+
// The Helper is requesting that the Owner terminate the relationship.
|
|
190
|
+
//
|
|
191
|
+
// The Owner SHOULD respond by sending an UnpairRequestMessage and
|
|
192
|
+
// ceasing further communication on the channel.
|
|
193
|
+
REQUEST_TO_CLOSE = 99;
|
|
194
|
+
}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) DeRec Alliance and its Contributors.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
syntax = "proto3";
|
|
7
|
+
|
|
8
|
+
import "google/protobuf/timestamp.proto";
|
|
9
|
+
import "result.proto";
|
|
10
|
+
import "transportprotocol.proto";
|
|
11
|
+
|
|
12
|
+
package org.derecalliance.derec.protobuf;
|
|
13
|
+
|
|
14
|
+
// GetSecretIdsVersionsRequestMessage requests the list of all secrets and
|
|
15
|
+
// corresponding share versions that a Helper stores for a given Owner.
|
|
16
|
+
//
|
|
17
|
+
// # Context
|
|
18
|
+
//
|
|
19
|
+
// This message is used during the recovery flow, after the Owner has
|
|
20
|
+
// re-paired with a Helper (typically in recovery mode).
|
|
21
|
+
//
|
|
22
|
+
// Since the recovering Owner does not know which secrets or versions
|
|
23
|
+
// the Helper holds, this message allows discovery of:
|
|
24
|
+
//
|
|
25
|
+
// - all secretIds associated with the Owner
|
|
26
|
+
// - all share versions stored for each secret
|
|
27
|
+
//
|
|
28
|
+
// # Semantics
|
|
29
|
+
//
|
|
30
|
+
// The Helper responds with a GetSecretIdsVersionsResponseMessage containing:
|
|
31
|
+
//
|
|
32
|
+
// - one entry per secretId
|
|
33
|
+
// - the list of versions stored for each secret
|
|
34
|
+
//
|
|
35
|
+
// # Authorization Rules
|
|
36
|
+
//
|
|
37
|
+
// The Helper MUST only fully process this request if it is received through
|
|
38
|
+
// a communication channel that was established in recovery mode and has been
|
|
39
|
+
// associated (via authentication) with the same Owner as previously stored
|
|
40
|
+
// secrets.
|
|
41
|
+
//
|
|
42
|
+
// If this condition is not met, the Helper MAY:
|
|
43
|
+
//
|
|
44
|
+
// - return only partial information (e.g., for the current channel), or
|
|
45
|
+
// - reject the request entirely
|
|
46
|
+
//
|
|
47
|
+
// # Authentication
|
|
48
|
+
//
|
|
49
|
+
// The Helper MUST authenticate the requester at the application level before
|
|
50
|
+
// disclosing any information about stored secrets. Authentication is outside
|
|
51
|
+
// the scope of the protocol and may include:
|
|
52
|
+
//
|
|
53
|
+
// - in-person verification
|
|
54
|
+
// - KYC processes
|
|
55
|
+
// - biometrics or credentials
|
|
56
|
+
//
|
|
57
|
+
// # Idempotency
|
|
58
|
+
//
|
|
59
|
+
// This request is idempotent. Repeated requests SHOULD return the same
|
|
60
|
+
// information unless the underlying storage changes.
|
|
61
|
+
message GetSecretIdsVersionsRequestMessage {
|
|
62
|
+
// Timestamp indicating when this message was created.
|
|
63
|
+
//
|
|
64
|
+
// This value is expressed in UTC and can be used for:
|
|
65
|
+
//
|
|
66
|
+
// - observability and logging
|
|
67
|
+
// - replay detection (in combination with sequence numbers)
|
|
68
|
+
// - timeout handling
|
|
69
|
+
google.protobuf.Timestamp timestamp = 1;
|
|
70
|
+
|
|
71
|
+
// Ephemeral transport endpoint at which the requester wants to receive
|
|
72
|
+
// the response to *this exchange*, overriding the channel's stored peer
|
|
73
|
+
// endpoint for this round-trip only.
|
|
74
|
+
//
|
|
75
|
+
// See `StoreShareRequestMessage.replyTo` for full semantics.
|
|
76
|
+
//
|
|
77
|
+
// Superseded by `replyToTransports`, which carries every endpoint rather
|
|
78
|
+
// than one. Kept, and still populated with the list's first entry, so
|
|
79
|
+
// implementations predating that field still receive a reply.
|
|
80
|
+
// **Scheduled for removal in v0.0.5.** Reading this field directly is now
|
|
81
|
+
// incorrect — resolve it against `replyToTransports`.
|
|
82
|
+
optional TransportProtocol replyTo = 2 [deprecated = true];
|
|
83
|
+
|
|
84
|
+
// Every ephemeral endpoint the requester wants this exchange's response
|
|
85
|
+
// delivered to, in its own preference order.
|
|
86
|
+
//
|
|
87
|
+
// See `StoreShareRequestMessage.replyToTransports` for full semantics,
|
|
88
|
+
// including why this is a new tag rather than a widened `replyTo`.
|
|
89
|
+
repeated TransportProtocol replyToTransports = 4;
|
|
90
|
+
|
|
91
|
+
// Identity of the replica-group member this message concerns.
|
|
92
|
+
//
|
|
93
|
+
// Present **only** on the replica path, where a member drives catch-up
|
|
94
|
+
// against another member. Absent on the owner ↔ helper path, which is
|
|
95
|
+
// unchanged.
|
|
96
|
+
//
|
|
97
|
+
// Every member of a group is addressed on one shared `channel_id`, so the
|
|
98
|
+
// channel cannot name the peer — this field does. Its presence is also what
|
|
99
|
+
// tells the receiver which path a message belongs to.
|
|
100
|
+
optional uint64 replicaId = 3;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
// GetSecretIdsVersionsResponseMessage returns the list of all secrets and
|
|
105
|
+
// their corresponding share versions stored by the Helper for the Owner.
|
|
106
|
+
//
|
|
107
|
+
// # Semantics
|
|
108
|
+
//
|
|
109
|
+
// Each entry in `secretList` represents:
|
|
110
|
+
//
|
|
111
|
+
// - a `secretId` previously shared by the Owner
|
|
112
|
+
// - the list of share versions currently stored for that secret
|
|
113
|
+
//
|
|
114
|
+
// This allows the recovering Owner to:
|
|
115
|
+
//
|
|
116
|
+
// - discover which secrets exist
|
|
117
|
+
// - determine which versions to request via GetShareRequestMessage
|
|
118
|
+
//
|
|
119
|
+
// # Authorization and Privacy
|
|
120
|
+
//
|
|
121
|
+
// The Helper MUST ensure that:
|
|
122
|
+
//
|
|
123
|
+
// - the requester is authenticated as the same Owner
|
|
124
|
+
// - the request originates from a recovery-mode channel
|
|
125
|
+
//
|
|
126
|
+
// Only under these conditions may the Helper return the full list of secrets.
|
|
127
|
+
//
|
|
128
|
+
// Otherwise, the Helper MUST:
|
|
129
|
+
//
|
|
130
|
+
// - return partial data (e.g., only for the current secretId), or
|
|
131
|
+
// - return a failure result
|
|
132
|
+
//
|
|
133
|
+
// # Security Considerations
|
|
134
|
+
//
|
|
135
|
+
// - This message reveals metadata about stored secrets
|
|
136
|
+
// - It MUST only be sent over an authenticated and encrypted channel
|
|
137
|
+
// - Unauthorized disclosure could leak information about user activity
|
|
138
|
+
//
|
|
139
|
+
// # Idempotency
|
|
140
|
+
//
|
|
141
|
+
// For a given Helper state, repeated responses SHOULD return the same data.
|
|
142
|
+
message GetSecretIdsVersionsResponseMessage {
|
|
143
|
+
|
|
144
|
+
// Result of processing the request.
|
|
145
|
+
//
|
|
146
|
+
// Indicates whether the request was successfully processed or rejected.
|
|
147
|
+
DeRecResult result = 1;
|
|
148
|
+
|
|
149
|
+
// List of secrets and their stored versions.
|
|
150
|
+
//
|
|
151
|
+
// Each entry corresponds to one secretId and the versions available
|
|
152
|
+
// for that secret.
|
|
153
|
+
repeated VersionList secretList = 2;
|
|
154
|
+
|
|
155
|
+
// Timestamp indicating when this message was created.
|
|
156
|
+
//
|
|
157
|
+
// This value is expressed in UTC and can be used for:
|
|
158
|
+
//
|
|
159
|
+
// - observability and logging
|
|
160
|
+
// - replay detection (in combination with sequence numbers)
|
|
161
|
+
// - timeout handling
|
|
162
|
+
google.protobuf.Timestamp timestamp = 3;
|
|
163
|
+
|
|
164
|
+
// Identity of the replica-group member this message concerns.
|
|
165
|
+
//
|
|
166
|
+
// Present **only** on the replica path, where a member drives catch-up
|
|
167
|
+
// against another member. Absent on the owner ↔ helper path, which is
|
|
168
|
+
// unchanged.
|
|
169
|
+
//
|
|
170
|
+
// Every member of a group is addressed on one shared `channel_id`, so the
|
|
171
|
+
// channel cannot name the peer — this field does. Its presence is also what
|
|
172
|
+
// tells the receiver which path a message belongs to.
|
|
173
|
+
optional uint64 replicaId = 4;
|
|
174
|
+
|
|
175
|
+
// VersionList groups the share versions stored for a single secretId.
|
|
176
|
+
//
|
|
177
|
+
// # Semantics
|
|
178
|
+
//
|
|
179
|
+
// - `secretId` uniquely identifies a secret
|
|
180
|
+
// - `versions` lists all share versions currently stored for that secret,
|
|
181
|
+
// each paired with a human-readable description
|
|
182
|
+
//
|
|
183
|
+
// The order of versions is not significant unless defined by the
|
|
184
|
+
// implementation.
|
|
185
|
+
message VersionList {
|
|
186
|
+
// Identifier of the secret.
|
|
187
|
+
uint64 secretId = 1;
|
|
188
|
+
|
|
189
|
+
// List of share versions stored for this secret.
|
|
190
|
+
//
|
|
191
|
+
// Each entry carries the numeric version identifier together with the
|
|
192
|
+
// human-readable description that was supplied by the Owner when the
|
|
193
|
+
// share was stored. Descriptions help the recovering Owner identify
|
|
194
|
+
// which secret corresponds to which identifier without relying on
|
|
195
|
+
// raw bytes alone.
|
|
196
|
+
repeated VersionEntry versions = 2;
|
|
197
|
+
|
|
198
|
+
// One stored version of a secret, paired with its human-readable label.
|
|
199
|
+
message VersionEntry {
|
|
200
|
+
// Numeric version identifier.
|
|
201
|
+
uint32 version = 1;
|
|
202
|
+
|
|
203
|
+
// Human-readable description supplied by the Owner at share-storage time.
|
|
204
|
+
//
|
|
205
|
+
// May be empty if no description was provided.
|
|
206
|
+
string versionDescription = 2;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) DeRec Alliance and its Contributors.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
syntax = "proto3";
|
|
7
|
+
|
|
8
|
+
import "google/protobuf/timestamp.proto";
|
|
9
|
+
import "result.proto";
|
|
10
|
+
import "transportprotocol.proto";
|
|
11
|
+
|
|
12
|
+
package org.derecalliance.derec.protobuf;
|
|
13
|
+
|
|
14
|
+
// StoreShareRequestMessage instructs a Helper to store a share for a given
|
|
15
|
+
// secret and manage the set of retained share versions.
|
|
16
|
+
//
|
|
17
|
+
// # Context
|
|
18
|
+
//
|
|
19
|
+
// This message is used in the sharing flow when:
|
|
20
|
+
//
|
|
21
|
+
// - a new secret is created
|
|
22
|
+
// - an existing secret is updated
|
|
23
|
+
// - the helper set or recovery threshold changes
|
|
24
|
+
//
|
|
25
|
+
// The Owner sends this message to each Helper to:
|
|
26
|
+
//
|
|
27
|
+
// - store (or replace) a specific share version
|
|
28
|
+
// - update the set of versions that must be retained (keepList)
|
|
29
|
+
//
|
|
30
|
+
// # Semantics
|
|
31
|
+
//
|
|
32
|
+
// This message may carry two independent instructions:
|
|
33
|
+
//
|
|
34
|
+
// 1. Share storage/update:
|
|
35
|
+
// - If `share` is present, the Helper MUST store this share under the
|
|
36
|
+
// specified `version`
|
|
37
|
+
// - If the version already exists, the Helper MUST replace it
|
|
38
|
+
//
|
|
39
|
+
// 2. Retention policy update:
|
|
40
|
+
// - If `keepList` is present, it defines the complete set of versions
|
|
41
|
+
// that MUST be retained
|
|
42
|
+
// - Any stored version not in `keepList` SHOULD be deleted
|
|
43
|
+
//
|
|
44
|
+
// If `keepList` is absent:
|
|
45
|
+
//
|
|
46
|
+
// - The Helper MUST preserve the existing keepList
|
|
47
|
+
// - The Helper MUST add the new `version` to the retained set
|
|
48
|
+
//
|
|
49
|
+
// # Consistency Requirements
|
|
50
|
+
//
|
|
51
|
+
// The Owner MUST ensure that for a given (secretId, version):
|
|
52
|
+
//
|
|
53
|
+
// - all Helpers receive identical share contents
|
|
54
|
+
//
|
|
55
|
+
// It is an error for different shares to be associated with the same
|
|
56
|
+
// version and secretId.
|
|
57
|
+
//
|
|
58
|
+
// # Replay Protection
|
|
59
|
+
//
|
|
60
|
+
// To prevent replay attacks:
|
|
61
|
+
//
|
|
62
|
+
// - If `version` is less than the latest stored version,
|
|
63
|
+
// the Helper MUST ignore the `keepList` field
|
|
64
|
+
//
|
|
65
|
+
// This ensures that stale messages cannot cause deletion of newer shares.
|
|
66
|
+
//
|
|
67
|
+
// # Share Opacity
|
|
68
|
+
//
|
|
69
|
+
// The Helper MUST treat the `share` field as opaque data. It is not required
|
|
70
|
+
// to understand or validate the share contents.
|
|
71
|
+
//
|
|
72
|
+
// # Idempotency
|
|
73
|
+
//
|
|
74
|
+
// This message is idempotent:
|
|
75
|
+
//
|
|
76
|
+
// - Re-sending the same (version, share) pair SHOULD result in the same state
|
|
77
|
+
// - Re-applying the same keepList SHOULD not change state after the first time
|
|
78
|
+
message StoreShareRequestMessage {
|
|
79
|
+
|
|
80
|
+
// Share bytes to be stored by the Helper.
|
|
81
|
+
//
|
|
82
|
+
// This is an opaque byte array produced by the share distribution
|
|
83
|
+
// algorithm. The Helper MUST store it without interpretation.
|
|
84
|
+
bytes share = 1;
|
|
85
|
+
|
|
86
|
+
// Identifier of the algorithm used to produce the share.
|
|
87
|
+
//
|
|
88
|
+
// This allows the Owner and Helper to coordinate on how the share
|
|
89
|
+
// should be interpreted during recovery.
|
|
90
|
+
//
|
|
91
|
+
// Algorithm 0 defines the share as a serialized `CommittedDeRecShare`
|
|
92
|
+
// protobuf message (see DeRec cryptography repository).
|
|
93
|
+
//
|
|
94
|
+
// Implementations SHOULD support algorithm 0 for interoperability.
|
|
95
|
+
int32 shareAlgorithm = 2;
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
// Identifier of the secret to which this share belongs.
|
|
99
|
+
//
|
|
100
|
+
// Used by the Helper to associate the share with the correct secret in the
|
|
101
|
+
// share store under the composite key (channel_id, secret_id, version).
|
|
102
|
+
uint64 secretId = 3;
|
|
103
|
+
|
|
104
|
+
// Version number of the share.
|
|
105
|
+
//
|
|
106
|
+
// Each resharing event increments this value.
|
|
107
|
+
uint32 version = 4;
|
|
108
|
+
|
|
109
|
+
// List of share versions that MUST be retained by the Helper.
|
|
110
|
+
//
|
|
111
|
+
// Any stored version not included in this list SHOULD be deleted.
|
|
112
|
+
//
|
|
113
|
+
// If absent, the Helper MUST:
|
|
114
|
+
//
|
|
115
|
+
// - retain the existing keepList
|
|
116
|
+
// - add the current `version` to the retained set
|
|
117
|
+
//
|
|
118
|
+
// This field MUST be ignored if `version` is older than the latest
|
|
119
|
+
// version already stored, to prevent replay attacks.
|
|
120
|
+
repeated uint32 keepList = 5;
|
|
121
|
+
|
|
122
|
+
// Optional human-readable description of this share version.
|
|
123
|
+
//
|
|
124
|
+
// This field is visible to the Helper and is not intended to carry
|
|
125
|
+
// sensitive information. It may be used for debugging, labeling, or
|
|
126
|
+
// user-facing display.
|
|
127
|
+
string versionDescription = 6;
|
|
128
|
+
|
|
129
|
+
// Timestamp indicating when this message was created.
|
|
130
|
+
//
|
|
131
|
+
// Used for observability, replay detection, and timeout handling.
|
|
132
|
+
google.protobuf.Timestamp timestamp = 7;
|
|
133
|
+
|
|
134
|
+
// Ephemeral transport endpoints at which the requester wants to receive
|
|
135
|
+
// the response to *this exchange*, in its own preference order,
|
|
136
|
+
// overriding the channel's stored peer endpoints for this round-trip
|
|
137
|
+
// only.
|
|
138
|
+
//
|
|
139
|
+
// # When to use
|
|
140
|
+
//
|
|
141
|
+
// Set when the requester's outbound endpoint does not match the endpoint
|
|
142
|
+
// the responder has on file for the channel — for example a replica
|
|
143
|
+
// talking to a helper that was paired with a sibling replica. The
|
|
144
|
+
// responder routes the response here but does NOT persist these
|
|
145
|
+
// endpoints; use `UpdateChannelInfoRequestMessage` for permanent changes.
|
|
146
|
+
//
|
|
147
|
+
// # Semantics
|
|
148
|
+
//
|
|
149
|
+
// - Absent (the default): the responder routes to the endpoints stored on
|
|
150
|
+
// its `Channel` record for this `channelId`.
|
|
151
|
+
// - Present: the responder routes this exchange's response here, and
|
|
152
|
+
// leaves the stored endpoints unchanged.
|
|
153
|
+
//
|
|
154
|
+
// Superseded by `replyToTransports`, which carries every endpoint rather
|
|
155
|
+
// than one. Kept, and still populated with the list's first entry, so
|
|
156
|
+
// implementations predating that field still receive a reply.
|
|
157
|
+
// **Scheduled for removal in v0.0.5.**
|
|
158
|
+
//
|
|
159
|
+
// **Reading this field directly is now incorrect** for the same reason it
|
|
160
|
+
// is on `transportProtocol`: it is one entry of a list and may be absent.
|
|
161
|
+
// Resolve it against `replyToTransports` instead.
|
|
162
|
+
optional TransportProtocol replyTo = 8 [deprecated = true];
|
|
163
|
+
|
|
164
|
+
// Every ephemeral endpoint the requester wants this exchange's response
|
|
165
|
+
// delivered to, in its own preference order.
|
|
166
|
+
//
|
|
167
|
+
// # Semantics
|
|
168
|
+
//
|
|
169
|
+
// - Empty, and `replyTo` absent: the responder routes to the endpoints
|
|
170
|
+
// stored on its `Channel` record for this `channelId`.
|
|
171
|
+
// - Empty, `replyTo` present: that one endpoint, which is how every
|
|
172
|
+
// implementation predating this field asks.
|
|
173
|
+
// - Non-empty: the responder routes the response to any one of these, in
|
|
174
|
+
// the order given, and leaves the stored endpoints unchanged. Delivery
|
|
175
|
+
// to any one is success.
|
|
176
|
+
//
|
|
177
|
+
// # Why this is a new field rather than a wider `replyTo`
|
|
178
|
+
//
|
|
179
|
+
// `replyTo` was singular through 0.0.2. Re-tagging it `repeated` would
|
|
180
|
+
// have been wire-compatible in the read direction only: protobuf merges a
|
|
181
|
+
// repeated submessage into a singular reader field-by-field, so a 0.0.2
|
|
182
|
+
// peer decoding a multi-entry list sees the **last** entry, while the
|
|
183
|
+
// first entry is what every other compatibility rule in this release
|
|
184
|
+
// designates as the legacy-readable one. One list cannot be ordered to
|
|
185
|
+
// satisfy both. A new tag lets the singular field keep meaning exactly
|
|
186
|
+
// what it did — the same shape `supportedTransports` (contact.proto tag 9)
|
|
187
|
+
// uses beside `transportProtocol` (tag 7).
|
|
188
|
+
repeated TransportProtocol replyToTransports = 10;
|
|
189
|
+
|
|
190
|
+
// Identity of the replica that authored this update.
|
|
191
|
+
//
|
|
192
|
+
// # Audience
|
|
193
|
+
//
|
|
194
|
+
// This field is for **replicas only**. Helpers know nothing about
|
|
195
|
+
// replicas and never receive it:
|
|
196
|
+
//
|
|
197
|
+
// - helper-bound (`SHARE_ALGORITHM_VSS`) — MUST be absent.
|
|
198
|
+
// - replica-bound (`SHARE_ALGORITHM_REPLICA_SECRET`) — MUST be present.
|
|
199
|
+
//
|
|
200
|
+
// The invariant is `replicaId.is_some() == (shareAlgorithm ==
|
|
201
|
+
// SHARE_ALGORITHM_REPLICA_SECRET)`, asserted on send and on receive; a
|
|
202
|
+
// violation is a protocol error, not a tolerated variation.
|
|
203
|
+
//
|
|
204
|
+
// # Why the receiver needs it
|
|
205
|
+
//
|
|
206
|
+
// Every member of a replica group shares one `channelId`, so the
|
|
207
|
+
// channel identifies the *group*, not the sender. The channel's
|
|
208
|
+
// counterparty says who established it, which after admission by a
|
|
209
|
+
// third member is not who wrote this message. Author attribution
|
|
210
|
+
// therefore comes from this field and never from the channel record.
|
|
211
|
+
//
|
|
212
|
+
// Applications use it to resolve which member published an update, and
|
|
213
|
+
// to route the response back to that member's endpoint.
|
|
214
|
+
//
|
|
215
|
+
// # Out of scope for the protocol
|
|
216
|
+
//
|
|
217
|
+
// The protocol does not authenticate the claim; anyone holding the
|
|
218
|
+
// group key may write any `replicaId`. It is an identifier, not an
|
|
219
|
+
// authenticator.
|
|
220
|
+
optional uint64 replicaId = 9;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// StoreShareResponseMessage is the response to a StoreShareRequestMessage.
|
|
224
|
+
//
|
|
225
|
+
// # Semantics
|
|
226
|
+
//
|
|
227
|
+
// This message indicates whether the Helper successfully:
|
|
228
|
+
//
|
|
229
|
+
// - stored or updated the requested share version
|
|
230
|
+
// - applied the retention policy (keepList)
|
|
231
|
+
//
|
|
232
|
+
// # Idempotency
|
|
233
|
+
//
|
|
234
|
+
// Multiple identical requests SHOULD produce identical responses.
|
|
235
|
+
message StoreShareResponseMessage {
|
|
236
|
+
|
|
237
|
+
// Result of processing the request.
|
|
238
|
+
//
|
|
239
|
+
// Indicates success or failure of the storage/update operation.
|
|
240
|
+
DeRecResult result = 1;
|
|
241
|
+
|
|
242
|
+
// Identifier of the secret to which this response refers.
|
|
243
|
+
//
|
|
244
|
+
// Echoed from the corresponding StoreShareRequestMessage so the Owner can
|
|
245
|
+
// correlate responses with the correct secret without inspecting the share
|
|
246
|
+
// bytes.
|
|
247
|
+
uint64 secretId = 2;
|
|
248
|
+
|
|
249
|
+
// Version number from the corresponding request.
|
|
250
|
+
//
|
|
251
|
+
// This allows the sender to correlate responses with requests.
|
|
252
|
+
uint32 version = 3;
|
|
253
|
+
|
|
254
|
+
// Timestamp indicating when this message was created.
|
|
255
|
+
//
|
|
256
|
+
// Used for observability, replay detection, and timeout handling.
|
|
257
|
+
google.protobuf.Timestamp timestamp = 4;
|
|
258
|
+
|
|
259
|
+
// Identity of the replica that produced this response.
|
|
260
|
+
//
|
|
261
|
+
// Present only when the corresponding request was replica-bound
|
|
262
|
+
// (`shareAlgorithm == SHARE_ALGORITHM_REPLICA_SECRET`); absent on
|
|
263
|
+
// helper responses, which carry no replica identity in either
|
|
264
|
+
// direction.
|
|
265
|
+
//
|
|
266
|
+
// # Why the requester needs it
|
|
267
|
+
//
|
|
268
|
+
// Every member of a replica group answers on the same `channelId`, and
|
|
269
|
+
// `secretId` and `version` are echoed identically by all of them. Two
|
|
270
|
+
// members responding to one publish are otherwise indistinguishable —
|
|
271
|
+
// the requester cannot tell whether both acknowledged or one
|
|
272
|
+
// acknowledged twice, and so cannot track a sharing round per member.
|
|
273
|
+
optional uint64 replicaId = 5;
|
|
274
|
+
}
|