@derec-alliance/react-native 0.0.7 → 0.0.9

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/cpp/derec_ffi.h CHANGED
@@ -239,6 +239,10 @@
239
239
 
240
240
  #define DEREC_CODE_VSS_SHARE_FAILED 64
241
241
 
242
+ #define DEREC_CODE_INVALID_WEIGHT 65
243
+
244
+ #define DEREC_CODE_TOO_MANY_SUBSHARES 66
245
+
242
246
  #define DEREC_CODE_EMPTY_RESPONSES 80
243
247
 
244
248
  #define DEREC_CODE_EMPTY_COMMITTED_DEREC_SHARE 81
@@ -289,6 +293,20 @@
289
293
  */
290
294
  #define DEREC_CODE_NO_USABLE_ENDPOINT 121
291
295
 
296
+ /**
297
+ * Return codes for [`crate::interop::ffi::protocol::stores::ShareStoreCallbacks::save`]
298
+ * and `ShareStoreCallbacks::record_verification`: `0` is success, each of
299
+ * these three refuses the write/verification with the matching
300
+ * [`crate::protocol::Refusal`] variant, and any other non-zero value is an
301
+ * ordinary backend failure. The values are the `StatusEnum` numbers the
302
+ * helper answers the owner with, not FFI-local codes.
303
+ */
304
+ #define DEREC_SHARE_STORE_REFUSED_SIZE_LIMIT_EXCEEDED 3
305
+
306
+ #define DEREC_SHARE_STORE_REFUSED_TOO_FREQUENT 4
307
+
308
+ #define DEREC_SHARE_STORE_REFUSED_REJECTED 10
309
+
292
310
  /**
293
311
  * Discriminants selecting which message [`derec_decode_message_json`] and
294
312
  * [`derec_encode_message_json`] operate on.
@@ -838,10 +856,31 @@ typedef struct SecretStoreCallbacks {
838
856
  * strings, matching the `Vec<u8>` ↔ JSON-array convention used for
839
857
  * every other wire-format buffer in this module.
840
858
  *
859
+ * A share crosses as the JSON object
860
+ * `{ "secret_id": "<u64>", "version": <u32>, "bytes": [..], "subshares": <u32>, "threshold": <u32> }`.
861
+ * `subshares` is the owner-side subshare count
862
+ * ([`crate::protocol::types::Share::subshares`]) and `threshold` the
863
+ * owner-side threshold the version was split with
864
+ * ([`crate::protocol::types::Share::threshold`]). Each is omitted when there
865
+ * is none, and absent or `null` reads as none. Store them as given and return
866
+ * them unchanged.
867
+ *
841
868
  * `keep_list` returns the JSON encoding of the application's answer:
842
869
  * `null` for no list (the owner sends an empty `keepList` and helpers keep
843
870
  * every version) or an array of version numbers. An empty buffer or return code `1` also
844
871
  * means `null`.
872
+ *
873
+ * `save` and `record_verification` share a return-code convention: `0` is
874
+ * success; `3`/`4`/`10` (the
875
+ * [`DEREC_SHARE_STORE_REFUSED_SIZE_LIMIT_EXCEEDED`](crate::interop::ffi::error::DEREC_SHARE_STORE_REFUSED_SIZE_LIMIT_EXCEEDED) /
876
+ * [`DEREC_SHARE_STORE_REFUSED_TOO_FREQUENT`](crate::interop::ffi::error::DEREC_SHARE_STORE_REFUSED_TOO_FREQUENT) /
877
+ * [`DEREC_SHARE_STORE_REFUSED_REJECTED`](crate::interop::ffi::error::DEREC_SHARE_STORE_REFUSED_REJECTED)
878
+ * constants) refuse the call with the matching
879
+ * [`crate::protocol::Refusal`] variant; any other non-zero value is an
880
+ * ordinary backend failure. `record_verification` is called once per
881
+ * accepted verification challenge, after the challenged share is found and
882
+ * before the helper answers — see
883
+ * [`crate::protocol::DeRecShareStore::record_verification`].
845
884
  */
846
885
  typedef struct ShareStoreCallbacks {
847
886
  void *user_data;
@@ -886,13 +925,19 @@ typedef struct ShareStoreCallbacks {
886
925
  uint32_t version,
887
926
  uint8_t **out_ptr,
888
927
  size_t *out_len);
928
+ int32_t (*record_verification)(void *user_data,
929
+ uint64_t secret_id,
930
+ uint64_t channel_id,
931
+ uint32_t version);
889
932
  void (*free_buffer)(void *user_data, uint8_t *ptr, size_t len);
890
933
  } ShareStoreCallbacks;
891
934
 
892
935
  /**
893
936
  * Caller-supplied callbacks for the user-secret store. Methods cross
894
937
  * the FFI keyed by `secret_id`; the `UserSecrets` payload travels as a
895
- * JSON buffer matching [`UserSecretsRecord`].
938
+ * JSON buffer matching [`UserSecretsRecord`]. Its `threshold` is the
939
+ * recorded threshold ([`crate::protocol::types::UserSecrets::threshold`]),
940
+ * omitted when there is none; store the buffer as given.
896
941
  */
