Skip to content

Commit e0d70fe

Browse files
committed
cbor: support deriving en/decoder for arrays/maps from structs
1 parent 4c89985 commit e0d70fe

File tree

9 files changed

+528
-320
lines changed

9 files changed

+528
-320
lines changed

Cargo.lock

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ rustdoc-args = ["--cfg", "docsrs"]
1818
default = []
1919
argon2 = ["dep:argon2"]
2020
async = ["dep:futures"]
21-
cbor = ["dep:thiserror"]
21+
cbor = ["dep:thiserror", "dep:darkbio-crypto-cbor-derive"]
2222
cose = ["cbor", "xhpke"]
2323
eddsa = ["pem", "dep:ed25519-dalek", "dep:sha2", "dep:signature"]
2424
hkdf = ["dep:hkdf", "dep:sha2"]
@@ -32,6 +32,7 @@ xdsa = ["pem", "eddsa", "mldsa", "x509", "dep:x509-parser"]
3232
xhpke = ["pem", "xdsa", "dep:generic-array", "dep:hpke", "dep:rand", "dep:rand_chacha", "dep:x-wing"]
3333

3434
[dependencies]
35+
darkbio-crypto-cbor-derive = { version = "0.11.0", path = "src/cbor/derive", optional = true }
3536
age-core = { version = "0.11.0", optional = true }
3637
argon2 = { version = "0.5.3", optional = true }
3738
base64 = { version = "0.22.1", optional = true }

src/cbor/derive/Cargo.toml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[package]
2+
name = "darkbio-crypto-cbor-derive"
3+
version = "0.11.0"
4+
authors = ["Péter Szilágyi <peter@dark.bio>"]
5+
description = "CBOR derive macros for darkbio-crypto"
6+
repository = "https://github.com/dark-bio/crypto-rs"
7+
license = "BSD-3-Clause"
8+
edition = "2024"
9+
10+
[lib]
11+
proc-macro = true
12+
13+
[dependencies]
14+
proc-macro2 = "1.0"
15+
quote = "1.0"
16+
syn = { version = "2.0", features = ["full", "extra-traits"] }

src/cbor/derive/src/cbor.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// crypto-rs: cryptography primitives and wrappers
2+
// Copyright 2025 Dark Bio AG. All rights reserved.
3+
//
4+
// Use of this source code is governed by a BSD-style
5+
// license that can be found in the LICENSE file.
6+
7+
//! CBOR encoding helpers for compile-time key sorting.
8+
9+
/// Encodes an integer key to its CBOR byte representation for sorting.
10+
/// Positive integers use major type 0, negative use major type 1.
11+
pub fn cbor_key_bytes(key: i64) -> Vec<u8> {
12+
let mut buf = Vec::new();
13+
if key >= 0 {
14+
let val = key as u64;
15+
encode_length(&mut buf, 0, val);
16+
} else {
17+
let val = (-1 - key) as u64;
18+
encode_length(&mut buf, 1, val);
19+
}
20+
buf
21+
}
22+
23+
/// Encodes a CBOR type header with major type and length/value.
24+
/// Uses the minimal encoding based on the value size.
25+
fn encode_length(buf: &mut Vec<u8>, major: u8, len: u64) {
26+
if len < 24 {
27+
buf.push(major << 5 | len as u8);
28+
} else if len <= 0xFF {
29+
buf.push(major << 5 | 24);
30+
buf.push(len as u8);
31+
} else if len <= 0xFFFF {
32+
buf.push(major << 5 | 25);
33+
buf.extend_from_slice(&(len as u16).to_be_bytes());
34+
} else if len <= 0xFFFFFFFF {
35+
buf.push(major << 5 | 26);
36+
buf.extend_from_slice(&(len as u32).to_be_bytes());
37+
} else {
38+
buf.push(major << 5 | 27);
39+
buf.extend_from_slice(&len.to_be_bytes());
40+
}
41+
}

0 commit comments

Comments
 (0)