hide-protocol 0.8.0-aarch64-linux → 0.9.1-aarch64-linux

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 718d313c9adab619e4d06d2368453982f93ac7a31bec8d131902e29ff711aa9d
4
- data.tar.gz: 8160e42099bb755e1f720339a61afccc54dab5b83648ddcd2d0b1ad964ec966c
3
+ metadata.gz: 30e1877e19a676b20598217324038d73c36c0751f1c62d545e838740f5838cd4
4
+ data.tar.gz: 5e75d57cd0c20cad9e8159bb8b4a2a0eca25f4d4eb632c9efe2397ec0e807538
5
5
  SHA512:
6
- metadata.gz: cfc27fab7c908e624bd490681970eb7e328ab7e3d9dc1fb96120521b778af1c3cecc019e05174ef5e7cb8e6c47f27f2e617803cc5c27b1b2c0089a7e4ab2501a
7
- data.tar.gz: 4ac6e0176c0e34b25073d3ebab7b0017c6e6d0be7d4ad228cd818a30820249055114e8cfe714b92c62daec25db48b9f8c8a7b01a408ba387bfd02bfd126a0592
6
+ metadata.gz: b3bd36b9988e09371c4d0256296c91c9f998219631214ed52f8fb3a809ad01ba8b037a5034741d1412fe46edc6d16ce056dd745c10f858b308466085248373e6
7
+ data.tar.gz: c3f139adf55e86ed865a7b704afdb7dd4f160421ea2080915dc373472dddce27d190b77a7a395a0dde8e5ad4e24f520c73d2a2f26c89d2873d6a46afa18cb93b
data/README.md CHANGED
@@ -103,12 +103,20 @@ written before signatures existed carries no signing seed and raises
103
103
  | `Hide.epoch_public_key(chain, epoch)` | the public key to encrypt to for `epoch` |
104
104
  | `Hide.verify_inclusion(leaf, index, size, path, root)` | `nil` |
105
105
  | `Hide.verify_consistency(old_size, new_size, path, old_root, new_root)` | `nil` |
106
+ | `Hide.verify_identity_pinned(log, recovery_binding, pinned_root)` | `Integer` — devices trusted, after checking the log against the 32-byte root you pinned |
107
+ | `Hide.verify_epoch_chain_bound(log, recovery_binding, pinned_root, chain, epoch_binding)` | `Integer` — epochs held, after proving the chain belongs to that identity |
108
+ | `Hide.verify_checkpoint(note, origin, log_public)` | `[size, root]` — tree size and 32-byte root of a signed checkpoint note |
106
109
 
107
110
  A cryptographic verify **raises** on failure (`MalformedError` if the bytes did
108
111
  not decode, `AuthenticationError` if they decoded but did not verify) and never
109
112
  returns `false`. The one boolean is `identity_trusts_device`: the log is
110
113
  verified first, so `false` means "not a member", never "did not verify".
111
114
 
115
+ `verify_identity_pinned` is the relying-party check (spec §16): a recovery key
116
+ taken from the same untrusted source as the log cannot catch a Recover appended
117
+ under a stranger's key, but a `recovery_binding` checked against a root you
118
+ trust out of band does.
119
+
112
120
  ## Native library
113
121
 
114
122
  The core is located in this order:
@@ -150,5 +158,5 @@ closes — including when the block raises. A closed handle raises
150
158
 
151
159
  - Repository: <https://github.com/hide-protocol/hide>
