beaconcrypt 0.2.0__tar.gz → 0.3.1__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.1/.github/workflows/go.yml +136 -0
  2. {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/.github/workflows/python.yml +1 -1
  3. {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/.github/workflows/release.yml +2 -1
  4. {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/.gitignore +5 -0
  5. {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/Cargo.lock +13 -13
  6. {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/Cargo.toml +2 -2
  7. {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/PKG-INFO +1 -1
  8. {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/README.md +5 -0
  9. beaconcrypt-0.3.1/beaconcrypt.go +256 -0
  10. beaconcrypt-0.3.1/beaconcrypt_test.go +208 -0
  11. {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/bindings.h +69 -0
  12. {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/build.rs +6 -0
  13. beaconcrypt-0.3.1/go.mod +3 -0
  14. beaconcrypt-0.3.1/src/lib.rs +519 -0
  15. beaconcrypt-0.2.0/src/lib.rs +0 -167
  16. {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/.cargo/config.toml +0 -0
  17. {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/.github/workflows/rust.yml +0 -0
  18. {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/LICENSE +0 -0
  19. {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/clippy.toml +0 -0
  20. {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/doc/protocol.md +0 -0
  21. {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/doc/rationale.md +0 -0
  22. {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/doc/threat_model.md +0 -0
  23. {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/pyproject.toml +0 -0
  24. {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/rustfmt.toml +0 -0
  25. {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/src/beacon.rs +0 -0
  26. {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/src/cnsa2.rs +0 -0
  27. {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/src/error.rs +0 -0
  28. {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/src/pqxdh.rs +0 -0
  29. {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/src/schema/cryptoframe.capnp +0 -0
  30. {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/src/schema/phase1.capnp +0 -0
  31. {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/src/schema/phase2.capnp +0 -0
  32. {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/src/schema/protogram.capnp +0 -0
  33. {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/src/server.rs +0 -0
  34. {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/src/shared.rs +0 -0
  35. {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/tests/beacon.rs +0 -0
  36. {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/tests/server.rs +0 -0
  37. {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/tests/test_encryption.py +0 -0
  38. {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/tests/test_registration.py +0 -0
  39. {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/uv.lock +0 -0
@@ -0,0 +1,136 @@
1
+ name: Go Module
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "[0-9]*.[0-9]*.[0-9]*"
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
+ test:
18
+ name: Test Go module on ${{ matrix.os }}
19
+ runs-on: ${{ matrix.os }}
20
+ strategy:
21
+ fail-fast: false
22
+ matrix:
23
+ os:
24
+ - ubuntu-latest
25
+ - ubuntu-24.04-arm
26
+ - macos-latest
27
+ - windows-latest
28
+
29
+ steps:
30
+ - uses: actions/checkout@v7
31
+
32
+ - name: Set up Go
33
+ uses: actions/setup-go@v6
34
+ with:
35
+ go-version-file: go.mod
36
+ check-latest: true
37
+
38
+ - name: Set up MinGW on Windows
39
+ if: runner.os == 'Windows'
40
+ uses: msys2/setup-msys2@v2
41
+ with:
42
+ install: mingw-w64-x86_64-gcc
43
+
44
+ - name: Install cap'n proto on Linux
45
+ if: runner.os == 'Linux'
46
+ run: sudo apt update && sudo apt install capnproto
47
+
48
+ - name: Install cap'n proto on macOS
49
+ if: runner.os == 'macOS'
50
+ run: brew install capnp
51
+
52
+ - name: Install cap'n proto on Windows
53
+ if: runner.os == 'Windows'
54
+ run: |
55
+ "C:\msys64\mingw64\bin" >> $env:GITHUB_PATH
56
+ curl.exe -O https://capnproto.org/capnproto-c++-win32-1.5.0.zip
57
+ Expand-Archive capnproto-c++-win32-1.5.0.zip
58
+ "$pwd\capnproto-c++-win32-1.5.0\capnproto-tools-win32-1.5.0" >> $env:GITHUB_PATH
59
+
60
+ - name: Build native library
61
+ if: runner.os != 'Windows'
62
+ run: cargo build --verbose
63
+
64
+ - name: Build native library on Windows
65
+ if: runner.os == 'Windows'
66
+ env:
67
+ CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER: gcc
68
+ run: |
69
+ rustup target add x86_64-pc-windows-gnu
70
+ cargo build --verbose --target x86_64-pc-windows-gnu
71
+
72
+ - name: Test Go module
73
+ if: runner.os != 'Windows'
74
+ env:
75
+ CGO_ENABLED: 1
76
+ run: go test ./...
77
+
78
+ - name: Test Go module on Windows
79
+ if: runner.os == 'Windows'
80
+ env:
81
+ CGO_ENABLED: 1
82
+ CC: gcc
83
+ run: go test ./...
84
+
85
+ publish:
86
+ needs: test
87
+ runs-on: ubuntu-latest
88
+ permissions:
89
+ contents: write
90
+
91
+ steps:
92
+ - uses: actions/checkout@v7
93
+ with:
94
+ fetch-depth: 0
95
+
96
+ - name: Set up Go
97
+ uses: actions/setup-go@v6
98
+ with:
99
+ go-version-file: go.mod
100
+ check-latest: true
101
+
102
+ - name: Publish module to Go proxy
103
+ run: |
104
+ module_path="$(go list -m)"
105
+ version="${GITHUB_REF_NAME}"
106
+ go_version="v${version}"
107
+
108
+ git fetch origin "refs/tags/${go_version}:refs/tags/${go_version}" || true
109
+ if ! git rev-parse --verify --quiet "refs/tags/${go_version}" >/dev/null; then
110
+ git tag "${go_version}" "${GITHUB_SHA}"
111
+ git push origin "refs/tags/${go_version}"
112
+ fi
113
+
114
+ tag_visible=false
115
+ for attempt in {1..30}; do
116
+ if git ls-remote --exit-code --tags origin "refs/tags/${go_version}" >/dev/null; then
117
+ tag_visible=true
118
+ break
119
+ fi
120
+ sleep 10
121
+ done
122
+ if [ "${tag_visible}" != "true" ]; then
123
+ echo "Timed out waiting for ${go_version} to become visible on origin" >&2
124
+ exit 1
125
+ fi
126
+
127
+ GOPROXY=direct go list -m "${module_path}@${go_version}"
128
+
129
+ for attempt in {1..30}; do
130
+ if go list -m "${module_path}@${go_version}"; then
131
+ exit 0
132
+ fi
133
+ sleep 10
134
+ done
135
+
136
+ go list -m "${module_path}@${go_version}"
@@ -11,7 +11,7 @@ name: Upload Python Package
11
11
  on:
12
12
  push:
13
13
  tags:
14
- - "**"
14
+ - "[0-9]*.[0-9]*.[0-9]*"
15
15
 
16
16
  permissions:
17
17
  contents: read
@@ -2,7 +2,8 @@ name: Release
2
2
 
3
3
  on:
4
4
  push:
5
- tags: '*'
5
+ tags:
6
+ - "[0-9]*.[0-9]*.[0-9]*"
6
7
 
7
8
  env:
8
9
  CARGO_TERM_COLOR: always
@@ -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.1"
88
88
  dependencies = [
89
89
  "capnp",
90
90
  "capnpc",
@@ -99,9 +99,9 @@ dependencies = [
99
99
 
100
100
  [[package]]
101
101
  name = "bitflags"
102
- version = "2.13.0"
102
+ version = "2.13.1"
103
103
  source = "registry+https://github.com/rust-lang/crates.io-index"
104
- checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8"
104
+ checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da"
105
105
 
106
106
  [[package]]
107
107
  name = "bumpalo"
@@ -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",
@@ -1166,9 +1166,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
1166
1166
 
1167
1167
  [[package]]
1168
1168
  name = "uuid"
1169
- version = "1.23.5"
1169
+ version = "1.24.0"
1170
1170
  source = "registry+https://github.com/rust-lang/crates.io-index"
1171
- checksum = "ea5fab0d6c3c01ae70085a09cb03d4c7a1d6314e2b3e075392783396d724ca0a"
1171
+ checksum = "bf3923a6f5c4c6382e0b653c4117f48d631ea17f38ed86e2a828e6f7412f5239"
1172
1172
  dependencies = [
1173
1173
  "getrandom",
1174
1174
  "js-sys",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "beaconcrypt"
3
- version = "0.2.0"
3
+ version = "0.3.1"
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.1
4
4
  Classifier: Programming Language :: Rust
5
5
  Classifier: Programming Language :: Python :: Implementation :: CPython
6
6
  Classifier: Programming Language :: Python :: Implementation :: PyPy
@@ -46,6 +46,11 @@ Test the C interface
46
46
  # Reference implementation
47
47
  I don't use rust a lot, so the code is probably fairly naive. It provides both a beacon and server implementation with C bindings through `cbindgen`. Ideally more bindings would be built on top of that so it can be used in the mythic server-side.
48
48
 
49
+ ## Building
50
+ You will need [Capn'Proto](https://capnproto.org/install.html) (just the binaries) and a recent version of rust for every build.
51
+
52
+ For windows, I prefer building with stable-gnu for normal usage, and nightly-gnu for release builds. You can find the exact arguments I use to the the static library as small as possible in [release.yml](/.github\workflows\release.yml). The MSVC toolchain is expected to work just as well, I just like mingw.
53
+
49
54
  ## Profiles
50
55
  The reference implementation has two profiles: `PQXDH` and `CNSA2`. Profiles are controlled by cargo features. The CNSA2 profile only exists as a test for now. It uses a simple ML-KEM encapsulation for key exchange and the underlying libraries are not FIPS-approved. It is experimental and is likely broken. PQXDH is the intended target and the default.
51
56
 
@@ -0,0 +1,256 @@
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 linux LDFLAGS: -L${SRCDIR}/target/debug -l:libbeaconcrypt.a
8
+ #cgo darwin LDFLAGS: ${SRCDIR}/target/debug/libbeaconcrypt.a
9
+ #include <stdint.h>
10
+ #include <stdlib.h>
11
+
12
+ typedef struct {
13
+ uint8_t *ptr;
14
+ uintptr_t len;
15
+ uintptr_t cap;
16
+ } beaconcrypt_go_buffer;
17
+
18
+ typedef struct {
19
+ beaconcrypt_go_buffer response;
20
+ beaconcrypt_go_buffer beacon_pk;
21
+ uint64_t key_id;
22
+ } beaconcrypt_go_registration_response;
23
+
24
+ void beaconcrypt_go_free_buffer(beaconcrypt_go_buffer buffer);
25
+ void *beaconcrypt_go_server_new(uint64_t server_kid);
26
+ void *beaconcrypt_go_server_new_from_seed(uint64_t server_kid, const uint8_t *seed_ptr, uintptr_t seed_len);
27
+ void *beaconcrypt_go_beacon_new(uint64_t server_kid, const uint8_t *server_pk_ptr, uintptr_t server_pk_len);
28
+ void beaconcrypt_go_free(void *handle);
29
+ beaconcrypt_go_buffer beaconcrypt_go_identity_pk(const void *handle);
30
+ beaconcrypt_go_buffer beaconcrypt_go_generate_registration(void *handle);
31
+ 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);
32
+ beaconcrypt_go_buffer beaconcrypt_go_process_initial_message(void *handle, const uint8_t *ptr, uintptr_t len);
33
+ beaconcrypt_go_buffer beaconcrypt_go_encrypt_to_beacon(void *handle, uint64_t key_id, const uint8_t *ptr, uintptr_t len);
34
+ beaconcrypt_go_buffer beaconcrypt_go_encrypt_to_beacon_signed(void *handle, uint64_t key_id, const uint8_t *ptr, uintptr_t len);
35
+ beaconcrypt_go_buffer beaconcrypt_go_decrypt_beacon_message(void *handle, uint64_t key_id, const uint8_t *ptr, uintptr_t len);
36
+ beaconcrypt_go_buffer beaconcrypt_go_encrypt_to_server(void *handle, const uint8_t *ptr, uintptr_t len);
37
+ beaconcrypt_go_buffer beaconcrypt_go_decrypt_server_message(void *handle, const uint8_t *ptr, uintptr_t len);
38
+ beaconcrypt_go_buffer beaconcrypt_go_decrypt_server_message_signed(void *handle, const uint8_t *ptr, uintptr_t len);
39
+ */
40
+ import "C"
41
+
42
+ import (
43
+ "errors"
44
+ "runtime"
45
+ "unsafe"
46
+ )
47
+
48
+ var (
49
+ ErrClosed = errors.New("beaconcrypt: handle is closed")
50
+ ErrCrypto = errors.New("beaconcrypt: cryptographic operation failed")
51
+ ErrSeedSize = errors.New("beaconcrypt: server seed must be 32 bytes")
52
+ ErrEmptyData = errors.New("beaconcrypt: input must not be empty")
53
+ )
54
+
55
+ type Server struct {
56
+ handle unsafe.Pointer
57
+ }
58
+
59
+ type Beacon struct {
60
+ handle unsafe.Pointer
61
+ }
62
+
63
+ type RegistrationResponse struct {
64
+ Serialized []byte
65
+ BeaconPK []byte
66
+ KeyID uint64
67
+ }
68
+
69
+ func NewServer(serverKID uint64) (*Server, error) {
70
+ handle := C.beaconcrypt_go_server_new(C.uint64_t(serverKID))
71
+ if handle == nil {
72
+ return nil, ErrCrypto
73
+ }
74
+ server := &Server{handle: handle}
75
+ runtime.SetFinalizer(server, (*Server).Close)
76
+ return server, nil
77
+ }
78
+
79
+ func NewServerFromSeed(serverKID uint64, seed []byte) (*Server, error) {
80
+ if len(seed) != 32 {
81
+ return nil, ErrSeedSize
82
+ }
83
+ ptr, free := cBytes(seed)
84
+ defer free()
85
+ handle := C.beaconcrypt_go_server_new_from_seed(C.uint64_t(serverKID), ptr, C.uintptr_t(len(seed)))
86
+ if handle == nil {
87
+ return nil, ErrCrypto
88
+ }
89
+ server := &Server{handle: handle}
90
+ runtime.SetFinalizer(server, (*Server).Close)
91
+ return server, nil
92
+ }
93
+
94
+ func NewBeacon(serverKID uint64, serverPK []byte) (*Beacon, error) {
95
+ ptr, free := cBytes(serverPK)
96
+ defer free()
97
+ handle := C.beaconcrypt_go_beacon_new(C.uint64_t(serverKID), ptr, C.uintptr_t(len(serverPK)))
98
+ if handle == nil {
99
+ return nil, ErrCrypto
100
+ }
101
+ beacon := &Beacon{handle: handle}
102
+ runtime.SetFinalizer(beacon, (*Beacon).Close)
103
+ return beacon, nil
104
+ }
105
+
106
+ func (s *Server) Close() {
107
+ if s != nil && s.handle != nil {
108
+ C.beaconcrypt_go_free(s.handle)
109
+ s.handle = nil
110
+ runtime.SetFinalizer(s, nil)
111
+ }
112
+ }
113
+
114
+ func (b *Beacon) Close() {
115
+ if b != nil && b.handle != nil {
116
+ C.beaconcrypt_go_free(b.handle)
117
+ b.handle = nil
118
+ runtime.SetFinalizer(b, nil)
119
+ }
120
+ }
121
+
122
+ func (s *Server) IdentityPK() ([]byte, error) {
123
+ if s == nil || s.handle == nil {
124
+ return nil, ErrClosed
125
+ }
126
+ return copyBuffer(C.beaconcrypt_go_identity_pk(s.handle))
127
+ }
128
+
129
+ func (b *Beacon) GenerateRegistration() ([]byte, error) {
130
+ if b == nil || b.handle == nil {
131
+ return nil, ErrClosed
132
+ }
133
+ return copyBuffer(C.beaconcrypt_go_generate_registration(b.handle))
134
+ }
135
+
136
+ func (s *Server) RegisterBeacon(registration, initialMessage []byte) (*RegistrationResponse, error) {
137
+ if s == nil || s.handle == nil {
138
+ return nil, ErrClosed
139
+ }
140
+ if len(registration) == 0 {
141
+ return nil, ErrEmptyData
142
+ }
143
+ regPtr, regFree := cBytes(registration)
144
+ defer regFree()
145
+ msgPtr, msgFree := cBytes(initialMessage)
146
+ defer msgFree()
147
+ response := C.beaconcrypt_go_register_beacon(
148
+ s.handle,
149
+ regPtr,
150
+ C.uintptr_t(len(registration)),
151
+ msgPtr,
152
+ C.uintptr_t(len(initialMessage)),
153
+ )
154
+ serialized, err := copyBuffer(response.response)
155
+ if err != nil {
156
+ C.beaconcrypt_go_free_buffer(response.beacon_pk)
157
+ return nil, err
158
+ }
159
+ beaconPK, err := copyBuffer(response.beacon_pk)
160
+ if err != nil {
161
+ return nil, err
162
+ }
163
+ return &RegistrationResponse{
164
+ Serialized: serialized,
165
+ BeaconPK: beaconPK,
166
+ KeyID: uint64(response.key_id),
167
+ }, nil
168
+ }
169
+
170
+ func (b *Beacon) ProcessInitialMessage(data []byte) ([]byte, error) {
171
+ if b == nil || b.handle == nil {
172
+ return nil, ErrClosed
173
+ }
174
+ return callUnary(data, func(ptr *C.uint8_t, len C.uintptr_t) C.beaconcrypt_go_buffer {
175
+ return C.beaconcrypt_go_process_initial_message(b.handle, ptr, len)
176
+ })
177
+ }
178
+
179
+ func (s *Server) EncryptToBeacon(keyID uint64, plaintext []byte) ([]byte, error) {
180
+ if s == nil || s.handle == nil {
181
+ return nil, ErrClosed
182
+ }
183
+ return callUnary(plaintext, func(ptr *C.uint8_t, len C.uintptr_t) C.beaconcrypt_go_buffer {
184
+ return C.beaconcrypt_go_encrypt_to_beacon(s.handle, C.uint64_t(keyID), ptr, len)
185
+ })
186
+ }
187
+
188
+ func (s *Server) EncryptToBeaconSigned(keyID uint64, plaintext []byte) ([]byte, error) {
189
+ if s == nil || s.handle == nil {
190
+ return nil, ErrClosed
191
+ }
192
+ return callUnary(plaintext, func(ptr *C.uint8_t, len C.uintptr_t) C.beaconcrypt_go_buffer {
193
+ return C.beaconcrypt_go_encrypt_to_beacon_signed(s.handle, C.uint64_t(keyID), ptr, len)
194
+ })
195
+ }
196
+
197
+ func (s *Server) DecryptBeaconMessage(keyID uint64, ciphertext []byte) ([]byte, error) {
198
+ if s == nil || s.handle == nil {
199
+ return nil, ErrClosed
200
+ }
201
+ return callUnary(ciphertext, func(ptr *C.uint8_t, len C.uintptr_t) C.beaconcrypt_go_buffer {
202
+ return C.beaconcrypt_go_decrypt_beacon_message(s.handle, C.uint64_t(keyID), ptr, len)
203
+ })
204
+ }
205
+
206
+ func (b *Beacon) EncryptToServer(plaintext []byte) ([]byte, error) {
207
+ if b == nil || b.handle == nil {
208
+ return nil, ErrClosed
209
+ }
210
+ return callUnary(plaintext, func(ptr *C.uint8_t, len C.uintptr_t) C.beaconcrypt_go_buffer {
211
+ return C.beaconcrypt_go_encrypt_to_server(b.handle, ptr, len)
212
+ })
213
+ }
214
+
215
+ func (b *Beacon) DecryptServerMessage(ciphertext []byte) ([]byte, error) {
216
+ if b == nil || b.handle == nil {
217
+ return nil, ErrClosed
218
+ }
219
+ return callUnary(ciphertext, func(ptr *C.uint8_t, len C.uintptr_t) C.beaconcrypt_go_buffer {
220
+ return C.beaconcrypt_go_decrypt_server_message(b.handle, ptr, len)
221
+ })
222
+ }
223
+
224
+ func (b *Beacon) DecryptServerMessageSigned(ciphertext []byte) ([]byte, error) {
225
+ if b == nil || b.handle == nil {
226
+ return nil, ErrClosed
227
+ }
228
+ return callUnary(ciphertext, func(ptr *C.uint8_t, len C.uintptr_t) C.beaconcrypt_go_buffer {
229
+ return C.beaconcrypt_go_decrypt_server_message_signed(b.handle, ptr, len)
230
+ })
231
+ }
232
+
233
+ func callUnary(data []byte, call func(*C.uint8_t, C.uintptr_t) C.beaconcrypt_go_buffer) ([]byte, error) {
234
+ if len(data) == 0 {
235
+ return nil, ErrEmptyData
236
+ }
237
+ ptr, free := cBytes(data)
238
+ defer free()
239
+ return copyBuffer(call(ptr, C.uintptr_t(len(data))))
240
+ }
241
+
242
+ func copyBuffer(buffer C.beaconcrypt_go_buffer) ([]byte, error) {
243
+ if buffer.ptr == nil || buffer.len == 0 {
244
+ return nil, ErrCrypto
245
+ }
246
+ defer C.beaconcrypt_go_free_buffer(buffer)
247
+ return C.GoBytes(unsafe.Pointer(buffer.ptr), C.int(buffer.len)), nil
248
+ }
249
+
250
+ func cBytes(data []byte) (*C.uint8_t, func()) {
251
+ if len(data) == 0 {
252
+ return nil, func() {}
253
+ }
254
+ ptr := C.CBytes(data)
255
+ return (*C.uint8_t)(ptr), func() { C.free(ptr) }
256
+ }