1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#![allow(unused)]
#![forbid(unsafe_code)]
use core::{cmp, ops::Add};
use generic_array::{sequence::Concat, typenum::Sum, ArrayLength, GenericArray};
use serde::{Deserialize, Serialize};
/// A ciphertext, overhead (e.g., tag) tuple.
#[derive(Serialize, Deserialize)]
pub struct Ciphertext<C, O> {
pub(crate) ciphertext: C,
pub(crate) overhead: O,
}
impl<N, M> Ciphertext<GenericArray<u8, N>, GenericArray<u8, M>>
where
N: ArrayLength + Add<M>,
M: ArrayLength,
Sum<N, M>: ArrayLength,
{
/// Converts the ciphertext into a contiguous array.
pub fn into_bytes(self) -> GenericArray<u8, Sum<N, M>> {
self.ciphertext.concat(self.overhead)
}
}
/// Returns `min(x, usize::MAX)`.
pub const fn saturate(x: u64) -> usize {
if x > (usize::MAX as u64) {
usize::MAX
} else {
x as usize
}
}
/// Copy from `src` to `dst`.
pub fn copy<T: Copy>(dst: &mut [T], src: &[T]) -> usize {
let n = cmp::min(src.len(), dst.len());
dst[..n].copy_from_slice(&src[..n]);
n
}
/// Like [`assert!`], but forces a compile-time error.
macro_rules! const_assert {
($($tt:tt)*) => {
const _: () = assert!($($tt)*);
}
}
pub(crate) use const_assert;
/// Invokes `$name` at some indeterminate time before `fn main`.
macro_rules! ctor {
($name:expr) => {
const _: () = {
extern "C" fn init() {
$name()
}
#[used]
// mach-o uses __mod_init_func
// - https://stackoverflow.com/a/30703178
// - https://opensource.apple.com/source/dyld/dyld-239.3/src/dyldInitialization.cpp
#[cfg_attr(
any(
target_os = "macos",
target_os = "ios",
target_os = "tvos",
target_os = "watchos"
),
link_section = "__DATA,__mod_init_func"
)]
// ELF uses .init_array
// - https://refspecs.linuxfoundation.org/LSB_1.1.0/gLSB/specialsections.html
#[cfg_attr(
all(
unix,
not(any(target_os = "macos", target_os = "ios", target_os = "tvos"))
),
link_section = ".init_array"
)]
// The only LLVM toolchain that uses .ctors is mingw.
#[cfg_attr(
all(target_os = "windows", target_env = "gnu"),
link_section = ".ctors"
)]
// Windows (outside of mingw) uses .CRT$XCU.
#[cfg_attr(all(windows, not(target_env = "gnu")), link_section = ".CRT$XCU")]
static __CTOR: extern "C" fn() = init;
// AIX uses -wl,-binitfini:$name
// I don't think VxWorks has any support for this,
// even though it uses ELF.
#[cfg(any(target_os = "aix", target_os = "vxworks",))]
compile_error("VxWorks and AIX are currently unsupported");
};
};
}