152
160
  - Documentation: [docs/](https://github.com/hide-protocol/hide/tree/main/docs)
153
- - Specification: [spec/hide-0.1.md](https://github.com/hide-protocol/hide/blob/main/spec/hide-0.1.md)
161
+ - Specification: [spec/hide-1.md](https://github.com/hide-protocol/hide/blob/main/spec/hide-1.md)
154
162
  - [CHANGELOG](https://github.com/hide-protocol/hide/blob/main/CHANGELOG.md)
@@ -122,6 +122,15 @@ module Hide
122
122
  ],
123
123
  hide_transparency_verify_consistency: [
124
124
  [UINT64, UINT64, VOIDP, SIZE_T, VOIDP, SIZE_T, VOIDP, SIZE_T], INT32
125
+ ],
126
+ hide_identity_verify_pinned: [
127
+ [VOIDP, SIZE_T, VOIDP, SIZE_T, VOIDP, SIZE_T, VOIDP], INT32
128
+ ],
129
+ hide_epoch_verify_bound: [
130
+ [VOIDP, SIZE_T, VOIDP, SIZE_T, VOIDP, SIZE_T, VOIDP, SIZE_T, VOIDP, SIZE_T, VOIDP], INT32
131
+ ],
132
+ hide_checkpoint_verify: [
133
+ [VOIDP, SIZE_T, VOIDP, VOIDP, SIZE_T, VOIDP, VOIDP], INT32
125
134
  ]
126
135
  }.freeze
127
136
 
@@ -189,5 +198,17 @@ module Hide
189
198
  slot[0, WORD] = "\x00" * WORD
190
199
  slot
191
200
  end
201
+
202
+ # A slot for a uint64_t out-parameter. Always 8 bytes, unlike a size_t
203
+ # slot, so it is read with "Q" rather than WORD_PACK.
204
+ def self.uint64_slot
205
+ slot = Fiddle::Pointer.malloc(8, Fiddle::RUBY_FREE)
206
+ slot[0, 8] = "\x00" * 8
207
+ slot
208
+ end
209
+
210
+ def self.read_uint64(slot)
211
+ slot[0, 8].unpack1("Q")
212
+ end
192
213
  end
193
214
  end
Binary file
data/lib/hide_protocol.rb CHANGED
@@ -292,6 +292,77 @@ module Hide
292
292
  nil
293
293
  end
294
294
 
295
+ # Verifies an identity log against the root the caller pinned out of band.
296
+ #
297
+ # recovery_binding establishes the recovery key, so a log extended by a
298
+ # Recover under a stranger's key fails — a bare verify_identity with a
299
+ # recovery key taken from the same untrusted source does not catch that.
300
+ # Returns how many devices the log trusts now; raises MalformedError for
301
+ # bytes that do not decode and AuthenticationError for a log that is not
302
+ # this identity's.
303
+ def verify_identity_pinned(log, recovery_binding, pinned_root)
304
+ bytes = binary(log, "log")
305
+ binding = binary(recovery_binding, "recovery binding")
306
+ root = binary(pinned_root, "pinned root")
307
+ slot = Binding.pointer_slot
308
+ check(Binding.call(
309
+ :hide_identity_verify_pinned,
310
+ buffer_arg(bytes), bytes.bytesize,
311
+ buffer_arg(binding), binding.bytesize,
312
+ buffer_arg(root), root.bytesize,
313
+ slot
314
+ ))
315
+ Binding.read_count(slot)
316
+ end
317
+
318
+ # Verifies that an epoch chain belongs to the pinned identity.
319
+ #
320
+ # epoch_binding must be signed by a device the log trusts now, over this
321
+ # exact chain. Returns how many epochs the chain holds.
322
+ def verify_epoch_chain_bound(log, recovery_binding, pinned_root, chain, epoch_binding)
323
+ bytes = binary(log, "log")
324
+ binding = binary(recovery_binding, "recovery binding")
325
+ root = binary(pinned_root, "pinned root")
326
+ chain_bytes = binary(chain, "chain")
327
+ epoch_bytes = binary(epoch_binding, "epoch binding")
328
+ slot = Binding.pointer_slot
329
+ check(Binding.call(
330
+ :hide_epoch_verify_bound,
331
+ buffer_arg(bytes), bytes.bytesize,
332
+ buffer_arg(binding), binding.bytesize,
333
+ buffer_arg(root), root.bytesize,
334
+ buffer_arg(chain_bytes), chain_bytes.bytesize,
335
+ buffer_arg(epoch_bytes), epoch_bytes.bytesize,
336
+ slot
337
+ ))
338
+ Binding.read_count(slot)
339
+ end
340
+
341
+ # Verifies a signed checkpoint note from the log named origin, under the
342
+ # log's 1984-byte public key. Returns [size, root]: the tree size and its
343
+ # 32-byte root. Raises AuthenticationError when the note was altered,
344
+ # names another origin, or is not signed under log_public.
345
+ def verify_checkpoint(note, origin, log_public)
346
+ bytes = binary(note, "note")
347
+ key = binary(log_public, "log public key")
348
+ size = Binding.uint64_slot
349
+ out = Binding.empty_buffer
350
+ begin
351
+ check(Binding.call(
352
+ :hide_checkpoint_verify,
353
+ buffer_arg(bytes), bytes.bytesize,
354
+ cstring(origin.to_s),
355
+ buffer_arg(key), key.bytesize,
356
+ size, out
357
+ ))
358
+ rescue StandardError
359
+ # On failure the core leaves out untouched; freeing it releases the scratch space.
360
+ Binding.take(out)
361
+ raise
362
+ end
363
+ [Binding.read_uint64(size), Binding.take(out)]
364
+ end
365
+
295
366
  def check(code)
296
367
  return if code == Binding::OK
297
368
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hide-protocol
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.1
5
5
  platform: aarch64-linux
6
6
  authors:
7
7
  - HIDE contributors