897
942
  typedef struct UserSecretStoreCallbacks {
898
943
  void *user_data;
@@ -1704,13 +1749,15 @@ struct ProcessPrePairResponseMessageResult process_pre_pair_response_message(con
1704
1749
  * are still passed as individual pointers, since purego marshals
1705
1750
  * pointer-sized arguments natively.
1706
1751
  *
1707
- * `config_json` must deserialize to [`ProtocolConfig`] — all field names
1708
- * `snake_case`. `secret_id` is the only required field. Every other field
1709
- * may be omitted, in which case the value matches
1710
- * [`crate::protocol::DeRecProtocolBuilder::new`]'s own default for that
1711
- * setting: [`ProtocolConfig`]'s field-level `#[serde(default)]` attributes
1712
- * read the same constants the builder does. A field that is present is
1713
- * used as given, including `0`, and validated by the builder.
1752
+ * `config_json` is a JSON object holding `secret_id` plus the canonical
1753
+ * [`DeRecProtocolConfig`] JSON, all field names `snake_case`. `secret_id`
1754
+ * is the only required field. The rest is parsed as a
1755
+ * [`DeRecProtocolConfig`] and applied with
1756
+ * [`crate::protocol::DeRecProtocolBuilder::with_config`]: an omitted field
1757
+ * keeps [`crate::protocol::DeRecProtocolBuilder::new`]'s own default for
1758
+ * that setting, and a field that is present is used as given, including
1759
+ * `0`, and validated by the builder. A key the config does not define is
1760
+ * rejected with `DEREC_CODE_FFI_BAD_PROTO` rather than ignored.
1714
1761
  *
1715
1762
  * ```json
1716
1763
  * {
@@ -1749,7 +1796,8 @@ struct ProcessPrePairResponseMessageResult process_pre_pair_response_message(con
1749
1796
  * "max_unresponsive_deletion_timeout": 0,
1750
1797
  * "min_unresponsive_deactivation_timeout": 0,
1751
1798
  * "max_unresponsive_deactivation_timeout": 0
1752
- * }
1799
+ * },
1800
+ * "max_subshares": null
1753
1801
  * }
1754
1802
  * ```
1755
1803
  *
@@ -1758,9 +1806,10 @@ struct ProcessPrePairResponseMessageResult process_pre_pair_response_message(con
1758
1806
  * preference order — the order decides which of a peer's offered
1759
1807
  * endpoints is used. `protocol` is its name (`"https"`, `"grpc"`) or
1760
1808
  * its `derec_proto::Protocol` discriminant (`0`, `1`). Each entry is validated, and
1761
- * two entries of the same protocol are rejected. Required: an absent or
1762
- * empty list is refused, since a node with no endpoint cannot be reached
1763
- * by any peer.
1809
+ * two entries of the same protocol are rejected. An unknown discriminant
1810
+ * or an invalid URI is rejected with `DEREC_CODE_TRANSPORT_INVALID`.
1811
+ * Required: an absent or empty list is refused, since a node with no
1812
+ * endpoint cannot be reached by any peer.
1764
1813
  * - `threshold`: omitted means [`crate::protocol::DEFAULT_THRESHOLD`]. A
1765
1814
  * `threshold` below `2` is rejected with `DEREC_CODE_INVALID_INPUT`.
1766
1815
  * - `unpair_ack`: `0` / `"required"` = Required, `1` / `"not_required"` =
@@ -1786,6 +1835,11 @@ struct ProcessPrePairResponseMessageResult process_pre_pair_response_message(con
1786
1835
  * string values. Mutually exclusive with a non-empty
1787
1836
  * `communication_info_ptr` buffer; omitted with an empty buffer means
1788
1837
  * no entries.
1838
+ * - `max_subshares`: decimal-string `u64` capping the total subshares one
1839
+ * sharing round may split the secret into, or absent/`null` for no cap.
1840
+ * A cap below `threshold` is rejected by the builder with
1841
+ * `DEREC_CODE_INVALID_INPUT`; a round over the cap fails with
1842
+ * `DEREC_CODE_TOO_MANY_SUBSHARES`.
1789
1843
  *
1790
1844
  * # Safety
1791
1845
  *
@@ -1995,7 +2049,8 @@ struct DeRecError derec_protocol_reject(struct DeRecProtocolHandle *handle,
1995
2049
  * "transports": [{ "uri": "https://replica.example", "protocol": "https" }],
1996
2050
  * "role": "Source", "communication_info": {} }],
1997
2051
  * "shared_key": [..32 bytes..]
1998
- * }
2052
+ * },
2053
+ * "threshold": 3
1999
2054
  * }
2000
2055
  * }
