bcore_mutation/operators/
secp256k1.rs1use super::{build, common, MutationOperator, OperatorSet};
10
11pub struct Secp256k1;
12
13const SECP256K1_SKIP_PREFIXES: &[&str] = &[
14 "VERIFY_CHECK",
16 "VERIFY_BITS",
17 "ARG_CHECK",
18 "ARG_CHECK_VOID",
19 "CHECK",
20 "secp256k1_fe_verify",
21 "secp256k1_ge_verify",
22 "secp256k1_gej_verify",
23 "secp256k1_scalar_verify",
24 "memset",
26 "printf",
27 "fprintf",
28];
29
30const SECP256K1_SKIP_SUBSTRINGS: &[&str] = &[
31 "VERIFY_CHECK",
33 "VERIFY_BITS",
34 "_VERIFY",
35 "ARG_CHECK",
36 "secp256k1_callback_call",
38 "secp256k1_declassify",
39 "SECP256K1_CHECKMEM_",
40 "secp256k1_memclear_explicit",
42 "secp256k1_scalar_clear",
43 "secp256k1_ge_clear",
44 "secp256k1_gej_clear",
45 "secp256k1_fe_clear",
46 "secp256k1_sha256_clear",
47 "secp256k1_hmac_sha256_clear",
48 "secp256k1_rfc6979_hmac_sha256_clear",
49 "secp256k1_memczero",
51 "secp256k1_fe_normalize",
56 "fopen(",
58 "fread(",
59 "fclose(",
60];
61
62impl OperatorSet for Secp256k1 {
63 fn regex_operators(&self) -> Result<Vec<MutationOperator>, regex::Error> {
64 build(common::regex_operators())
65 }
66
67 fn security_operators(&self) -> Result<Vec<MutationOperator>, regex::Error> {
68 build(common::security_operators())
69 }
70
71 fn test_operators(&self) -> Result<Vec<MutationOperator>, regex::Error> {
72 build(common::test_operators())
73 }
74
75 fn do_not_mutate_patterns(&self) -> Vec<&'static str> {
76 let mut patterns = common::do_not_mutate_patterns();
77 patterns.extend(SECP256K1_SKIP_PREFIXES);
78 patterns
79 }
80
81 fn do_not_mutate_py_patterns(&self) -> Vec<&'static str> {
82 Vec::new()
84 }
85
86 fn do_not_mutate_unit_patterns(&self) -> Vec<&'static str> {
87 vec![
88 "while",
89 "for",
90 "if",
91 "else",
92 "return",
93 "continue",
94 "break",
95 "static",
96 "void",
97 "CHECK",
99 "VERIFY_CHECK",
100 "run_",
101 "test_",
102 "secp256k1_",
103 ]
104 }
105
106 fn skip_if_contain_patterns(&self) -> Vec<&'static str> {
107 SECP256K1_SKIP_SUBSTRINGS.to_vec()
108 }
109
110 fn test_line_skip_prefixes(&self) -> Vec<&'static str> {
111 let mut prefixes = vec!["assert", "CHECK", "run_", "test_"];
112 prefixes.extend(SECP256K1_SKIP_PREFIXES);
113 prefixes
114 }
115}
116
117#[cfg(test)]
118mod tests {
119 use super::*;
120
121 fn skipped_by_global_secp256k1_lists(line: &str) -> bool {
122 let ops = Secp256k1;
123 let trimmed = line.trim_start();
124
125 ops.do_not_mutate_patterns()
126 .iter()
127 .any(|pattern| trimmed.starts_with(pattern))
128 || ops
129 .skip_if_contain_patterns()
130 .iter()
131 .any(|pattern| line.contains(pattern))
132 }
133
134 #[test]
135 fn skips_verify_and_api_guard_lines() {
136 assert!(skipped_by_global_secp256k1_lists(
137 " VERIFY_CHECK(r != NULL);"
138 ));
139 assert!(skipped_by_global_secp256k1_lists(
140 " VERIFY_BITS_128(x, 64);"
141 ));
142 assert!(skipped_by_global_secp256k1_lists(
143 " SECP256K1_SCALAR_VERIFY (&s);"
144 ));
145 assert!(skipped_by_global_secp256k1_lists(
146 " ARG_CHECK(ctx != NULL);"
147 ));
148 }
149
150 #[test]
151 fn skips_annotations_cleanup_and_zeroing() {
152 assert!(skipped_by_global_secp256k1_lists(
153 " secp256k1_callback_call(&ctx->error_callback, \"bad\");"
154 ));
155 assert!(skipped_by_global_secp256k1_lists(
156 " secp256k1_declassify(ctx, &ret, sizeof(ret));"
157 ));
158 assert!(skipped_by_global_secp256k1_lists(
159 " SECP256K1_CHECKMEM_CHECK(p, len);"
160 ));
161 assert!(skipped_by_global_secp256k1_lists(
162 " secp256k1_scalar_clear(&s);"
163 ));
164 assert!(skipped_by_global_secp256k1_lists(
165 " secp256k1_memczero(sig64, 64, !ret);"
166 ));
167 assert!(skipped_by_global_secp256k1_lists(
168 " memset(sig64, 0, 64);"
169 ));
170 }
171
172 #[test]
173 fn skips_field_normalization_calls() {
174 assert!(skipped_by_global_secp256k1_lists(
175 " secp256k1_fe_normalize(&r->x);"
176 ));
177 assert!(skipped_by_global_secp256k1_lists(
178 " secp256k1_fe_normalize_weak(&r->x);"
179 ));
180 assert!(skipped_by_global_secp256k1_lists(
181 " secp256k1_fe_normalize_var(&r->x);"
182 ));
183 assert!(skipped_by_global_secp256k1_lists(
184 " secp256k1_fe_normalize_to_zero_var(&t);"
185 ));
186 }
187
188 #[test]
189 fn skips_preprocessor_comments_and_testrand_diagnostics() {
190 assert!(skipped_by_global_secp256k1_lists("# ifdef VERIFY"));
191 assert!(skipped_by_global_secp256k1_lists(
192 " fprintf(stderr, \"random seed failure\\n\");"
193 ));
194 assert!(skipped_by_global_secp256k1_lists(
195 " fp = fopen(\"/dev/urandom\", \"rb\");"
196 ));
197 assert!(skipped_by_global_secp256k1_lists(
198 " fread(seed, 1, sizeof(seed), fp);"
199 ));
200 assert!(skipped_by_global_secp256k1_lists(" // comment"));
201 assert!(!skipped_by_global_secp256k1_lists(" ret = a + b;"));
202 }
203}