beaconcrypt 0.2.0__tar.gz → 0.3.0__tar.gz

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.
Files changed (39) hide show
  1. beaconcrypt-0.3.0/.github/workflows/go.yml +44 -0
  2. {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/.gitignore +5 -0
  3. {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/Cargo.lock +9 -9
  4. {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/Cargo.toml +2 -2
  5. {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/PKG-INFO +1 -1
  6. beaconcrypt-0.3.0/beaconcrypt.go +255 -0
  7. beaconcrypt-0.3.0/beaconcrypt_test.go +208 -0
  8. {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/bindings.h +69 -0
  9. {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/build.rs +6 -0
  10. beaconcrypt-0.3.0/go.mod +3 -0
  11. beaconcrypt-0.3.0/src/lib.rs +519 -0
  12. beaconcrypt-0.2.0/src/lib.rs +0 -167
  13. {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/.cargo/config.toml +0 -0
  14. {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/.github/workflows/python.yml +0 -0
  15. {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/.github/workflows/release.yml +0 -0
  16. {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/.github/workflows/rust.yml +0 -0
  17. {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/LICENSE +0 -0
  18. {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/README.md +0 -0
  19. {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/clippy.toml +0 -0
  20. {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/doc/protocol.md +0 -0
  21. {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/doc/rationale.md +0 -0
  22. {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/doc/threat_model.md +0 -0
  23. {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/pyproject.toml +0 -0
  24. {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/rustfmt.toml +0 -0
  25. {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/src/beacon.rs +0 -0
  26. {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/src/cnsa2.rs +0 -0
  27. {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/src/error.rs +0 -0
  28. {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/src/pqxdh.rs +0 -0
  29. {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/src/schema/cryptoframe.capnp +0 -0
  30. {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/src/schema/phase1.capnp +0 -0
  31. {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/src/schema/phase2.capnp +0 -0
  32. {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/src/schema/protogram.capnp +0 -0
  33. {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/src/server.rs +0 -0
  34. {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/src/shared.rs +0 -0
  35. {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/tests/beacon.rs +0 -0
  36. {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/tests/server.rs +0 -0
  37. {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/tests/test_encryption.py +0 -0
  38. {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/tests/test_registration.py +0 -0
  39. {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/uv.lock +0 -0
@@ -0,0 +1,44 @@
1
+ name: Go Module
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "*"
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ env:
12
+ CARGO_TERM_COLOR: always
13
+ GOPROXY: https://proxy.golang.org
14
+ GONOSUMDB: ""
15
+
16
+ jobs:
17
+ publish:
18
+ runs-on: ubuntu-latest
19
+
20
+ steps:
21
+ - uses: actions/checkout@v7
22
+
23
+ - name: Set up Go
24
+ uses: actions/setup-go@v6
25
+ with:
26
+ go-version-file: go.mod
27
+ check-latest: true
28
+
29
+ - name: Install cap'n proto
30
+ run: sudo apt update && sudo apt install capnproto
31
+
32
+ - name: Build native library
33
+ run: cargo build --verbose
34
+
35
+ - name: Test Go module
36
+ run: go test ./...
37
+
38
+ - name: Publish module to Go proxy
39
+ run: |
40
+ module_path="$(go list -m)"
41
+ version="${GITHUB_REF_NAME}"
42
+ encoded_module="${module_path,,}"
43
+ curl --fail --show-error --location --retry 5 --retry-all-errors --retry-delay 10 \
44
+ "https://proxy.golang.org/${encoded_module}/@v/v${version}.info"
@@ -70,3 +70,8 @@ docs/_build/
70
70
 
71
71
  # Pyenv
72
72
  .python-version
73
+
74
+ .gocache/
75
+ .go-appdata/
76
+ .go-localappdata/
77
+ .gotelemetry/
@@ -84,7 +84,7 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
84
84
 
85
85
  [[package]]
86
86
  name = "beaconcrypt"
87
- version = "0.2.0"
87
+ version = "0.3.0"
88
88
  dependencies = [
89
89
  "capnp",
90
90
  "capnpc",
@@ -181,18 +181,18 @@ dependencies = [
181
181
 
182
182
  [[package]]
183
183
  name = "clap"
184
- version = "4.6.1"
184
+ version = "4.6.2"
185
185
  source = "registry+https://github.com/rust-lang/crates.io-index"
186
- checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51"
186
+ checksum = "dd059f9da4f5c36b3787f65d38ccaab1cc315f07b01f89abc8359ee6a8205011"
187
187
  dependencies = [
188
188
  "clap_builder",
189
189
  ]
190
190
 
191
191
  [[package]]
192
192
  name = "clap_builder"
193
- version = "4.6.0"
193
+ version = "4.6.2"
194
194
  source = "registry+https://github.com/rust-lang/crates.io-index"
195
- checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f"
195
+ checksum = "f09628afdcc538b57f3c6341e9c8e9970f18e4a481690a64974d7023bd33548b"
196
196
  dependencies = [
197
197
  "anstream",
198
198
  "anstyle",
@@ -978,9 +978,9 @@ checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
978
978
 
979
979
  [[package]]
980
980
  name = "simd-adler32"
981
- version = "0.3.9"
981
+ version = "0.3.10"
982
982
  source = "registry+https://github.com/rust-lang/crates.io-index"
983
- checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214"
983
+ checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea"
984
984
 
985
985
  [[package]]
986
986
  name = "slab"
@@ -996,9 +996,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
996
996
 
997
997
  [[package]]
998
998
  name = "syn"
999
- version = "2.0.118"
999
+ version = "2.0.119"
1000
1000
  source = "registry+https://github.com/rust-lang/crates.io-index"
1001
- checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422"
1001
+ checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
1002
1002
  dependencies = [
1003
1003
  "proc-macro2",
1004
1004
  "quote",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "beaconcrypt"
3
- version = "0.2.0"
3
+ version = "0.3.0"
4
4
  edition = "2024"
5
5
  license-file = "LICENSE"
6
6
  readme = "README.md"
@@ -10,7 +10,7 @@ repository = "https://github.com/0xd6cb6d73/beaconcrypt"
10
10
 
11
11
  [lib]
12
12
  name = "beaconcrypt"
13
- crate-type = ["cdylib", "rlib"]
13
+ crate-type = ["cdylib", "staticlib", "rlib"]
14
14
 
15
15
  [build-dependencies]
16
16
  capnpc = "0.26"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: beaconcrypt
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Classifier: Programming Language :: Rust
5
5
  Classifier: Programming Language :: Python :: Implementation :: CPython
6
6
  Classifier: Programming Language :: Python :: Implementation :: PyPy
@@ -0,0 +1,255 @@
1
+ // SPDX-License-Identifier: 0BSD
2
+
3
+ package beaconcrypt
4
+
5
+ /*
6
+ #cgo windows LDFLAGS: -L${SRCDIR}/target/x86_64-pc-windows-gnu/debug -l:libbeaconcrypt.a -lbcrypt -lws2_32 -luserenv -ldbghelp -lntdll
7
+ #cgo !windows LDFLAGS: -L${SRCDIR}/target/debug -l:libbeaconcrypt.a
8
+ #include <stdint.h>
9
+ #include <stdlib.h>
10
+
11
+ typedef struct {
12
+ uint8_t *ptr;
13
+ uintptr_t len;
14
+ uintptr_t cap;
15
+ } beaconcrypt_go_buffer;
16
+
17
+ typedef struct {
18
+ beaconcrypt_go_buffer response;
19
+ beaconcrypt_go_buffer beacon_pk;
20
+ uint64_t key_id;
21
+ } beaconcrypt_go_registration_response;
22
+
23
+ void beaconcrypt_go_free_buffer(beaconcrypt_go_buffer buffer);
24
+ void *beaconcrypt_go_server_new(uint64_t server_kid);
25
+ void *beaconcrypt_go_server_new_from_seed(uint64_t server_kid, const uint8_t *seed_ptr, uintptr_t seed_len);
26
+ void *beaconcrypt_go_beacon_new(uint64_t server_kid, const uint8_t *server_pk_ptr, uintptr_t server_pk_len);
27
+ void beaconcrypt_go_free(void *handle);
28
+ beaconcrypt_go_buffer beaconcrypt_go_identity_pk(const void *handle);
29
+ beaconcrypt_go_buffer beaconcrypt_go_generate_registration(void *handle);
30
+ beaconcrypt_go_registration_response beaconcrypt_go_register_beacon(void *handle, const uint8_t *reg_ptr, uintptr_t reg_len, const uint8_t *msg_ptr, uintptr_t msg_len);
31
+ beaconcrypt_go_buffer beaconcrypt_go_process_initial_message(void *handle, const uint8_t *ptr, uintptr_t len);
32
+ beaconcrypt_go_buffer beaconcrypt_go_encrypt_to_beacon(void *handle, uint64_t key_id, const uint8_t *ptr, uintptr_t len);
33
+ beaconcrypt_go_buffer beaconcrypt_go_encrypt_to_beacon_signed(void *handle, uint64_t key_id, const uint8_t *ptr, uintptr_t len);
34
+ beaconcrypt_go_buffer beaconcrypt_go_decrypt_beacon_message(void *handle, uint64_t key_id, const uint8_t *ptr, uintptr_t len);
35
+ beaconcrypt_go_buffer beaconcrypt_go_encrypt_to_server(void *handle, const uint8_t *ptr, uintptr_t len);
36
+ beaconcrypt_go_buffer beaconcrypt_go_decrypt_server_message(void *handle, const uint8_t *ptr, uintptr_t len);
37
+ beaconcrypt_go_buffer beaconcrypt_go_decrypt_server_message_signed(void *handle, const uint8_t *ptr, uintptr_t len);
38
+ */
39
+ import "C"
40
+
41
+ import (
42
+ "errors"
43
+ "runtime"
44
+ "unsafe"
45
+ )
46
+
47
+ var (
48
+ ErrClosed = errors.New("beaconcrypt: handle is closed")
49
+ ErrCrypto = errors.New("beaconcrypt: cryptographic operation failed")
50
+ ErrSeedSize = errors.New("beaconcrypt: server seed must be 32 bytes")
51
+ ErrEmptyData = errors.New("beaconcrypt: input must not be empty")
52
+ )
53
+
54
+ type Server struct {
55
+ handle unsafe.Pointer
56
+ }
57
+
58
+ type Beacon struct {
59
+ handle unsafe.Pointer
60
+ }
61
+
62
+ type RegistrationResponse struct {
63
+ Serialized []byte
64
+ BeaconPK []byte
65
+ KeyID uint64
66
+ }
67
+
68
+ func NewServer(serverKID uint64) (*Server, error) {
69
+ handle := C.beaconcrypt_go_server_new(C.uint64_t(serverKID))
70
+ if handle == nil {
71
+ return nil, ErrCrypto
72
+ }
73
+ server := &Server{handle: handle}
74
+ runtime.SetFinalizer(server, (*Server).Close)
75
+ return server, nil
76
+ }
77
+
78
+ func NewServerFromSeed(serverKID uint64, seed []byte) (*Server, error) {
79
+ if len(seed) != 32 {
80
+ return nil, ErrSeedSize
81
+ }
82
+ ptr, free := cBytes(seed)
83
+ defer free()
84
+ handle := C.beaconcrypt_go_server_new_from_seed(C.uint64_t(serverKID), ptr, C.uintptr_t(len(seed)))
85
+ if handle == nil {
86
+ return nil, ErrCrypto
87
+ }
88
+ server := &Server{handle: handle}
89
+ runtime.SetFinalizer(server, (*Server).Close)
90
+ return server, nil
91
+ }
92
+
93
+ func NewBeacon(serverKID uint64, serverPK []byte) (*Beacon, error) {
94
+ ptr, free := cBytes(serverPK)
95
+ defer free()
96
+ handle := C.beaconcrypt_go_beacon_new(C.uint64_t(serverKID), ptr, C.uintptr_t(len(serverPK)))
97
+ if handle == nil {
98
+ return nil, ErrCrypto
99
+ }
100
+ beacon := &Beacon{handle: handle}
101
+ runtime.SetFinalizer(beacon, (*Beacon).Close)
102
+ return beacon, nil
103
+ }
104
+
105
+ func (s *Server) Close() {
106
+ if s != nil && s.handle != nil {
107
+ C.beaconcrypt_go_free(s.handle)
108
+ s.handle = nil
109
+ runtime.SetFinalizer(s, nil)
110
+ }
111
+ }
112
+
113
+ func (b *Beacon) Close() {
114
+ if b != nil && b.handle != nil {
115
+ C.beaconcrypt_go_free(b.handle)
116
+ b.handle = nil
117
+ runtime.SetFinalizer(b, nil)
118
+ }
119
+ }
120
+
121
+ func (s *Server) IdentityPK() ([]byte, error) {
122
+ if s == nil || s.handle == nil {
123
+ return nil, ErrClosed
124
+ }
125
+ return copyBuffer(C.beaconcrypt_go_identity_pk(s.handle))
126
+ }
127
+
128
+ func (b *Beacon) GenerateRegistration() ([]byte, error) {
129
+ if b == nil || b.handle == nil {
130
+ return nil, ErrClosed
131
+ }
132
+ return copyBuffer(C.beaconcrypt_go_generate_registration(b.handle))
133
+ }
134
+
135
+ func (s *Server) RegisterBeacon(registration, initialMessage []byte) (*RegistrationResponse, error) {
136
+ if s == nil || s.handle == nil {
137
+ return nil, ErrClosed
138
+ }
139
+ if len(registration) == 0 {
140
+ return nil, ErrEmptyData
141
+ }
142
+ regPtr, regFree := cBytes(registration)
143
+ defer regFree()
144
+ msgPtr, msgFree := cBytes(initialMessage)
145
+ defer msgFree()
146
+ response := C.beaconcrypt_go_register_beacon(
147
+ s.handle,
148
+ regPtr,
149
+ C.uintptr_t(len(registration)),
150
+ msgPtr,
151
+ C.uintptr_t(len(initialMessage)),
152
+ )
153
+ serialized, err := copyBuffer(response.response)
154
+ if err != nil {
155
+ C.beaconcrypt_go_free_buffer(response.beacon_pk)
156
+ return nil, err
157
+ }
158
+ beaconPK, err := copyBuffer(response.beacon_pk)
159
+ if err != nil {
160
+ return nil, err
161
+ }
162
+ return &RegistrationResponse{
163
+ Serialized: serialized,
164
+ BeaconPK: beaconPK,
165
+ KeyID: uint64(response.key_id),
166
+ }, nil
167
+ }
168
+
169
+ func (b *Beacon) ProcessInitialMessage(data []byte) ([]byte, error) {
170
+ if b == nil || b.handle == nil {
171
+ return nil, ErrClosed
172
+ }
173
+ return callUnary(data, func(ptr *C.uint8_t, len C.uintptr_t) C.beaconcrypt_go_buffer {
174
+ return C.beaconcrypt_go_process_initial_message(b.handle, ptr, len)
175
+ })
176
+ }
177
+
178
+ func (s *Server) EncryptToBeacon(keyID uint64, plaintext []byte) ([]byte, error) {
179
+ if s == nil || s.handle == nil {
180
+ return nil, ErrClosed
181
+ }
182
+ return callUnary(plaintext, func(ptr *C.uint8_t, len C.uintptr_t) C.beaconcrypt_go_buffer {
183
+ return C.beaconcrypt_go_encrypt_to_beacon(s.handle, C.uint64_t(keyID), ptr, len)
184
+ })
185
+ }
186
+
187
+ func (s *Server) EncryptToBeaconSigned(keyID uint64, plaintext []byte) ([]byte, error) {
188
+ if s == nil || s.handle == nil {
189
+ return nil, ErrClosed
190
+ }
191
+ return callUnary(plaintext, func(ptr *C.uint8_t, len C.uintptr_t) C.beaconcrypt_go_buffer {
192
+ return C.beaconcrypt_go_encrypt_to_beacon_signed(s.handle, C.uint64_t(keyID), ptr, len)
193
+ })
194
+ }
195
+
196
+ func (s *Server) DecryptBeaconMessage(keyID uint64, ciphertext []byte) ([]byte, error) {
197
+ if s == nil || s.handle == nil {
198
+ return nil, ErrClosed
199
+ }
200
+ return callUnary(ciphertext, func(ptr *C.uint8_t, len C.uintptr_t) C.beaconcrypt_go_buffer {
201
+ return C.beaconcrypt_go_decrypt_beacon_message(s.handle, C.uint64_t(keyID), ptr, len)
202
+ })
203
+ }
204
+
205
+ func (b *Beacon) EncryptToServer(plaintext []byte) ([]byte, error) {
206
+ if b == nil || b.handle == nil {
207
+ return nil, ErrClosed
208
+ }
209
+ return callUnary(plaintext, func(ptr *C.uint8_t, len C.uintptr_t) C.beaconcrypt_go_buffer {
210
+ return C.beaconcrypt_go_encrypt_to_server(b.handle, ptr, len)
211
+ })
212
+ }
213
+
214
+ func (b *Beacon) DecryptServerMessage(ciphertext []byte) ([]byte, error) {
215
+ if b == nil || b.handle == nil {
216
+ return nil, ErrClosed
217
+ }
218
+ return callUnary(ciphertext, func(ptr *C.uint8_t, len C.uintptr_t) C.beaconcrypt_go_buffer {
219
+ return C.beaconcrypt_go_decrypt_server_message(b.handle, ptr, len)
220
+ })
221
+ }
222
+
223
+ func (b *Beacon) DecryptServerMessageSigned(ciphertext []byte) ([]byte, error) {
224
+ if b == nil || b.handle == nil {
225
+ return nil, ErrClosed
226
+ }
227
+ return callUnary(ciphertext, func(ptr *C.uint8_t, len C.uintptr_t) C.beaconcrypt_go_buffer {
228
+ return C.beaconcrypt_go_decrypt_server_message_signed(b.handle, ptr, len)
229
+ })
230
+ }
231
+
232
+ func callUnary(data []byte, call func(*C.uint8_t, C.uintptr_t) C.beaconcrypt_go_buffer) ([]byte, error) {
233
+ if len(data) == 0 {
234
+ return nil, ErrEmptyData
235
+ }
236
+ ptr, free := cBytes(data)
237
+ defer free()
238
+ return copyBuffer(call(ptr, C.uintptr_t(len(data))))
239
+ }
240
+
241
+ func copyBuffer(buffer C.beaconcrypt_go_buffer) ([]byte, error) {
242
+ if buffer.ptr == nil || buffer.len == 0 {
243
+ return nil, ErrCrypto
244
+ }
245
+ defer C.beaconcrypt_go_free_buffer(buffer)
246
+ return C.GoBytes(unsafe.Pointer(buffer.ptr), C.int(buffer.len)), nil
247
+ }
248
+
249
+ func cBytes(data []byte) (*C.uint8_t, func()) {
250
+ if len(data) == 0 {
251
+ return nil, func() {}
252
+ }
253
+ ptr := C.CBytes(data)
254
+ return (*C.uint8_t)(ptr), func() { C.free(ptr) }
255
+ }
@@ -0,0 +1,208 @@
1
+ // SPDX-License-Identifier: 0BSD
2
+
3
+ package beaconcrypt
4
+
5
+ import (
6
+ "bytes"
7
+ "testing"
8
+ )
9
+
10
+ func registerBeacon(t *testing.T, server *Server, beacon *Beacon) []byte {
11
+ t.Helper()
12
+
13
+ message := bytes.Repeat([]byte{0xff}, 32)
14
+ phase1, err := beacon.GenerateRegistration()
15
+ if err != nil {
16
+ t.Fatal(err)
17
+ }
18
+
19
+ regOut, err := server.RegisterBeacon(phase1, message)
20
+ if err != nil {
21
+ t.Fatal(err)
22
+ }
23
+ if regOut.KeyID == 0 {
24
+ t.Fatal("expected non-zero beacon key id")
25
+ }
26
+
27
+ phase2, err := beacon.ProcessInitialMessage(regOut.Serialized)
28
+ if err != nil {
29
+ t.Fatal(err)
30
+ }
31
+ if !bytes.Equal(phase2, message) {
32
+ t.Fatalf("initial message mismatch: got %x want %x", phase2, message)
33
+ }
34
+ return phase2
35
+ }
36
+
37
+ func newServer(t *testing.T) *Server {
38
+ t.Helper()
39
+
40
+ server, err := NewServer(0)
41
+ if err != nil {
42
+ t.Fatal(err)
43
+ }
44
+ t.Cleanup(server.Close)
45
+ return server
46
+ }
47
+
48
+ func newBeacon(t *testing.T, serverPK []byte) *Beacon {
49
+ t.Helper()
50
+
51
+ beacon, err := NewBeacon(0, serverPK)
52
+ if err != nil {
53
+ t.Fatal(err)
54
+ }
55
+ t.Cleanup(beacon.Close)
56
+ return beacon
57
+ }
58
+
59
+ func TestRegister(t *testing.T) {
60
+ server := newServer(t)
61
+ beacon := newBeacon(t, nil)
62
+
63
+ if registerBeacon(t, server, beacon) == nil {
64
+ t.Fatal("expected registration to return initial message")
65
+ }
66
+ }
67
+
68
+ func TestEncryptToMultiple(t *testing.T) {
69
+ server := newServer(t)
70
+ b1 := newBeacon(t, nil)
71
+ b2 := newBeacon(t, nil)
72
+ message := bytes.Repeat([]byte{0x01}, 32)
73
+
74
+ b1Initial := registerBeacon(t, server, b1)
75
+ b2Initial := registerBeacon(t, server, b2)
76
+ if !bytes.Equal(b2Initial, b1Initial) {
77
+ t.Fatalf("initial messages differ: got %x want %x", b2Initial, b1Initial)
78
+ }
79
+
80
+ b1M1, err := server.EncryptToBeacon(1, message)
81
+ if err != nil {
82
+ t.Fatal(err)
83
+ }
84
+ b2M1, err := server.EncryptToBeacon(2, message)
85
+ if err != nil {
86
+ t.Fatal(err)
87
+ }
88
+ if bytes.Equal(b1M1, b2M1) {
89
+ t.Fatal("expected different ciphertexts for different beacons")
90
+ }
91
+ }
92
+
93
+ func TestEncryptMultiple(t *testing.T) {
94
+ server := newServer(t)
95
+ b1 := newBeacon(t, nil)
96
+ message := bytes.Repeat([]byte{0x01}, 32)
97
+
98
+ registerBeacon(t, server, b1)
99
+
100
+ b1M1, err := server.EncryptToBeacon(1, message)
101
+ if err != nil {
102
+ t.Fatal(err)
103
+ }
104
+ b1M2, err := server.EncryptToBeacon(1, message)
105
+ if err != nil {
106
+ t.Fatal(err)
107
+ }
108
+ if bytes.Equal(b1M1, b1M2) {
109
+ t.Fatal("expected repeated encryption to produce different ciphertexts")
110
+ }
111
+ }
112
+
113
+ func TestDecryptMultiple(t *testing.T) {
114
+ server := newServer(t)
115
+ beacon := newBeacon(t, nil)
116
+ message := bytes.Repeat([]byte{0x01}, 32)
117
+
118
+ registerBeacon(t, server, beacon)
119
+ m1, err := server.EncryptToBeacon(1, message)
120
+ if err != nil {
121
+ t.Fatal(err)
122
+ }
123
+ m2, err := server.EncryptToBeacon(1, message)
124
+ if err != nil {
125
+ t.Fatal(err)
126
+ }
127
+ if bytes.Equal(m1, m2) {
128
+ t.Fatal("expected different ciphertexts")
129
+ }
130
+
131
+ plain1, err := beacon.DecryptServerMessage(m1)
132
+ if err != nil {
133
+ t.Fatal(err)
134
+ }
135
+ plain2, err := beacon.DecryptServerMessage(m2)
136
+ if err != nil {
137
+ t.Fatal(err)
138
+ }
139
+ if !bytes.Equal(plain1, message) || !bytes.Equal(plain2, message) {
140
+ t.Fatalf("decrypted messages mismatch: got %x and %x want %x", plain1, plain2, message)
141
+ }
142
+ }
143
+
144
+ func TestDecryptMultipleSigned(t *testing.T) {
145
+ server := newServer(t)
146
+ beacon := newBeacon(t, nil)
147
+ message := bytes.Repeat([]byte{0x01}, 32)
148
+
149
+ registerBeacon(t, server, beacon)
150
+ m1, err := server.EncryptToBeaconSigned(1, message)
151
+ if err != nil {
152
+ t.Fatal(err)
153
+ }
154
+ m2, err := server.EncryptToBeaconSigned(1, message)
155
+ if err != nil {
156
+ t.Fatal(err)
157
+ }
158
+ if bytes.Equal(m1, m2) {
159
+ t.Fatal("expected different signed ciphertexts")
160
+ }
161
+
162
+ plain1, err := beacon.DecryptServerMessageSigned(m1)
163
+ if err != nil {
164
+ t.Fatal(err)
165
+ }
166
+ plain2, err := beacon.DecryptServerMessageSigned(m2)
167
+ if err != nil {
168
+ t.Fatal(err)
169
+ }
170
+ if !bytes.Equal(plain1, message) || !bytes.Equal(plain2, message) {
171
+ t.Fatalf("decrypted signed messages mismatch: got %x and %x want %x", plain1, plain2, message)
172
+ }
173
+ }
174
+
175
+ func TestDecryptCatchUp(t *testing.T) {
176
+ server := newServer(t)
177
+ serverPK, err := server.IdentityPK()
178
+ if err != nil {
179
+ t.Fatal(err)
180
+ }
181
+ beacon := newBeacon(t, serverPK)
182
+ message := bytes.Repeat([]byte{0x01}, 32)
183
+
184
+ registerBeacon(t, server, beacon)
185
+ m1, err := server.EncryptToBeacon(1, message)
186
+ if err != nil {
187
+ t.Fatal(err)
188
+ }
189
+ m2, err := server.EncryptToBeacon(1, message)
190
+ if err != nil {
191
+ t.Fatal(err)
192
+ }
193
+ if bytes.Equal(m1, m2) {
194
+ t.Fatal("expected different ciphertexts")
195
+ }
196
+
197
+ plain2, err := beacon.DecryptServerMessage(m2)
198
+ if err != nil {
199
+ t.Fatal(err)
200
+ }
201
+ plain1, err := beacon.DecryptServerMessage(m1)
202
+ if err != nil {
203
+ t.Fatal(err)
204
+ }
205
+ if !bytes.Equal(plain1, message) || !bytes.Equal(plain2, message) {
206
+ t.Fatalf("catch-up decrypt mismatch: got %x and %x want %x", plain1, plain2, message)
207
+ }
208
+ }
@@ -47,6 +47,20 @@
47
47
 
48
48
  #define beaconcrypt_KEM_SHARED_SECRET_SIZE 32
49
49
 
50
+ typedef struct beaconcrypt_BeaconCryptPqxdh beaconcrypt_BeaconCryptPqxdh;
51
+
52
+ typedef struct beaconcrypt_GoBuffer {
53
+ uint8_t *ptr;
54
+ uintptr_t len;
55
+ uintptr_t cap;
56
+ } beaconcrypt_GoBuffer;
57
+
58
+ typedef struct beaconcrypt_GoRegistrationResponse {
59
+ struct beaconcrypt_GoBuffer response;
60
+ struct beaconcrypt_GoBuffer beacon_pk;
61
+ uint64_t key_id;
62
+ } beaconcrypt_GoRegistrationResponse;
63
+
50
64
  #ifdef __cplusplus
51
65
  extern "C" {
52
66
  #endif // __cplusplus
@@ -398,6 +412,61 @@ int32_t sign_message(const uint8_t *bytes,
398
412
  uintptr_t *out_len,
399
413
  uintptr_t *out_capa);
400
414
 
415
+ void beaconcrypt_go_free_buffer(struct beaconcrypt_GoBuffer buffer);
416
+
417
+ struct beaconcrypt_BeaconCryptPqxdh *beaconcrypt_go_server_new(uint64_t server_kid);
418
+
419
+ struct beaconcrypt_BeaconCryptPqxdh *beaconcrypt_go_server_new_from_seed(uint64_t server_kid,
420
+ const uint8_t *seed_ptr,
421
+ uintptr_t seed_len);
422
+
423
+ struct beaconcrypt_BeaconCryptPqxdh *beaconcrypt_go_beacon_new(uint64_t server_kid,
424
+ const uint8_t *server_pk_ptr,
425
+ uintptr_t server_pk_len);
426
+
427
+ void beaconcrypt_go_free(struct beaconcrypt_BeaconCryptPqxdh *handle);
428
+
429
+ struct beaconcrypt_GoBuffer beaconcrypt_go_identity_pk(const struct beaconcrypt_BeaconCryptPqxdh *handle);
430
+
431
+ struct beaconcrypt_GoBuffer beaconcrypt_go_generate_registration(struct beaconcrypt_BeaconCryptPqxdh *handle);
432
+
433
+ struct beaconcrypt_GoRegistrationResponse beaconcrypt_go_register_beacon(struct beaconcrypt_BeaconCryptPqxdh *handle,
434
+ const uint8_t *reg_ptr,
435
+ uintptr_t reg_len,
436
+ const uint8_t *msg_ptr,
437
+ uintptr_t msg_len);
438
+
439
+ struct beaconcrypt_GoBuffer beaconcrypt_go_process_initial_message(struct beaconcrypt_BeaconCryptPqxdh *handle,
440
+ const uint8_t *ptr,
441
+ uintptr_t len);
442
+
443
+ struct beaconcrypt_GoBuffer beaconcrypt_go_encrypt_to_beacon(struct beaconcrypt_BeaconCryptPqxdh *handle,
444
+ uint64_t key_id,
445
+ const uint8_t *ptr,
446
+ uintptr_t len);
447
+
448
+ struct beaconcrypt_GoBuffer beaconcrypt_go_encrypt_to_beacon_signed(struct beaconcrypt_BeaconCryptPqxdh *handle,
449
+ uint64_t key_id,
450
+ const uint8_t *ptr,
451
+ uintptr_t len);
452
+
453
+ struct beaconcrypt_GoBuffer beaconcrypt_go_decrypt_beacon_message(struct beaconcrypt_BeaconCryptPqxdh *handle,
454
+ uint64_t key_id,
455
+ const uint8_t *ptr,
456
+ uintptr_t len);
457
+
458
+ struct beaconcrypt_GoBuffer beaconcrypt_go_encrypt_to_server(struct beaconcrypt_BeaconCryptPqxdh *handle,
459
+ const uint8_t *ptr,
460
+ uintptr_t len);
461
+
462
+ struct beaconcrypt_GoBuffer beaconcrypt_go_decrypt_server_message(struct beaconcrypt_BeaconCryptPqxdh *handle,
463
+ const uint8_t *ptr,
464
+ uintptr_t len);
465
+
466
+ struct beaconcrypt_GoBuffer beaconcrypt_go_decrypt_server_message_signed(struct beaconcrypt_BeaconCryptPqxdh *handle,
467
+ const uint8_t *ptr,
468
+ uintptr_t len);
469
+
401
470
  #ifdef __cplusplus
402
471
  } // extern "C"
403
472
  #endif // __cplusplus
@@ -1,6 +1,10 @@
1
1
  // SPDX-License-Identifier: 0BSD
2
2
 
3
3
  fn main() {
4
+ if cfg!(windows) {
5
+ println!("cargo:rustc-link-lib=bcrypt");
6
+ }
7
+
4
8
  capnpc::CompilerCommand::new()
5
9
  .src_prefix("src/schema")
6
10
  .import_path("src/schema")
@@ -26,6 +30,8 @@ fn main() {
26
30
  .with_autogen_warning("// Do not modify manually.")
27
31
  .with_item_prefix("beaconcrypt_")
28
32
  .with_std_types(true)
33
+ .exclude_item("memset_explicit")
34
+ .exclude_item("SystemFunction036")
29
35
  .generate()
30
36
  .expect("Unable to generate bindings")
31
37
  .write_to_file("bindings.h");