2001
2056
  * ```
@@ -2008,7 +2063,11 @@ struct DeRecError derec_protocol_reject(struct DeRecProtocolHandle *handle,
2008
2063
  * order; `protocol` is its name, `"https"` or `"grpc"`. An absent or
2009
2064
  * `null` `transports` reads as an empty list, and a helper or member with
2010
2065
  * no endpoint gets no channel: restore skips it and reports it as a
2011
- * `PeerNotRestored` event. `role` is `"Source"` or `"Destination"`.
2066
+ * `PeerNotRestored` event. `role` is `"Source"` or `"Destination"`. An
2067
+ * absent or `null` `communication_info` reads as an empty map, and an
2068
+ * absent or `null` helper `weight` as `1`. `threshold` is the threshold the
2069
+ * secret was split with; absent or `null` is none, and a value below `2` is
2070
+ * rejected. Restore writes it into the snapshot.
2012
2071
  *
2013
2072
  * `replicas` is an **object**, not an array, and is omitted entirely when
2014
2073
  * the `secret_id` has no replica group. Every member of the group shares
@@ -2220,14 +2279,23 @@ struct RecoverFromShareResponsesResult recover_from_share_responses(const uint8_
2220
2279
  uint64_t derec_generate_replica_id(void);
2221
2280
 
2222
2281
  /**
2282
+ * Splits `secret_data` into one committed share per weighted channel; see
2283
+ * [`crate::primitives::sharing::request::split`] for the weight and threshold
2284
+ * rules. Channels are given as the aligned `channels_ptr` / `weights_ptr`
2285
+ * arrays described in the module-level "Weighted channels" section; the
2286
+ * result does not depend on the order they are listed in.
2287
+ *
2223
2288
  * # Safety
2224
2289
  *
2225
- * Non-null input pointers must point to the corresponding readable byte ranges.
2290
+ * Non-null input pointers must point to the corresponding readable ranges:
2291
+ * `secret_data_len` bytes, and `channels_len` entries for each of
2292
+ * `channels_ptr` and `weights_ptr`.
2226
2293
  */
2227
2294
  struct ProtectSecretResult protect_secret(uint64_t secret_id,
2228
2295
  const uint8_t *secret_data_ptr,
2229
2296
  size_t secret_data_len,
2230
2297
  const uint64_t *channels_ptr,
2298
+ const uint32_t *weights_ptr,
2231
2299
  size_t channels_len,
2232
2300
  size_t threshold,
2233
2301
  uint32_t version);
@@ -239,6 +239,10 @@
239
239
 
240
240
  #define DEREC_CODE_VSS_SHARE_FAILED 64
241
241
 
242
+ #define DEREC_CODE_INVALID_WEIGHT 65
243
+
244
+ #define DEREC_CODE_TOO_MANY_SUBSHARES 66
245
+
242
246
  #define DEREC_CODE_EMPTY_RESPONSES 80
243
247
 
244
248
  #define DEREC_CODE_EMPTY_COMMITTED_DEREC_SHARE 81
@@ -289,6 +293,20 @@
289
293
  */
290
294
  #define DEREC_CODE_NO_USABLE_ENDPOINT 121
291
295
 
296
+ /**
297
+ * Return codes for [`crate::interop::ffi::protocol::stores::ShareStoreCallbacks::save`]
298
+ * and `ShareStoreCallbacks::record_verification`: `0` is success, each of
299
+ * these three refuses the write/verification with the matching
300
+ * [`crate::protocol::Refusal`] variant, and any other non-zero value is an
301
+ * ordinary backend failure. The values are the `StatusEnum` numbers the
302
+ * helper answers the owner with, not FFI-local codes.
303
+ */
304
+ #define DEREC_SHARE_STORE_REFUSED_SIZE_LIMIT_EXCEEDED 3
305
+
306
+ #define DEREC_SHARE_STORE_REFUSED_TOO_FREQUENT 4
307
+
308
+ #define DEREC_SHARE_STORE_REFUSED_REJECTED 10
309
+
292
310
  /**
293
311
  * Discriminants selecting which message [`derec_decode_message_json`] and
294
312
  * [`derec_encode_message_json`] operate on.
@@ -838,10 +856,31 @@ typedef struct SecretStoreCallbacks {
838
856
  * strings, matching the `Vec<u8>` ↔ JSON-array convention used for
839
857
  * every other wire-format buffer in this module.
840
858
  *
859
+ * A share crosses as the JSON object
860
+ * `{ "secret_id": "<u64>", "version": <u32>, "bytes": [..], "subshares": <u32>, "threshold": <u32> }`.
861
+ * `subshares` is the owner-side subshare count
862
+ * ([`crate::protocol::types::Share::subshares`]) and `threshold` the
863
+ * owner-side threshold the version was split with
864
+ * ([`crate::protocol::types::Share::threshold`]). Each is omitted when there
865
+ * is none, and absent or `null` reads as none. Store them as given and return
866
+ * them unchanged.
867
+ *
841
868
  * `keep_list` returns the JSON encoding of the application's answer:
842
869
  * `null` for no list (the owner sends an empty `keepList` and helpers keep
843
870
  * every version) or an array of version numbers. An empty buffer or return code `1` also
844
871
  * means `null`.
872
+ *
873
+ * `save` and `record_verification` share a return-code convention: `0` is
874
+ * success; `3`/`4`/`10` (the
875
+ * [`DEREC_SHARE_STORE_REFUSED_SIZE_LIMIT_EXCEEDED`](crate::interop::ffi::error::DEREC_SHARE_STORE_REFUSED_SIZE_LIMIT_EXCEEDED) /
876
+ * [`DEREC_SHARE_STORE_REFUSED_TOO_FREQUENT`](crate::interop::ffi::error::DEREC_SHARE_STORE_REFUSED_TOO_FREQUENT) /
877
+ * [`DEREC_SHARE_STORE_REFUSED_REJECTED`](crate::interop::ffi::error::DEREC_SHARE_STORE_REFUSED_REJECTED)
878
+ * constants) refuse the call with the matching
879
+ * [`crate::protocol::Refusal`] variant; any other non-zero value is an
880
+ * ordinary backend failure. `record_verification` is called once per
881
+ * accepted verification challenge, after the challenged share is found and
882
+ * before the helper answers — see
883
+ * [`crate::protocol::DeRecShareStore::record_verification`].
845
884
  */
846
885
  typedef struct ShareStoreCallbacks {
847
886
  void *user_data;
@@ -886,13 +925,19 @@ typedef struct ShareStoreCallbacks {
886
925
  uint32_t version,
887
926
  uint8_t **out_ptr,
888
927
  size_t *out_len);
928
+ int32_t (*record_verification)(void *user_data,
929
+ uint64_t secret_id,
930
+ uint64_t channel_id,
931
+ uint32_t version);
889
932
  void (*free_buffer)(void *user_data, uint8_t *ptr, size_t len);
890
933
  } ShareStoreCallbacks;
891
934
 
892
935
  /**
893
936
  * Caller-supplied callbacks for the user-secret store. Methods cross
894
937
  * the FFI keyed by `secret_id`; the `UserSecrets` payload travels as a
895
- * JSON buffer matching [`UserSecretsRecord`].
938
+ * JSON buffer matching [`UserSecretsRecord`]. Its `threshold` is the
939
+ * recorded threshold ([`crate::protocol::types::UserSecrets::threshold`]),
940
+ * omitted when there is none; store the buffer as given.
896
941
  */
897
942
  typedef struct UserSecretStoreCallbacks {
898
943
  void *user_data;
@@ -1704,13 +1749,15 @@ struct ProcessPrePairResponseMessageResult process_pre_pair_response_message(con
1704
1749
  * are still passed as individual pointers, since purego marshals
1705
1750
  * pointer-sized arguments natively.
1706
1751
  *
1707
- * `config_json` must deserialize to [`ProtocolConfig`] — all field names
1708
- * `snake_case`. `secret_id` is the only required field. Every other field
1709
- * may be omitted, in which case the value matches
1710
- * [`crate::protocol::DeRecProtocolBuilder::new`]'s own default for that
1711
- * setting: [`ProtocolConfig`]'s field-level `#[serde(default)]` attributes
1712
- * read the same constants the builder does. A field that is present is
1713
- * used as given, including `0`, and validated by the builder.
1752
+ * `config_json` is a JSON object holding `secret_id` plus the canonical
1753
+ * [`DeRecProtocolConfig`] JSON, all field names `snake_case`. `secret_id`
1754
+ * is the only required field. The rest is parsed as a
1755
+ * [`DeRecProtocolConfig`] and applied with
1756
+ * [`crate::protocol::DeRecProtocolBuilder::with_config`]: an omitted field
1757
+ * keeps [`crate::protocol::DeRecProtocolBuilder::new`]'s own default for
1758
+ * that setting, and a field that is present is used as given, including
1759
+ * `0`, and validated by the builder. A key the config does not define is
1760
+ * rejected with `DEREC_CODE_FFI_BAD_PROTO` rather than ignored.
1714
1761
  *
