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.
- beaconcrypt-0.3.1/.github/workflows/go.yml +136 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/.github/workflows/python.yml +1 -1
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/.github/workflows/release.yml +2 -1
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/.gitignore +5 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/Cargo.lock +13 -13
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/Cargo.toml +2 -2
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/PKG-INFO +1 -1
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/README.md +5 -0
- beaconcrypt-0.3.1/beaconcrypt.go +256 -0
- beaconcrypt-0.3.1/beaconcrypt_test.go +208 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/bindings.h +69 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/build.rs +6 -0
- beaconcrypt-0.3.1/go.mod +3 -0
- beaconcrypt-0.3.1/src/lib.rs +519 -0
- beaconcrypt-0.2.0/src/lib.rs +0 -167
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/.cargo/config.toml +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/.github/workflows/rust.yml +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/LICENSE +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/clippy.toml +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/doc/protocol.md +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/doc/rationale.md +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/doc/threat_model.md +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/pyproject.toml +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/rustfmt.toml +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/src/beacon.rs +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/src/cnsa2.rs +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/src/error.rs +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/src/pqxdh.rs +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/src/schema/cryptoframe.capnp +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/src/schema/phase1.capnp +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/src/schema/phase2.capnp +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/src/schema/protogram.capnp +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/src/server.rs +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/src/shared.rs +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/tests/beacon.rs +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/tests/server.rs +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/tests/test_encryption.py +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.1}/tests/test_registration.py +0 -0
- {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}"
|
|
@@ -84,7 +84,7 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
|
|
84
84
|
|
|
85
85
|
[[package]]
|
|
86
86
|
name = "beaconcrypt"
|
|
87
|
-
version = "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.
|
|
102
|
+
version = "2.13.1"
|
|
103
103
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
104
|
-
checksum = "
|
|
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.
|
|
184
|
+
version = "4.6.2"
|
|
185
185
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
186
|
-
checksum = "
|
|
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.
|
|
193
|
+
version = "4.6.2"
|
|
194
194
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
195
|
-
checksum = "
|
|
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.
|
|
981
|
+
version = "0.3.10"
|
|
982
982
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
983
|
-
checksum = "
|
|
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.
|
|
999
|
+
version = "2.0.119"
|
|
1000
1000
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1001
|
-
checksum = "
|
|
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.
|
|
1169
|
+
version = "1.24.0"
|
|
1170
1170
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1171
|
-
checksum = "
|
|
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.
|
|
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"
|
|
@@ -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
|
+
}
|