@derec-alliance/nodejs 0.0.3 → 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 +18 -0
- package/derec_descriptor.bin +0 -0
- package/derec_library_bg.wasm +0 -0
- 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
package/README.md
CHANGED
|
@@ -29,6 +29,24 @@ No native dependencies are required.
|
|
|
29
29
|
|
|
30
30
|
---
|
|
31
31
|
|
|
32
|
+
## Protocol schema
|
|
33
|
+
|
|
34
|
+
The package ships the DeRec `.proto` schema at its root so you can generate
|
|
35
|
+
code for any language without a `lib-derec` checkout:
|
|
36
|
+
|
|
37
|
+
- `proto/` — the 18 schema files, flat. Every import is a bare filename, so a
|
|
38
|
+
single include root resolves the whole closure:
|
|
39
|
+
`protoc --proto_path=node_modules/@derec-alliance/nodejs/proto node_modules/@derec-alliance/nodejs/proto/*.proto`
|
|
40
|
+
- `derec_descriptor.bin` — the same closure precompiled, well-known types
|
|
41
|
+
included. Needs no include path at all. Compiled with
|
|
42
|
+
`--include_source_info`, so code generated from it keeps the protocol's doc
|
|
43
|
+
comments instead of emitting bare type declarations.
|
|
44
|
+
|
|
45
|
+
The schema is versioned with the package: `vX.Y.Z` carries exactly the schema
|
|
46
|
+
`vX.Y.Z` was built from.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
32
50
|
## Design Overview
|
|
33
51
|
|
|
34
52
|
The NodeJS SDK is a **thin binding layer** over the Rust implementation.
|
|
Binary file
|
package/derec_library_bg.wasm
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@derec-alliance/nodejs",
|
|
3
3
|
"description": "Node.js WebAssembly bindings for derec-library, the Rust SDK for the DeRec protocol.",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.4",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
"derec_library.d.ts",
|
|
15
15
|
"index.js",
|
|
16
16
|
"index.d.ts",
|
|
17
|
+
"proto",
|
|
18
|
+
"derec_descriptor.bin",
|
|
17
19
|
"README.md",
|
|
18
20
|
"LICENSE"
|
|
19
21
|
],
|
|
@@ -0,0 +1,79 @@
|
|
|
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
|
+
// CommittedDeRecShare represents a DeRec share that has been committed and
|
|
11
|
+
// is ready to be given to a helper for storage.
|
|
12
|
+
//
|
|
13
|
+
// During recovery, this protobuf message is returned.
|
|
14
|
+
//
|
|
15
|
+
// The commitment uses a Merkle tree. The hash of the share given to each
|
|
16
|
+
// helper forms a leaf in the tree. Each leaf and internal node hash is a
|
|
17
|
+
// SHA-384 hash.
|
|
18
|
+
//
|
|
19
|
+
// The Merkle path from a leaf to the root (i.e., the sibling nodes along
|
|
20
|
+
// that route) is called merklePath. The root hash is referred to as the
|
|
21
|
+
// "commitment".
|
|
22
|
+
message CommittedDeRecShare {
|
|
23
|
+
|
|
24
|
+
// Protobuf serialization of DeRecShare.
|
|
25
|
+
bytes deRecShare = 1;
|
|
26
|
+
|
|
27
|
+
// The Merkle root.
|
|
28
|
+
bytes commitment = 2;
|
|
29
|
+
|
|
30
|
+
// Represents a leaf or interior node in the Merkle path.
|
|
31
|
+
// isLeft is true if the sibling is a left child.
|
|
32
|
+
message SiblingHash {
|
|
33
|
+
bool isLeft = 1;
|
|
34
|
+
bytes hash = 2;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// The bottom-up Merkle path from the leaf to the root.
|
|
38
|
+
repeated SiblingHash merklePath = 3;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
// DeRecShare contains the information that a sharer provides to a helper.
|
|
43
|
+
//
|
|
44
|
+
// The sharer first generates a random AES-256 key k and uses it to
|
|
45
|
+
// AES-GCM encrypt the secret. A random polynomial f is generated such
|
|
46
|
+
// that f(0) = k. The polynomial is then evaluated at a random x value
|
|
47
|
+
// for the intended helper, and the share contains the value y where
|
|
48
|
+
// f(x) = y.
|
|
49
|
+
//
|
|
50
|
+
// The computation should be done in GF(p), where p is the smallest
|
|
51
|
+
// 256-bit prime. The degree of the polynomial determines the threshold
|
|
52
|
+
// number of helpers required to reconstruct the secret.
|
|
53
|
+
//
|
|
54
|
+
// The message also includes the secretId and the share version number,
|
|
55
|
+
// because they must be serialized together with the share so that they
|
|
56
|
+
// are covered by the same signature.
|
|
57
|
+
message DeRecShare {
|
|
58
|
+
|
|
59
|
+
// The result of serializing the secret to be shared and encrypting it
|
|
60
|
+
// with a randomly generated AES-256 key.
|
|
61
|
+
bytes encryptedSecret = 1;
|
|
62
|
+
|
|
63
|
+
// Random 256-bit integer encoded as two's complement, big-endian.
|
|
64
|
+
bytes x = 2;
|
|
65
|
+
|
|
66
|
+
// The value y = f(x).
|
|
67
|
+
bytes y = 3;
|
|
68
|
+
|
|
69
|
+
// Numeric identifier of the secret associated with the share.
|
|
70
|
+
//
|
|
71
|
+
// Must be unique for each secret created by a sharer.
|
|
72
|
+
uint64 secretId = 4;
|
|
73
|
+
|
|
74
|
+
// Version number of the share.
|
|
75
|
+
//
|
|
76
|
+
// A helper is entitled to ignore any StoreShareRequestMessage whose
|
|
77
|
+
// version is less than or equal to the last seen version.
|
|
78
|
+
uint32 version = 5;
|
|
79
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
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
|
+
// CommunicationInfoKeyValue represents a single application-defined
|
|
11
|
+
// key-value pair used to convey user-facing identification data.
|
|
12
|
+
//
|
|
13
|
+
// # Purpose
|
|
14
|
+
//
|
|
15
|
+
// This structure is intended for:
|
|
16
|
+
//
|
|
17
|
+
// - displaying human-readable information to users during pairing
|
|
18
|
+
// - helping users identify and confirm counterparties
|
|
19
|
+
// - providing contextual metadata for UI/UX purposes
|
|
20
|
+
//
|
|
21
|
+
// # Semantics
|
|
22
|
+
//
|
|
23
|
+
// - The `key` is an application-defined identifier (e.g., "name", "phone")
|
|
24
|
+
// - The `value` contains the associated data, either as a string or raw bytes
|
|
25
|
+
//
|
|
26
|
+
// The protocol does not interpret these fields; they are opaque to the
|
|
27
|
+
// DeRec protocol and are only intended for application-level use.
|
|
28
|
+
//
|
|
29
|
+
// # Encoding
|
|
30
|
+
//
|
|
31
|
+
// Exactly one of the `value` fields MUST be set.
|
|
32
|
+
//
|
|
33
|
+
// Implementations SHOULD:
|
|
34
|
+
//
|
|
35
|
+
// - prefer `stringValue` for human-readable data
|
|
36
|
+
// - use `bytesValue` for structured or binary data (e.g., encoded identifiers)
|
|
37
|
+
//
|
|
38
|
+
// # Interoperability
|
|
39
|
+
//
|
|
40
|
+
// Applications SHOULD use consistent and well-known keys where possible
|
|
41
|
+
// (e.g., "name", "email", "phone") to improve cross-implementation UX,
|
|
42
|
+
// but no global registry is enforced by the protocol.
|
|
43
|
+
message CommunicationInfoKeyValue {
|
|
44
|
+
// Application-defined key identifying the type of information.
|
|
45
|
+
//
|
|
46
|
+
// Examples include "name", "email", "phone", or "accountId".
|
|
47
|
+
string key = 1;
|
|
48
|
+
|
|
49
|
+
// Value associated with the key.
|
|
50
|
+
//
|
|
51
|
+
// Exactly one of the following fields MUST be set.
|
|
52
|
+
oneof value {
|
|
53
|
+
// Human-readable string value.
|
|
54
|
+
//
|
|
55
|
+
// This is the preferred representation for most user-facing data.
|
|
56
|
+
string stringValue = 2;
|
|
57
|
+
|
|
58
|
+
// Binary value.
|
|
59
|
+
//
|
|
60
|
+
// May be used for structured or encoded data that is not naturally
|
|
61
|
+
// represented as a string.
|
|
62
|
+
bytes bytesValue = 3;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// CommunicationInfo contains application-level identifying information
|
|
67
|
+
// about a participant (Owner or Helper).
|
|
68
|
+
//
|
|
69
|
+
// # Purpose
|
|
70
|
+
//
|
|
71
|
+
// This message is used to:
|
|
72
|
+
//
|
|
73
|
+
// - present identifying details to users during pairing
|
|
74
|
+
// - assist users in verifying the identity of the counterparty
|
|
75
|
+
// - provide contextual metadata for UI display
|
|
76
|
+
//
|
|
77
|
+
// # Semantics
|
|
78
|
+
//
|
|
79
|
+
// - The contents are entirely application-defined
|
|
80
|
+
// - The protocol does not validate, interpret, or enforce any schema
|
|
81
|
+
// - Entries are independent key-value pairs
|
|
82
|
+
//
|
|
83
|
+
// # Security Considerations
|
|
84
|
+
//
|
|
85
|
+
// - This data MUST NOT be relied upon for authentication
|
|
86
|
+
// - Authentication is handled outside the protocol (e.g., in-person,
|
|
87
|
+
// KYC, or application-specific mechanisms)
|
|
88
|
+
//
|
|
89
|
+
// # Privacy Considerations
|
|
90
|
+
//
|
|
91
|
+
// - Applications SHOULD avoid including sensitive information unless
|
|
92
|
+
// necessary for the user experience
|
|
93
|
+
// - Users should be informed about what data is being shared
|
|
94
|
+
//
|
|
95
|
+
// # Interoperability
|
|
96
|
+
//
|
|
97
|
+
// While no schema is enforced, using common keys improves usability
|
|
98
|
+
// across implementations.
|
|
99
|
+
message CommunicationInfo {
|
|
100
|
+
// List of key-value entries describing the participant.
|
|
101
|
+
//
|
|
102
|
+
// Each entry represents one piece of identifying information.
|
|
103
|
+
repeated CommunicationInfoKeyValue communicationInfoEntries = 1;
|
|
104
|
+
}
|
|
@@ -0,0 +1,264 @@
|
|
|
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 "transportprotocol.proto";
|
|
10
|
+
|
|
11
|
+
package org.derecalliance.derec.protobuf;
|
|
12
|
+
|
|
13
|
+
// ContactMessage is the only DeRec protocol message that is not wrapped
|
|
14
|
+
// inside a DeRecMessage.
|
|
15
|
+
//
|
|
16
|
+
// This message is exchanged out-of-band before pairing begins. It provides
|
|
17
|
+
// the minimum information required for another party to initiate contact and
|
|
18
|
+
// send the first protocol message for a new pairing session.
|
|
19
|
+
//
|
|
20
|
+
// Unlike normal DeRec protocol messages, a ContactMessage:
|
|
21
|
+
//
|
|
22
|
+
// - is not wrapped in a DeRecMessage
|
|
23
|
+
// - is not signed
|
|
24
|
+
// - is not encrypted
|
|
25
|
+
// - is not delivered through an already-established DeRec channel
|
|
26
|
+
//
|
|
27
|
+
// Because it is exchanged before any secure channel exists, this message
|
|
28
|
+
// should only contain bootstrap information needed to establish that channel.
|
|
29
|
+
// It is typically transferred through a trusted or user-mediated mechanism.
|
|
30
|
+
//
|
|
31
|
+
// Typical exchange mechanisms include:
|
|
32
|
+
//
|
|
33
|
+
// - QR codes displayed by either the Owner or Helper and scanned by the other
|
|
34
|
+
// party
|
|
35
|
+
// - distribution inside an application controlled by one of the parties
|
|
36
|
+
// - transmission over an already-existing communication channel when the
|
|
37
|
+
// parties have a prior relationship
|
|
38
|
+
//
|
|
39
|
+
// The recipient of this message uses its contents to construct and send the
|
|
40
|
+
// initial pairing request. In particular, the ContactMessage conveys:
|
|
41
|
+
//
|
|
42
|
+
// - the public encryption key material needed to protect the first inbound
|
|
43
|
+
// pairing message
|
|
44
|
+
// - a channel identifier that the recipient must echo in subsequent protocol
|
|
45
|
+
// messages sent to this contact
|
|
46
|
+
// - a nonce that binds the pairing attempt to the out-of-band contact exchange
|
|
47
|
+
// - the transport information required to deliver the pairing request
|
|
48
|
+
//
|
|
49
|
+
// The nonce may be transmitted together with the rest of the message or
|
|
50
|
+
// delivered separately by the application, depending on the authentication
|
|
51
|
+
// and pairing UX.
|
|
52
|
+
//
|
|
53
|
+
// # Modes
|
|
54
|
+
//
|
|
55
|
+
// `ContactMessage` supports three delivery modes for the public encryption
|
|
56
|
+
// material, selected by `contactMode`:
|
|
57
|
+
//
|
|
58
|
+
// - `INLINE_KEYS` (default): both `mlkemEncapsulationKey` and
|
|
59
|
+
// `eciesPublicKey` are present in the contact. The recipient may proceed
|
|
60
|
+
// directly to `PairRequestMessage`. This is the original, wire-equivalent
|
|
61
|
+
// behavior — existing contacts (which have no `contactMode` set) are
|
|
62
|
+
// parsed as `INLINE_KEYS` by virtue of the proto3 default.
|
|
63
|
+
//
|
|
64
|
+
// - `HASHED_KEYS`: `contactBindingHash` is present and both
|
|
65
|
+
// key fields are absent. The contact is small enough to fit in a QR code
|
|
66
|
+
// or short URL. The recipient must first exchange a `PrePairRequest` /
|
|
67
|
+
// `PrePairResponse` pair to obtain the actual keys, then verify them
|
|
68
|
+
// against the hash before sending `PairRequestMessage`. The hash binding
|
|
69
|
+
// gives the OOB-shared contact the same MITM resistance as inline-keys
|
|
70
|
+
// mode despite the keys traveling over the (unauthenticated) transport.
|
|
71
|
+
// Because the `PrePair*` messages are plaintext, the `transportProtocol`
|
|
72
|
+
// carried in this mode MUST be ephemeral — see the security note on
|
|
73
|
+
// `PrePairRequestMessage` for the required ephemeral-then-swap discipline.
|
|
74
|
+
//
|
|
75
|
+
// - `NO_KEYS`: all of `mlkemEncapsulationKey`, `eciesPublicKey`, and
|
|
76
|
+
// `contactBindingHash` are absent. The contact carries only
|
|
77
|
+
// `channelId`, `nonce`, and `transportProtocol` — small enough to be
|
|
78
|
+
// hand-typed or dictated over the phone. There is no cryptographic
|
|
79
|
+
// binding: the recipient's `PrePairRequest` triggers on-the-fly key
|
|
80
|
+
// generation on the contact creator, and the returned keys are used
|
|
81
|
+
// without hash verification. The security model rests **entirely** on
|
|
82
|
+
// the out-of-band delivery channel being fully trusted (e.g. a
|
|
83
|
+
// verified email from an already-KYC-authenticated institution). The
|
|
84
|
+
// `nonce` correlates the incoming request to the intended user; because
|
|
85
|
+
// the nonce is intentionally small for human typability, applications
|
|
86
|
+
// MUST rate-limit incoming `PrePairRequest`s per `channelId` and expire
|
|
87
|
+
// outstanding NoKeys contacts on a short timer. Not appropriate for
|
|
88
|
+
// peer-to-peer pairing over untrusted channels — use `HASHED_KEYS` or
|
|
89
|
+
// `INLINE_KEYS` there.
|
|
90
|
+
//
|
|
91
|
+
// Because nothing binds the published keys to the contact, a `NO_KEYS`
|
|
92
|
+
// channel MUST NOT be used until the pair is confirmed out of band. An
|
|
93
|
+
// implementation MUST hold it unusable — no secrets sent, inbound
|
|
94
|
+
// messages ignored — until both sides compare the human-readable
|
|
95
|
+
// fingerprint derived from the established shared key and it matches. A
|
|
96
|
+
// man-in-the-middle on the `PrePair` leg yields two different shared
|
|
97
|
+
// keys and therefore two different fingerprints, so this comparison is
|
|
98
|
+
// what `HASHED_KEYS` gets from its `contactBindingHash` and `NO_KEYS`
|
|
99
|
+
// can get no other way. This is a requirement of the mode, not a
|
|
100
|
+
// deployment choice.
|
|
101
|
+
//
|
|
102
|
+
// The mode selector and the per-mode field-presence invariants are enforced
|
|
103
|
+
// by the implementation; mixing fields across modes is a protocol error.
|
|
104
|
+
|
|
105
|
+
// Selects the delivery mode for the public encryption material in
|
|
106
|
+
// `ContactMessage`. See `ContactMessage` for details.
|
|
107
|
+
enum ContactMode {
|
|
108
|
+
// Default. `mlkemEncapsulationKey` and `eciesPublicKey` are inlined
|
|
109
|
+
// in the contact.
|
|
110
|
+
INLINE_KEYS = 0;
|
|
111
|
+
// `contactBindingHash` is inlined in the contact; keys are obtained via
|
|
112
|
+
// `PrePairRequest` / `PrePairResponse` and verified against the hash.
|
|
113
|
+
HASHED_KEYS = 1;
|
|
114
|
+
// No key material and no hash are inlined. The contact carries only
|
|
115
|
+
// `channelId`, `nonce`, and `transportProtocol`; the contact creator
|
|
116
|
+
// generates key material on the fly when the corresponding
|
|
117
|
+
// `PrePairRequest` arrives. Only appropriate when the out-of-band
|
|
118
|
+
// delivery channel is fully trusted, and the channel stays unusable
|
|
119
|
+
// until both sides confirm the fingerprint out of band — nothing else
|
|
120
|
+
// binds the published keys to the contact.
|
|
121
|
+
NO_KEYS = 2;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
message ContactMessage {
|
|
125
|
+
|
|
126
|
+
// Selects how the public encryption material is delivered. Defaults to
|
|
127
|
+
// `INLINE_KEYS` (current behavior) when unset.
|
|
128
|
+
ContactMode contactMode = 1;
|
|
129
|
+
|
|
130
|
+
// Serialized ML-KEM-768 encapsulation key.
|
|
131
|
+
//
|
|
132
|
+
// Present only when `contactMode == INLINE_KEYS`. Used by
|
|
133
|
+
// the recipient to construct the initial pairing message.
|
|
134
|
+
optional bytes mlkemEncapsulationKey = 2;
|
|
135
|
+
|
|
136
|
+
// Serialized ECIES public key.
|
|
137
|
+
//
|
|
138
|
+
// Present only when `contactMode == INLINE_KEYS`. Used by
|
|
139
|
+
// the recipient to construct the initial pairing message.
|
|
140
|
+
optional bytes eciesPublicKey = 3;
|
|
141
|
+
|
|
142
|
+
// SHA-384 commitment to the public encryption material.
|
|
143
|
+
//
|
|
144
|
+
// Present only when `contactMode == HASHED_KEYS`. Computed
|
|
145
|
+
// as:
|
|
146
|
+
//
|
|
147
|
+
// ```text
|
|
148
|
+
// SHA-384(
|
|
149
|
+
// mlkemEncapsulationKey
|
|
150
|
+
// || eciesPublicKey
|
|
151
|
+
// || u64_be(nonce)
|
|
152
|
+
// || u64_be(channelId)
|
|
153
|
+
// )
|
|
154
|
+
// ```
|
|
155
|
+
//
|
|
156
|
+
// The recipient obtains the actual keys via `PrePairRequest` and
|
|
157
|
+
// recomputes this hash to confirm integrity before proceeding to
|
|
158
|
+
// `PairRequestMessage`.
|
|
159
|
+
optional bytes contactBindingHash = 4;
|
|
160
|
+
|
|
161
|
+
// Channel identifier associated with this contact.
|
|
162
|
+
//
|
|
163
|
+
// This value identifies the communication channel that the creator of this
|
|
164
|
+
// ContactMessage expects to use for the new pairing. After receiving this
|
|
165
|
+
// contact, the initiating party includes this channelId in subsequent
|
|
166
|
+
// protocol messages sent to the contact creator.
|
|
167
|
+
//
|
|
168
|
+
// The recipient uses this identifier to determine which local key material
|
|
169
|
+
// and pairing state should be used when processing the message.
|
|
170
|
+
//
|
|
171
|
+
// If an implementation generates multiple pending contact records or
|
|
172
|
+
// multiple encryption key pairs for different pairing attempts, it should
|
|
173
|
+
// retain the mapping from channelId to the corresponding local state so it
|
|
174
|
+
// can process inbound messages without trial decryption across all keys.
|
|
175
|
+
//
|
|
176
|
+
// This value MUST be unique within the scope required by the implementation
|
|
177
|
+
// to disambiguate concurrent or stored pairing sessions.
|
|
178
|
+
uint64 channelId = 5;
|
|
179
|
+
|
|
180
|
+
// Random nonce used to bind the pairing request to this contact exchange.
|
|
181
|
+
//
|
|
182
|
+
// The initiator includes this value in the pairing request so the creator
|
|
183
|
+
// of the ContactMessage can confirm that the request corresponds to the
|
|
184
|
+
// same out-of-band contact information that was just shared.
|
|
185
|
+
//
|
|
186
|
+
// This helps the application detect mismatched, stale, or spoofed pairing
|
|
187
|
+
// attempts during the bootstrap phase.
|
|
188
|
+
//
|
|
189
|
+
// Applications may choose to reveal this nonce only after sufficient
|
|
190
|
+
// out-of-band authentication has taken place.
|
|
191
|
+
uint64 nonce = 6;
|
|
192
|
+
|
|
193
|
+
// Transport information used to reach the creator of this contact.
|
|
194
|
+
//
|
|
195
|
+
// This specifies both:
|
|
196
|
+
//
|
|
197
|
+
// - the endpoint to which the first protocol message should be sent
|
|
198
|
+
// - the transport protocol that determines how that endpoint is interpreted
|
|
199
|
+
// and used
|
|
200
|
+
//
|
|
201
|
+
// The initiating party uses this field to deliver the initial pairing
|
|
202
|
+
// request. Subsequent protocol exchanges may continue using the same
|
|
203
|
+
// transport information or updated transport details, depending on the
|
|
204
|
+
// protocol and application behavior.
|
|
205
|
+
//
|
|
206
|
+
// Deprecated: superseded by `supportedTransports`, which carries every
|
|
207
|
+
// endpoint rather than one.
|
|
208
|
+
//
|
|
209
|
+
// **Reading this field directly is now incorrect.** Its meaning narrowed
|
|
210
|
+
// from "the endpoint" to "one entry of a list, and possibly absent": a
|
|
211
|
+
// creator that has moved past this field advertises only
|
|
212
|
+
// `supportedTransports`. A reader that was correct before this release is
|
|
213
|
+
// a bug now — it rejects, or fails to reach, a peer that is offering it a
|
|
214
|
+
// perfectly good endpoint. Resolve both spellings instead of reading
|
|
215
|
+
// either: `advertised_endpoints()` (Rust and TypeScript),
|
|
216
|
+
// `AdvertisedEndpoints()` (Go), `AdvertisedEndpoints()` (.NET).
|
|
217
|
+
//
|
|
218
|
+
// Senders still populate it: a sender that sets `supportedTransports`
|
|
219
|
+
// MUST also set this to a single best-compatibility choice, so
|
|
220
|
+
// implementations predating the list still pair.
|
|
221
|
+
//
|
|
222
|
+
// **Scheduled for removal in v0.0.5.**
|
|
223
|
+
TransportProtocol transportProtocol = 7 [deprecated = true];
|
|
224
|
+
|
|
225
|
+
// Timestamp indicating when the sender created this message.
|
|
226
|
+
//
|
|
227
|
+
// This value is expressed in UTC and can be used for:
|
|
228
|
+
//
|
|
229
|
+
// - replay detection
|
|
230
|
+
// - timeout handling
|
|
231
|
+
// - logging and observability
|
|
232
|
+
google.protobuf.Timestamp timestamp = 8;
|
|
233
|
+
|
|
234
|
+
// Every transport endpoint the creator of this contact can be reached on.
|
|
235
|
+
//
|
|
236
|
+
// Each entry is a complete endpoint: a URI plus the protocol that says
|
|
237
|
+
// how to interpret it. The list is written in the creator's own
|
|
238
|
+
// preference order.
|
|
239
|
+
//
|
|
240
|
+
// # Selection is the recipient's
|
|
241
|
+
//
|
|
242
|
+
// A recipient picks whichever entry suits it, ordered by its **own**
|
|
243
|
+
// preference rather than the sender's. The order here expresses
|
|
244
|
+
// availability, not a ranking the recipient must honor.
|
|
245
|
+
//
|
|
246
|
+
// # Compatibility
|
|
247
|
+
//
|
|
248
|
+
// Absent means "only `transportProtocol` is offered", which is how every
|
|
249
|
+
// implementation predating this field behaves. A sender populating this
|
|
250
|
+
// list MUST also set `transportProtocol` to a single best-compatibility
|
|
251
|
+
// choice so those implementations still pair.
|
|
252
|
+
//
|
|
253
|
+
// # Security
|
|
254
|
+
//
|
|
255
|
+
// `contactBindingHash` does not cover this field, exactly as it does not
|
|
256
|
+
// cover `transportProtocol`. An attacker able to rewrite an
|
|
257
|
+
// out-of-band contact can therefore remove entries. Removing the secure
|
|
258
|
+
// ones leaves only plaintext, which the recipient's transport policy
|
|
259
|
+
// refuses unless plaintext has been explicitly opted into. DeRec messages
|
|
260
|
+
// are signed and encrypted at the application layer on every transport,
|
|
261
|
+
// so substituting one secure transport for another is not a loss of
|
|
262
|
+
// confidentiality or authenticity.
|
|
263
|
+
repeated TransportProtocol supportedTransports = 9;
|
|
264
|
+
}
|