1715
1762
  * ```json
1716
1763
  * {
@@ -1749,7 +1796,8 @@ struct ProcessPrePairResponseMessageResult process_pre_pair_response_message(con
1749
1796
  * "max_unresponsive_deletion_timeout": 0,
1750
1797
  * "min_unresponsive_deactivation_timeout": 0,
1751
1798
  * "max_unresponsive_deactivation_timeout": 0
1752
- * }
1799
+ * },
1800
+ * "max_subshares": null
1753
1801
  * }
1754
1802
  * ```
1755
1803
  *
@@ -1758,9 +1806,10 @@ struct ProcessPrePairResponseMessageResult process_pre_pair_response_message(con
1758
1806
  * preference order — the order decides which of a peer's offered
1759
1807
  * endpoints is used. `protocol` is its name (`"https"`, `"grpc"`) or
1760
1808
  * its `derec_proto::Protocol` discriminant (`0`, `1`). Each entry is validated, and
1761
- * two entries of the same protocol are rejected. Required: an absent or
1762
- * empty list is refused, since a node with no endpoint cannot be reached
1763
- * by any peer.
1809
+ * two entries of the same protocol are rejected. An unknown discriminant
1810
+ * or an invalid URI is rejected with `DEREC_CODE_TRANSPORT_INVALID`.
1811
+ * Required: an absent or empty list is refused, since a node with no
1812
+ * endpoint cannot be reached by any peer.
1764
1813
  * - `threshold`: omitted means [`crate::protocol::DEFAULT_THRESHOLD`]. A
1765
1814
  * `threshold` below `2` is rejected with `DEREC_CODE_INVALID_INPUT`.
1766
1815
  * - `unpair_ack`: `0` / `"required"` = Required, `1` / `"not_required"` =
@@ -1786,6 +1835,11 @@ struct ProcessPrePairResponseMessageResult process_pre_pair_response_message(con
1786
1835
  * string values. Mutually exclusive with a non-empty
1787
1836
  * `communication_info_ptr` buffer; omitted with an empty buffer means
1788
1837
  * no entries.
1838
+ * - `max_subshares`: decimal-string `u64` capping the total subshares one
1839
+ * sharing round may split the secret into, or absent/`null` for no cap.
1840
+ * A cap below `threshold` is rejected by the builder with
1841
+ * `DEREC_CODE_INVALID_INPUT`; a round over the cap fails with
1842
+ * `DEREC_CODE_TOO_MANY_SUBSHARES`.
1789
1843
  *
1790
1844
  * # Safety
1791
1845
  *
@@ -1995,7 +2049,8 @@ struct DeRecError derec_protocol_reject(struct DeRecProtocolHandle *handle,
1995
2049
  * "transports": [{ "uri": "https://replica.example", "protocol": "https" }],
1996
2050
  * "role": "Source", "communication_info": {} }],
1997
2051
  * "shared_key": [..32 bytes..]
1998
- * }
2052
+ * },
2053
+ * "threshold": 3
1999
2054
  * }
