rustcrypt_ct_macros/
lib.rs1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{parse_macro_input, LitByteStr, LitStr};
4
5#[proc_macro]
6pub fn obf_lit(input: TokenStream) -> TokenStream {
7 let lit = parse_macro_input!(input as LitStr);
8 let bytes = lit.value().into_bytes();
9
10 let mut keystream = Vec::with_capacity(bytes.len());
11 let mut s: u64 = 0xA076_1D64 ^ (bytes.len() as u64).wrapping_mul(0x9E37_79B9);
12 for _ in 0..bytes.len() {
13 s ^= s << 13;
14 s ^= s >> 7;
15 s ^= s << 17;
16 keystream.push(((s ^ (s >> 11)) & 0xFF) as u8);
17 }
18
19 let obf: Vec<u8> = bytes
20 .iter()
21 .enumerate()
22 .map(|(i, b)| b ^ keystream[i])
23 .collect();
24
25 let n = obf.len();
26 let obf_tokens = quote! { [#(#obf),*] };
27 let key_tokens = quote! { [#(#keystream),*] };
28
29 let expanded = quote! {{
30 const __OBF: [u8; #n] = #obf_tokens;
31 const __KEY: [u8; #n] = #key_tokens;
32 let mut __buf = vec![0u8; #n];
33 let mut __i = 0usize;
34 while __i < #n { __buf[__i] = __OBF[__i] ^ __KEY[__i]; __i += 1; }
35 String::from_utf8(__buf).expect("obf_lit produced invalid UTF-8")
36 }};
37
38 TokenStream::from(expanded)
39}
40
41#[proc_macro]
43pub fn obf_lit_bytes(input: TokenStream) -> TokenStream {
44 let lit = parse_macro_input!(input as LitByteStr);
45 let bytes = lit.value();
46
47 let mut keystream = Vec::with_capacity(bytes.len());
48 let mut s: u64 = 0xA076_1D64 ^ (bytes.len() as u64).wrapping_mul(0x9E37_79B9);
49 for _ in 0..bytes.len() {
50 s ^= s << 13;
51 s ^= s >> 7;
52 s ^= s << 17;
53 keystream.push(((s ^ (s >> 11)) & 0xFF) as u8);
54 }
55
56 let obf: Vec<u8> = bytes
57 .iter()
58 .enumerate()
59 .map(|(i, b)| b ^ keystream[i])
60 .collect();
61
62 let n = obf.len();
63 let obf_tokens = quote! { [#(#obf),*] };
64 let key_tokens = quote! { [#(#keystream),*] };
65
66 let expanded = quote! {{
67 const __OBF: [u8; #n] = #obf_tokens;
68 const __KEY: [u8; #n] = #key_tokens;
69 let mut __buf = vec![0u8; #n];
70 let mut __i = 0usize;
71 while __i < #n { __buf[__i] = __OBF[__i] ^ __KEY[__i]; __i += 1; }
72 __buf
73 }};
74
75 TokenStream::from(expanded)
76}
77
78#[proc_macro]
79pub fn obf_lit_cstr(input: TokenStream) -> TokenStream {
80 let lit = parse_macro_input!(input as LitStr);
81 let mut bytes = lit.value().into_bytes();
82 bytes.push(0);
83 let mut keystream = Vec::with_capacity(bytes.len());
84 let mut s: u64 = 0xA076_1D64 ^ (bytes.len() as u64).wrapping_mul(0x9E37_79B9);
85 for _ in 0..bytes.len() { s ^= s << 13; s ^= s >> 7; s ^= s << 17; keystream.push(((s ^ (s >> 11)) & 0xFF) as u8); }
86 let obf: Vec<u8> = bytes.iter().enumerate().map(|(i, b)| b ^ keystream[i]).collect();
87 let n = obf.len();
88 let obf_tokens = quote! { [#(#obf),*] };
89 let key_tokens = quote! { [#(#keystream),*] };
90 let expanded = quote! {{
91 const __OBF: [u8; #n] = #obf_tokens;
92 const __KEY: [u8; #n] = #key_tokens;
93 let mut __buf = vec![0u8; #n];
94 let mut __i = 0usize;
95 while __i < #n { __buf[__i] = __OBF[__i] ^ __KEY[__i]; __i += 1; }
96 __buf
97 }};
98 TokenStream::from(expanded)
99}
100
101#[proc_macro]
102pub fn obf_lit_array(input: TokenStream) -> TokenStream {
103 let lit = parse_macro_input!(input as LitByteStr);
104 let bytes = lit.value();
105 let mut keystream = Vec::with_capacity(bytes.len());
106 let mut s: u64 = 0xA076_1D64 ^ (bytes.len() as u64).wrapping_mul(0x9E37_79B9);
107 for _ in 0..bytes.len() { s ^= s << 13; s ^= s >> 7; s ^= s << 17; keystream.push(((s ^ (s >> 11)) & 0xFF) as u8); }
108 let obf: Vec<u8> = bytes.iter().enumerate().map(|(i, b)| b ^ keystream[i]).collect();
109 let n = obf.len();
110 let obf_tokens = quote! { [#(#obf),*] };
111 let key_tokens = quote! { [#(#keystream),*] };
112 let expanded = quote! {{
113 const __OBF: [u8; #n] = #obf_tokens;
114 const __KEY: [u8; #n] = #key_tokens;
115 (__OBF, __KEY)
116 }};
117 TokenStream::from(expanded)
118}