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.
- beaconcrypt-0.3.0/.github/workflows/go.yml +44 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/.gitignore +5 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/Cargo.lock +9 -9
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/Cargo.toml +2 -2
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/PKG-INFO +1 -1
- beaconcrypt-0.3.0/beaconcrypt.go +255 -0
- beaconcrypt-0.3.0/beaconcrypt_test.go +208 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/bindings.h +69 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/build.rs +6 -0
- beaconcrypt-0.3.0/go.mod +3 -0
- beaconcrypt-0.3.0/src/lib.rs +519 -0
- beaconcrypt-0.2.0/src/lib.rs +0 -167
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/.cargo/config.toml +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/.github/workflows/python.yml +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/.github/workflows/release.yml +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/.github/workflows/rust.yml +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/LICENSE +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/README.md +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/clippy.toml +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/doc/protocol.md +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/doc/rationale.md +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/doc/threat_model.md +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/pyproject.toml +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/rustfmt.toml +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/src/beacon.rs +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/src/cnsa2.rs +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/src/error.rs +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/src/pqxdh.rs +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/src/schema/cryptoframe.capnp +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/src/schema/phase1.capnp +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/src/schema/phase2.capnp +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/src/schema/protogram.capnp +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/src/server.rs +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/src/shared.rs +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/tests/beacon.rs +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/tests/server.rs +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/tests/test_encryption.py +0 -0
- {beaconcrypt-0.2.0 → beaconcrypt-0.3.0}/tests/test_registration.py +0 -0
- {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"
|
|
@@ -84,7 +84,7 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
|
|
84
84
|
|
|
85
85
|
[[package]]
|
|
86
86
|
name = "beaconcrypt"
|
|
87
|
-
version = "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.
|
|
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",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "beaconcrypt"
|
|
3
|
-
version = "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"
|
|
@@ -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");
|