2000
2055
  * }
2001
2056
  * ```
@@ -2008,7 +2063,11 @@ struct DeRecError derec_protocol_reject(struct DeRecProtocolHandle *handle,
2008
2063
  * order; `protocol` is its name, `"https"` or `"grpc"`. An absent or
2009
2064
  * `null` `transports` reads as an empty list, and a helper or member with
2010
2065
  * no endpoint gets no channel: restore skips it and reports it as a
2011
- * `PeerNotRestored` event. `role` is `"Source"` or `"Destination"`.
2066
+ * `PeerNotRestored` event. `role` is `"Source"` or `"Destination"`. An
2067
+ * absent or `null` `communication_info` reads as an empty map, and an
2068
+ * absent or `null` helper `weight` as `1`. `threshold` is the threshold the
2069
+ * secret was split with; absent or `null` is none, and a value below `2` is
2070
+ * rejected. Restore writes it into the snapshot.
2012
2071
  *
2013
2072
  * `replicas` is an **object**, not an array, and is omitted entirely when
2014
2073
  * the `secret_id` has no replica group. Every member of the group shares
@@ -2220,14 +2279,23 @@ struct RecoverFromShareResponsesResult recover_from_share_responses(const uint8_
2220
2279
  uint64_t derec_generate_replica_id(void);
2221
2280
 
2222
2281
  /**
2282
+ * Splits `secret_data` into one committed share per weighted channel; see
2283
+ * [`crate::primitives::sharing::request::split`] for the weight and threshold
2284
+ * rules. Channels are given as the aligned `channels_ptr` / `weights_ptr`
2285
+ * arrays described in the module-level "Weighted channels" section; the
2286
+ * result does not depend on the order they are listed in.
2287
+ *
2223
2288
  * # Safety
2224
2289
  *
2225
- * Non-null input pointers must point to the corresponding readable byte ranges.
2290
+ * Non-null input pointers must point to the corresponding readable ranges:
2291
+ * `secret_data_len` bytes, and `channels_len` entries for each of
2292
+ * `channels_ptr` and `weights_ptr`.
2226
2293
  */
2227
2294
  struct ProtectSecretResult protect_secret(uint64_t secret_id,
2228
2295
  const uint8_t *secret_data_ptr,
2229
2296
  size_t secret_data_len,
2230
2297
  const uint64_t *channels_ptr,
2298
+ const uint32_t *weights_ptr,
2231
2299
  size_t channels_len,
2232
2300
  size_t threshold,
2233
2301
  uint32_t version);
@@ -239,6 +239,10 @@
239
239
 
240
240
  #define DEREC_CODE_VSS_SHARE_FAILED 64
241
241
 
242
+ #define DEREC_CODE_INVALID_WEIGHT 65
243
+
244
+ #define DEREC_CODE_TOO_MANY_SUBSHARES 66
245
+
242
246
  #define DEREC_CODE_EMPTY_RESPONSES 80
243
247
 
244
248
  #define DEREC_CODE_EMPTY_COMMITTED_DEREC_SHARE 81
@@ -289,6 +293,20 @@
289
293
  */
290
294
  #define DEREC_CODE_NO_USABLE_ENDPOINT 121
291
295
 
296
+ /**
297
+ * Return codes for [`crate::interop::ffi::protocol::stores::ShareStoreCallbacks::save`]
298
+ * and `ShareStoreCallbacks::record_verification`: `0` is success, each of
299
+ * these three refuses the write/verification with the matching
300
+ * [`crate::protocol::Refusal`] variant, and any other non-zero value is an
301
+ * ordinary backend failure. The values are the `StatusEnum` numbers the
302
+ * helper answers the owner with, not FFI-local codes.
303
+ */
304
+ #define DEREC_SHARE_STORE_REFUSED_SIZE_LIMIT_EXCEEDED 3
305
+
306
+ #define DEREC_SHARE_STORE_REFUSED_TOO_FREQUENT 4
307
+
308
+ #define DEREC_SHARE_STORE_REFUSED_REJECTED 10
309
+
292
310
  /**
293
311
  * Discriminants selecting which message [`derec_decode_message_json`] and
294
312
  * [`derec_encode_message_json`] operate on.
@@ -838,10 +856,31 @@ typedef struct SecretStoreCallbacks {
838
856
  * strings, matching the `Vec<u8>` ↔ JSON-array convention used for
839
857
  * every other wire-format buffer in this module.
840
858
  *
859
+ * A share crosses as the JSON object
860
+ * `{ "secret_id": "<u64>", "version": <u32>, "bytes": [..], "subshares": <u32>, "threshold": <u32> }`.
861
+ * `subshares` is the owner-side subshare count
862
+ * ([`crate::protocol::types::Share::subshares`]) and `threshold` the
863
+ * owner-side threshold the version was split with
864
+ * ([`crate::protocol::types::Share::threshold`]). Each is omitted when there
865
+ * is none, and absent or `null` reads as none. Store them as given and return
866
+ * them unchanged.
867
+ *
841
868
  * `keep_list` returns the JSON encoding of the application's answer:
842
869
  * `null` for no list (the owner sends an empty `keepList` and helpers keep
843
870
  * every version) or an array of version numbers. An empty buffer or return code `1` also
844
871
  * means `null`.
872
+ *
873
+ * `save` and `record_verification` share a return-code convention: `0` is
874
+ * success; `3`/`4`/`10` (the
875
+ * [`DEREC_SHARE_STORE_REFUSED_SIZE_LIMIT_EXCEEDED`](crate::interop::ffi::error::DEREC_SHARE_STORE_REFUSED_SIZE_LIMIT_EXCEEDED) /
876
+ * [`DEREC_SHARE_STORE_REFUSED_TOO_FREQUENT`](crate::interop::ffi::error::DEREC_SHARE_STORE_REFUSED_TOO_FREQUENT) /
877
+ * [`DEREC_SHARE_STORE_REFUSED_REJECTED`](crate::interop::ffi::error::DEREC_SHARE_STORE_REFUSED_REJECTED)
878
+ * constants) refuse the call with the matching
879
+ * [`crate::protocol::Refusal`] variant; any other non-zero value is an
880
+ * ordinary backend failure. `record_verification` is called once per
881
+ * accepted verification challenge, after the challenged share is found and
882
+ * before the helper answers — see
883
+ * [`crate::protocol::DeRecShareStore::record_verification`].
845
884
  */
846
885
  typedef struct ShareStoreCallbacks {
847
886
  void *user_data;
@@ -886,13 +925,19 @@ typedef struct ShareStoreCallbacks {
886
925
  uint32_t version,
887
926
  uint8_t **out_ptr,
888
927
  size_t *out_len);
928
+ int32_t (*record_verification)(void *user_data,
929
+ uint64_t secret_id,
930
+ uint64_t channel_id,
931
+ uint32_t version);
889
932
  void (*free_buffer)(void *user_data, uint8_t *ptr, size_t len);
890
933
  } ShareStoreCallbacks;
891
934
 
892
935
  /**
893
936
  * Caller-supplied callbacks for the user-secret store. Methods cross
894
937
  * the FFI keyed by `secret_id`; the `UserSecrets` payload travels as a
895
- * JSON buffer matching [`UserSecretsRecord`].
938
+ * JSON buffer matching [`UserSecretsRecord`]. Its `threshold` is the
939
+ * recorded threshold ([`crate::protocol::types::UserSecrets::threshold`]),
940
+ * omitted when there is none; store the buffer as given.
896
941
  */
897
942
  typedef struct UserSecretStoreCallbacks {
898
943
  void *user_data;
@@ -1704,13 +1749,15 @@ struct ProcessPrePairResponseMessageResult process_pre_pair_response_message(con
1704
1749
  * are still passed as individual pointers, since purego marshals
1705
1750
  * pointer-sized arguments natively.
1706
1751
  *
1707
- * `config_json` must deserialize to [`ProtocolConfig`] — all field names
1708
- * `snake_case`. `secret_id` is the only required field. Every other field
1709
- * may be omitted, in which case the value matches
1710
- * [`crate::protocol::DeRecProtocolBuilder::new`]'s own default for that
1711
- * setting: [`ProtocolConfig`]'s field-level `#[serde(default)]` attributes
1712
- * read the same constants the builder does. A field that is present is
1713
- * used as given, including `0`, and validated by the builder.
1752
+ * `config_json` is a JSON object holding `secret_id` plus the canonical
1753
+ * [`DeRecProtocolConfig`] JSON, all field names `snake_case`. `secret_id`
1754
+ * is the only required field. The rest is parsed as a
1755
+ * [`DeRecProtocolConfig`] and applied with
1756
+ * [`crate::protocol::DeRecProtocolBuilder::with_config`]: an omitted field
1757
+ * keeps [`crate::protocol::DeRecProtocolBuilder::new`]'s own default for
1758
+ * that setting, and a field that is present is used as given, including
1759
+ * `0`, and validated by the builder. A key the config does not define is
1760
+ * rejected with `DEREC_CODE_FFI_BAD_PROTO` rather than ignored.
1714
1761
  *
1715
1762
  * ```json
1716
1763
  * {
@@ -1749,7 +1796,8 @@ struct ProcessPrePairResponseMessageResult process_pre_pair_response_message(con
1749
1796
  * "max_unresponsive_deletion_timeout": 0,
1750
1797
  * "min_unresponsive_deactivation_timeout": 0,
1751
1798
  * "max_unresponsive_deactivation_timeout": 0
1752
- * }
1799
+ * },
1800
+ * "max_subshares": null
1753
1801
  * }
1754
1802
  * ```
1755
1803
  *
@@ -1758,9 +1806,10 @@ struct ProcessPrePairResponseMessageResult process_pre_pair_response_message(con
1758
1806
  * preference order — the order decides which of a peer's offered
1759
1807
  * endpoints is used. `protocol` is its name (`"https"`, `"grpc"`) or
1760
1808
  * its `derec_proto::Protocol` discriminant (`0`, `1`). Each entry is validated, and
1761
- * two entries of the same protocol are rejected. Required: an absent or
1762
- * empty list is refused, since a node with no endpoint cannot be reached
1763
- * by any peer.
1809
+ * two entries of the same protocol are rejected. An unknown discriminant
1810
+ * or an invalid URI is rejected with `DEREC_CODE_TRANSPORT_INVALID`.
1811
+ * Required: an absent or empty list is refused, since a node with no
1812
+ * endpoint cannot be reached by any peer.
1764
1813
  * - `threshold`: omitted means [`crate::protocol::DEFAULT_THRESHOLD`]. A
1765
1814
  * `threshold` below `2` is rejected with `DEREC_CODE_INVALID_INPUT`.
1766
1815
  * - `unpair_ack`: `0` / `"required"` = Required, `1` / `"not_required"` =
@@ -1786,6 +1835,11 @@ struct ProcessPrePairResponseMessageResult process_pre_pair_response_message(con
1786
1835
  * string values. Mutually exclusive with a non-empty
1787
1836
  * `communication_info_ptr` buffer; omitted with an empty buffer means
1788
1837
  * no entries.
1838
+ * - `max_subshares`: decimal-string `u64` capping the total subshares one
1839
+ * sharing round may split the secret into, or absent/`null` for no cap.
1840
+ * A cap below `threshold` is rejected by the builder with
1841
+ * `DEREC_CODE_INVALID_INPUT`; a round over the cap fails with
1842
+ * `DEREC_CODE_TOO_MANY_SUBSHARES`.
1789
1843
  *
1790
1844
  * # Safety
1791
1845
  *
@@ -1995,7 +2049,8 @@ struct DeRecError derec_protocol_reject(struct DeRecProtocolHandle *handle,
1995
2049
  * "transports": [{ "uri": "https://replica.example", "protocol": "https" }],
1996
2050
  * "role": "Source", "communication_info": {} }],
1997
2051
  * "shared_key": [..32 bytes..]
1998
- * }
2052
+ * },
2053
+ * "threshold": 3
1999
2054
  * }
2000
2055
  * }
2001
2056
  * ```
@@ -2008,7 +2063,11 @@ struct DeRecError derec_protocol_reject(struct DeRecProtocolHandle *handle,
2008
2063
  * order; `protocol` is its name, `"https"` or `"grpc"`. An absent or
2009
2064
  * `null` `transports` reads as an empty list, and a helper or member with
2010
2065
  * no endpoint gets no channel: restore skips it and reports it as a
2011
- * `PeerNotRestored` event. `role` is `"Source"` or `"Destination"`.
2066
+ * `PeerNotRestored` event. `role` is `"Source"` or `"Destination"`. An
2067
+ * absent or `null` `communication_info` reads as an empty map, and an
2068
+ * absent or `null` helper `weight` as `1`. `threshold` is the threshold the
2069
+ * secret was split with; absent or `null` is none, and a value below `2` is
2070
+ * rejected. Restore writes it into the snapshot.
2012
2071
  *
2013
2072
  * `replicas` is an **object**, not an array, and is omitted entirely when
2014
2073
  * the `secret_id` has no replica group. Every member of the group shares
@@ -2220,14 +2279,23 @@ struct RecoverFromShareResponsesResult recover_from_share_responses(const uint8_
2220
2279
  uint64_t derec_generate_replica_id(void);
2221
2280
 
2222
2281
  /**
2282
+ * Splits `secret_data` into one committed share per weighted channel; see
2283
+ * [`crate::primitives::sharing::request::split`] for the weight and threshold
2284
+ * rules. Channels are given as the aligned `channels_ptr` / `weights_ptr`
2285
+ * arrays described in the module-level "Weighted channels" section; the
2286
+ * result does not depend on the order they are listed in.
2287
+ *
2223
2288
  * # Safety
2224
2289
  *
2225
- * Non-null input pointers must point to the corresponding readable byte ranges.
2290
+ * Non-null input pointers must point to the corresponding readable ranges:
2291
+ * `secret_data_len` bytes, and `channels_len` entries for each of
2292
+ * `channels_ptr` and `weights_ptr`.
2226
2293
  */
2227
2294
  struct ProtectSecretResult protect_secret(uint64_t secret_id,
2228
2295
  const uint8_t *secret_data_ptr,
2229
2296
  size_t secret_data_len,
2230
2297
  const uint64_t *channels_ptr,
2298
+ const uint32_t *weights_ptr,
2231
2299
  size_t channels_len,
2232
2300
  size_t threshold,
2233
2301
  uint32_t version);
@@ -1,4 +1,4 @@
1
1
  [diffend] Oversized file quarantined before diffing.
2
2
  name: package/ios/DeRecFFI.xcframework/ios-arm64_x86_64-simulator/libderec_library.a
3
- size: 38454248 bytes
4
- sha256: 8e4fa480cdb006907de3fbd3c13011ee89816dc78b4c1c22b6a730297f29521a
3
+ size: 39345736 bytes
4
+ sha256: ba3ef018d9a8d24ff7859106f19da05e272a9dc2fa8935202eac4d5af54e35b3
package/lib/errors.d.ts CHANGED
@@ -13,9 +13,19 @@ import type { DeRecEvent } from './types';
13
13
  */
14
14
  export declare const DEREC_ERROR_CATEGORIES: readonly ["ok", "ffi", "pairing", "sharing", "recovery", "verification", "discovery", "unpairing", "derec_message", "secret_store", "channel_store", "share_store", "input", "protobuf", "invariant", "state_store"];
15
15
  export type DeRecErrorCategory = (typeof DEREC_ERROR_CATEGORIES)[number];
16
+ /**
17
+ * Every code `derec_error_code_name` can return, and no others.
18
+ *
19
+ * Held to the shared enum fixture by a test, like {@link DEREC_ERROR_CATEGORIES}.
20
+ * Unlike the WASM bindings, this SDK raises no marshalling-level codes of its
21
+ * own before a value reaches the library, so this list is exactly the Rust
22
+ * `Code` table in `library/src/interop/error_codes.rs`.
23
+ */
24
+ export declare const DEREC_ERROR_CODES: readonly ["ok", "non_ok_status", "version_mismatch", "invariant", "invalid_input", "protobuf_decode", "protobuf_encode", "protocol_violation", "store_error", "builder_error", "missing_shared_key", "role_mismatch", "replica_id_not_configured", "channel_already_paired", "already_restored", "restore_conflict", "replica_id_conflict", "encryption", "keygen", "finish_pairing_initiator", "finish_pairing_responder", "empty_transport_uri", "invalid_contact_message", "invalid_pair_request_message", "invalid_pair_response_message", "prepair_hash_mismatch", "missing_replica_id", "unexpected_replica_id", "incompatible_parameter_range", "empty_channels", "duplicate_channel_id", "invalid_threshold", "empty_secret_data", "vss_share_failed", "invalid_weight", "too_many_subshares", "empty_responses", "empty_committed_derec_share", "decode_committed_derec_share", "decode_derec_share", "secret_id_mismatch", "reconstruction_failed", "malformed_recovered_secret", "ffi_null_ptr", "ffi_bad_length", "ffi_bad_utf8", "ffi_bad_proto", "ffi_invalid_enum", "ffi_bad_shared_key", "ffi_nul_in_string", "transport_invalid", "no_usable_endpoint"];
25
+ export type DeRecErrorCode = (typeof DEREC_ERROR_CODES)[number];
16
26
  export interface DeRecError {
17
27
  category: DeRecErrorCategory;
18
- code: string;
28
+ code: DeRecErrorCode;
19
29
  message: string;
20
30
  status?: number;
21
31
  memo?: string;