bauta-rs 0.1.1__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.
@@ -0,0 +1,466 @@
1
+ # This file is automatically @generated by Cargo.
2
+ # It is not intended for manual editing.
3
+ version = 4
4
+
5
+ [[package]]
6
+ name = "aes"
7
+ version = "0.9.3"
8
+ source = "registry+https://github.com/rust-lang/crates.io-index"
9
+ checksum = "35f0f96ce78e38c3dc6d8948aa8163d06385be74000f3c7a95bf1eef35d3ea32"
10
+ dependencies = [
11
+ "cipher",
12
+ "cpubits",
13
+ "cpufeatures",
14
+ ]
15
+
16
+ [[package]]
17
+ name = "autocfg"
18
+ version = "1.5.1"
19
+ source = "registry+https://github.com/rust-lang/crates.io-index"
20
+ checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
21
+
22
+ [[package]]
23
+ name = "bauta-core"
24
+ version = "0.1.1"
25
+ dependencies = [
26
+ "aes",
27
+ "hex",
28
+ "num-bigint",
29
+ "num-traits",
30
+ "ring",
31
+ "serde_json",
32
+ ]
33
+
34
+ [[package]]
35
+ name = "bauta-rs"
36
+ version = "0.1.1"
37
+ dependencies = [
38
+ "bauta-core",
39
+ "num-bigint",
40
+ "pyo3",
41
+ ]
42
+
43
+ [[package]]
44
+ name = "cc"
45
+ version = "1.4.6"
46
+ source = "registry+https://github.com/rust-lang/crates.io-index"
47
+ checksum = "a3eb0f42d6c360dc3f8a821f6bf2fdea7f72bfd36b3076eb0e6d1e9e0752fff4"
48
+ dependencies = [
49
+ "find-msvc-tools",
50
+ "shlex",
51
+ ]
52
+
53
+ [[package]]
54
+ name = "cfg-if"
55
+ version = "1.0.5"
56
+ source = "registry+https://github.com/rust-lang/crates.io-index"
57
+ checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600"
58
+
59
+ [[package]]
60
+ name = "cipher"
61
+ version = "0.5.2"
62
+ source = "registry+https://github.com/rust-lang/crates.io-index"
63
+ checksum = "e8cf2a2c93cd704877c0858356ed03480ff301ee950b43f1cbe4573b088bfa6c"
64
+ dependencies = [
65
+ "crypto-common",
66
+ "inout",
67
+ ]
68
+
69
+ [[package]]
70
+ name = "cpubits"
71
+ version = "0.1.1"
72
+ source = "registry+https://github.com/rust-lang/crates.io-index"
73
+ checksum = "15b85f9c39137c3a891689859392b1bd49812121d0d61c9caf00d46ed5ce06ae"
74
+
75
+ [[package]]
76
+ name = "cpufeatures"
77
+ version = "0.3.1"
78
+ source = "registry+https://github.com/rust-lang/crates.io-index"
79
+ checksum = "5ca28b0ae3115b884660db4118d803791fd6756b6e88f39c0f3f7859060d7566"
80
+ dependencies = [
81
+ "libc",
82
+ ]
83
+
84
+ [[package]]
85
+ name = "crypto-common"
86
+ version = "0.2.2"
87
+ source = "registry+https://github.com/rust-lang/crates.io-index"
88
+ checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453"
89
+ dependencies = [
90
+ "hybrid-array",
91
+ ]
92
+
93
+ [[package]]
94
+ name = "find-msvc-tools"
95
+ version = "0.1.12"
96
+ source = "registry+https://github.com/rust-lang/crates.io-index"
97
+ checksum = "3e0f1c7c3a72c66fd80abe965175f7523475c0489a87d3ff9d6e8c87d87a9d2d"
98
+
99
+ [[package]]
100
+ name = "getrandom"
101
+ version = "0.2.17"
102
+ source = "registry+https://github.com/rust-lang/crates.io-index"
103
+ checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
104
+ dependencies = [
105
+ "cfg-if",
106
+ "libc",
107
+ "wasi",
108
+ ]
109
+
110
+ [[package]]
111
+ name = "heck"
112
+ version = "0.5.0"
113
+ source = "registry+https://github.com/rust-lang/crates.io-index"
114
+ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
115
+
116
+ [[package]]
117
+ name = "hex"
118
+ version = "0.4.3"
119
+ source = "registry+https://github.com/rust-lang/crates.io-index"
120
+ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
121
+
122
+ [[package]]
123
+ name = "hybrid-array"
124
+ version = "0.4.15"
125
+ source = "registry+https://github.com/rust-lang/crates.io-index"
126
+ checksum = "27f864f10dfb56725ce5ce5472bc52252c8f93a4ab86327122cebf62c5f59a17"
127
+ dependencies = [
128
+ "typenum",
129
+ ]
130
+
131
+ [[package]]
132
+ name = "inout"
133
+ version = "0.2.2"
134
+ source = "registry+https://github.com/rust-lang/crates.io-index"
135
+ checksum = "4250ce6452e92010fdf7268ccc5d14faa80bb12fc741938534c58f16804e03c7"
136
+ dependencies = [
137
+ "hybrid-array",
138
+ ]
139
+
140
+ [[package]]
141
+ name = "itoa"
142
+ version = "1.0.18"
143
+ source = "registry+https://github.com/rust-lang/crates.io-index"
144
+ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
145
+
146
+ [[package]]
147
+ name = "libc"
148
+ version = "0.2.189"
149
+ source = "registry+https://github.com/rust-lang/crates.io-index"
150
+ checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2"
151
+
152
+ [[package]]
153
+ name = "memchr"
154
+ version = "2.8.3"
155
+ source = "registry+https://github.com/rust-lang/crates.io-index"
156
+ checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
157
+
158
+ [[package]]
159
+ name = "num-bigint"
160
+ version = "0.4.8"
161
+ source = "registry+https://github.com/rust-lang/crates.io-index"
162
+ checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367"
163
+ dependencies = [
164
+ "num-integer",
165
+ "num-traits",
166
+ ]
167
+
168
+ [[package]]
169
+ name = "num-integer"
170
+ version = "0.1.47"
171
+ source = "registry+https://github.com/rust-lang/crates.io-index"
172
+ checksum = "7ce2d95d4b3734dc35aa2f45e1aa22cd416814592a4f9d9205e11affd5b8e10b"
173
+ dependencies = [
174
+ "num-traits",
175
+ ]
176
+
177
+ [[package]]
178
+ name = "num-traits"
179
+ version = "0.2.19"
180
+ source = "registry+https://github.com/rust-lang/crates.io-index"
181
+ checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
182
+ dependencies = [
183
+ "autocfg",
184
+ ]
185
+
186
+ [[package]]
187
+ name = "once_cell"
188
+ version = "1.21.4"
189
+ source = "registry+https://github.com/rust-lang/crates.io-index"
190
+ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
191
+
192
+ [[package]]
193
+ name = "portable-atomic"
194
+ version = "1.15.0"
195
+ source = "registry+https://github.com/rust-lang/crates.io-index"
196
+ checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85"
197
+
198
+ [[package]]
199
+ name = "proc-macro2"
200
+ version = "1.0.107"
201
+ source = "registry+https://github.com/rust-lang/crates.io-index"
202
+ checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
203
+ dependencies = [
204
+ "unicode-ident",
205
+ ]
206
+
207
+ [[package]]
208
+ name = "pyo3"
209
+ version = "0.29.2"
210
+ source = "registry+https://github.com/rust-lang/crates.io-index"
211
+ checksum = "4688ddedf473e32662b9b067670129a8afb8c18e351482c70d62ba4a88171e8b"
212
+ dependencies = [
213
+ "libc",
214
+ "num-bigint",
215
+ "num-traits",
216
+ "once_cell",
217
+ "portable-atomic",
218
+ "pyo3-build-config",
219
+ "pyo3-ffi",
220
+ "pyo3-macros",
221
+ ]
222
+
223
+ [[package]]
224
+ name = "pyo3-build-config"
225
+ version = "0.29.2"
226
+ source = "registry+https://github.com/rust-lang/crates.io-index"
227
+ checksum = "f41027e41b4bd03f6e60f9f417fe24a6341a6bb744edd62b6f709f2a52ea30e9"
228
+ dependencies = [
229
+ "target-lexicon",
230
+ ]
231
+
232
+ [[package]]
233
+ name = "pyo3-ffi"
234
+ version = "0.29.2"
235
+ source = "registry+https://github.com/rust-lang/crates.io-index"
236
+ checksum = "e591a95526fead067432c3b3a33fc74770b87b1e04e73671090d9c2055a2b327"
237
+ dependencies = [
238
+ "libc",
239
+ "pyo3-build-config",
240
+ ]
241
+
242
+ [[package]]
243
+ name = "pyo3-macros"
244
+ version = "0.29.2"
245
+ source = "registry+https://github.com/rust-lang/crates.io-index"
246
+ checksum = "73225868fc1cd84eef2c3c230ddb91273bf1de46aeb8a4248da76d32a0924a1c"
247
+ dependencies = [
248
+ "proc-macro2",
249
+ "pyo3-macros-backend",
250
+ "quote",
251
+ "syn 2.0.119",
252
+ ]
253
+
254
+ [[package]]
255
+ name = "pyo3-macros-backend"
256
+ version = "0.29.2"
257
+ source = "registry+https://github.com/rust-lang/crates.io-index"
258
+ checksum = "571575aa3749fa6216757dd47d2a3e7ef360f329a40f0666a9fbd14889024952"
259
+ dependencies = [
260
+ "heck",
261
+ "proc-macro2",
262
+ "quote",
263
+ "syn 2.0.119",
264
+ ]
265
+
266
+ [[package]]
267
+ name = "quote"
268
+ version = "1.0.47"
269
+ source = "registry+https://github.com/rust-lang/crates.io-index"
270
+ checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
271
+ dependencies = [
272
+ "proc-macro2",
273
+ ]
274
+
275
+ [[package]]
276
+ name = "ring"
277
+ version = "0.17.14"
278
+ source = "registry+https://github.com/rust-lang/crates.io-index"
279
+ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
280
+ dependencies = [
281
+ "cc",
282
+ "cfg-if",
283
+ "getrandom",
284
+ "libc",
285
+ "untrusted",
286
+ "windows-sys",
287
+ ]
288
+
289
+ [[package]]
290
+ name = "serde"
291
+ version = "1.0.229"
292
+ source = "registry+https://github.com/rust-lang/crates.io-index"
293
+ checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba"
294
+ dependencies = [
295
+ "serde_core",
296
+ ]
297
+
298
+ [[package]]
299
+ name = "serde_core"
300
+ version = "1.0.229"
301
+ source = "registry+https://github.com/rust-lang/crates.io-index"
302
+ checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48"
303
+ dependencies = [
304
+ "serde_derive",
305
+ ]
306
+
307
+ [[package]]
308
+ name = "serde_derive"
309
+ version = "1.0.229"
310
+ source = "registry+https://github.com/rust-lang/crates.io-index"
311
+ checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
312
+ dependencies = [
313
+ "proc-macro2",
314
+ "quote",
315
+ "syn 3.0.6",
316
+ ]
317
+
318
+ [[package]]
319
+ name = "serde_json"
320
+ version = "1.0.151"
321
+ source = "registry+https://github.com/rust-lang/crates.io-index"
322
+ checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14"
323
+ dependencies = [
324
+ "itoa",
325
+ "memchr",
326
+ "serde",
327
+ "serde_core",
328
+ "zmij",
329
+ ]
330
+
331
+ [[package]]
332
+ name = "shlex"
333
+ version = "2.0.1"
334
+ source = "registry+https://github.com/rust-lang/crates.io-index"
335
+ checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
336
+
337
+ [[package]]
338
+ name = "syn"
339
+ version = "2.0.119"
340
+ source = "registry+https://github.com/rust-lang/crates.io-index"
341
+ checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
342
+ dependencies = [
343
+ "proc-macro2",
344
+ "quote",
345
+ "unicode-ident",
346
+ ]
347
+
348
+ [[package]]
349
+ name = "syn"
350
+ version = "3.0.6"
351
+ source = "registry+https://github.com/rust-lang/crates.io-index"
352
+ checksum = "8593e8e72159ed2257d083c7a454a85cbf854f37a0966d8d483aff8c8a3ebcee"
353
+ dependencies = [
354
+ "proc-macro2",
355
+ "quote",
356
+ "unicode-ident",
357
+ ]
358
+
359
+ [[package]]
360
+ name = "target-lexicon"
361
+ version = "0.13.5"
362
+ source = "registry+https://github.com/rust-lang/crates.io-index"
363
+ checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca"
364
+
365
+ [[package]]
366
+ name = "typenum"
367
+ version = "1.20.1"
368
+ source = "registry+https://github.com/rust-lang/crates.io-index"
369
+ checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20"
370
+
371
+ [[package]]
372
+ name = "unicode-ident"
373
+ version = "1.0.26"
374
+ source = "registry+https://github.com/rust-lang/crates.io-index"
375
+ checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954"
376
+
377
+ [[package]]
378
+ name = "untrusted"
379
+ version = "0.9.0"
380
+ source = "registry+https://github.com/rust-lang/crates.io-index"
381
+ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
382
+
383
+ [[package]]
384
+ name = "wasi"
385
+ version = "0.11.1+wasi-snapshot-preview1"
386
+ source = "registry+https://github.com/rust-lang/crates.io-index"
387
+ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
388
+
389
+ [[package]]
390
+ name = "windows-sys"
391
+ version = "0.52.0"
392
+ source = "registry+https://github.com/rust-lang/crates.io-index"
393
+ checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
394
+ dependencies = [
395
+ "windows-targets",
396
+ ]
397
+
398
+ [[package]]
399
+ name = "windows-targets"
400
+ version = "0.52.6"
401
+ source = "registry+https://github.com/rust-lang/crates.io-index"
402
+ checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
403
+ dependencies = [
404
+ "windows_aarch64_gnullvm",
405
+ "windows_aarch64_msvc",
406
+ "windows_i686_gnu",
407
+ "windows_i686_gnullvm",
408
+ "windows_i686_msvc",
409
+ "windows_x86_64_gnu",
410
+ "windows_x86_64_gnullvm",
411
+ "windows_x86_64_msvc",
412
+ ]
413
+
414
+ [[package]]
415
+ name = "windows_aarch64_gnullvm"
416
+ version = "0.52.6"
417
+ source = "registry+https://github.com/rust-lang/crates.io-index"
418
+ checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
419
+
420
+ [[package]]
421
+ name = "windows_aarch64_msvc"
422
+ version = "0.52.6"
423
+ source = "registry+https://github.com/rust-lang/crates.io-index"
424
+ checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
425
+
426
+ [[package]]
427
+ name = "windows_i686_gnu"
428
+ version = "0.52.6"
429
+ source = "registry+https://github.com/rust-lang/crates.io-index"
430
+ checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
431
+
432
+ [[package]]
433
+ name = "windows_i686_gnullvm"
434
+ version = "0.52.6"
435
+ source = "registry+https://github.com/rust-lang/crates.io-index"
436
+ checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
437
+
438
+ [[package]]
439
+ name = "windows_i686_msvc"
440
+ version = "0.52.6"
441
+ source = "registry+https://github.com/rust-lang/crates.io-index"
442
+ checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
443
+
444
+ [[package]]
445
+ name = "windows_x86_64_gnu"
446
+ version = "0.52.6"
447
+ source = "registry+https://github.com/rust-lang/crates.io-index"
448
+ checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
449
+
450
+ [[package]]
451
+ name = "windows_x86_64_gnullvm"
452
+ version = "0.52.6"
453
+ source = "registry+https://github.com/rust-lang/crates.io-index"
454
+ checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
455
+
456
+ [[package]]
457
+ name = "windows_x86_64_msvc"
458
+ version = "0.52.6"
459
+ source = "registry+https://github.com/rust-lang/crates.io-index"
460
+ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
461
+
462
+ [[package]]
463
+ name = "zmij"
464
+ version = "1.0.23"
465
+ source = "registry+https://github.com/rust-lang/crates.io-index"
466
+ checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"
@@ -0,0 +1,18 @@
1
+ # Two crates rather than one: `core` knows nothing about Python, so the same
2
+ # masking can later back a Rust CLI or a PostgreSQL extension, and its tests
3
+ # run without an interpreter. `py` is the PyO3 layer and holds every unsafe
4
+ # boundary and every type conversion.
5
+ [workspace]
6
+ members = ["core", "py"]
7
+ resolver = "2"
8
+
9
+ [workspace.package]
10
+ version = "0.1.1"
11
+ edition = "2021"
12
+ rust-version = "1.83"
13
+ license = "MIT"
14
+
15
+ [profile.release]
16
+ lto = true
17
+ codegen-units = 1
18
+ panic = "abort"
@@ -0,0 +1,98 @@
1
+ Metadata-Version: 2.4
2
+ Name: bauta-rs
3
+ Version: 0.1.1
4
+ Classifier: Operating System :: MacOS
5
+ Classifier: Operating System :: POSIX :: Linux
6
+ Classifier: Programming Language :: Rust
7
+ Classifier: Programming Language :: Python :: 3 :: Only
8
+ Classifier: Programming Language :: Python :: Implementation :: CPython
9
+ Classifier: Topic :: Security
10
+ Summary: The native masking core for Bauta. Optional: bauta works without it.
11
+ Keywords: data masking,format-preserving encryption,bauta
12
+ Author: David Ribeiro
13
+ License: MIT
14
+ Requires-Python: >=3.10
15
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
16
+ Project-URL: Documentation, https://github.com/ribeiro11075/bauta/blob/master/docs/masking.md#the-native-masker
17
+ Project-URL: Homepage, https://github.com/ribeiro11075/bauta
18
+ Project-URL: Issues, https://github.com/ribeiro11075/bauta/issues
19
+
20
+ # bauta-rs
21
+
22
+ The optional native masker for [Bauta](https://github.com/ribeiro11075/bauta).
23
+
24
+ Bauta masks data on its way from production to a copy. Masking `key` and
25
+ `fpe` columns costs tens of microseconds a value in Python, most of it spent in
26
+ the interpreter rather than in cryptography. This computes the same masks in
27
+ Rust, four to five times faster on a whole job.
28
+
29
+ It is optional. Bauta works without it, and produces identical output
30
+ either way.
31
+
32
+ ## Installing
33
+
34
+ ```
35
+ pip install "bauta[native]"
36
+ ```
37
+
38
+ The extra installs the `bauta-rs` released with your version of `bauta`, which
39
+ is the only one Bauta uses; any other is ignored with a warning. Wheels cover
40
+ Linux (x86-64 and ARM) and macOS (Apple silicon and Intel) on every supported
41
+ Python. Elsewhere pip compiles it, which needs Rust 1.83 or newer.
42
+
43
+ ## Layout
44
+
45
+ | | |
46
+ | --- | --- |
47
+ | `core/` | The constructions. No Python dependency, so they are testable without an interpreter. |
48
+ | `py/` | The PyO3 layer: conversions in, results out, and every unsafe boundary. |
49
+ | `vectors/reference.json` | What the Python implementation produces, recorded. The contract between the two. |
50
+ | `generate_vectors.py` | Regenerates that file from the Python implementation. |
51
+
52
+ ## Building
53
+
54
+ From a clone, with Rust 1.83 or newer.
55
+
56
+ ```
57
+ cargo test --release
58
+ cd py && maturin build --release
59
+ pip install ../target/wheels/bauta_rs-*.whl
60
+ ```
61
+
62
+ `--release` matters for the tests: two of them measure SHA-256 and AES
63
+ throughput to catch a backend that has silently fallen back to software, and a
64
+ debug build is indistinguishable from one.
65
+
66
+ ## The rule
67
+
68
+ **Python is the reference.** This crate exists to be faster, not to be
69
+ different. Where the two disagree, Python is right.
70
+
71
+ That is not a style preference. Bauta's masks are deterministic and keyed,
72
+ so a difference between the two implementations would not surface as a wrong
73
+ answer — it would surface as a changed key, months later, as joins between an
74
+ old copy and a new one quietly stopping matching. The key fingerprint would not
75
+ change, because the key did not.
76
+
77
+ So:
78
+
79
+ - Every covered strategy is checked against `vectors/reference.json`, over a
80
+ corpus chosen for boundaries rather than volume: the lengths where a Feistel
81
+ half stops fitting a machine word, domains of exactly 2\*\*128, the maximum
82
+ identifier length, single-character alphabets, mixed-case hex, and every
83
+ refusal with its exact message.
84
+ - Anything whose behaviour depends on Python's own Unicode rules is not
85
+ reimplemented. Non-ASCII text, `str.isspace()` when an address is stripped,
86
+ digits normalised across scripts — those values are handed back, and Python
87
+ masks them.
88
+ - FF1 is checked against NIST SP 800-38G's sample vectors, and the keyed hash
89
+ against RFC 4231.
90
+
91
+ ## What it covers
92
+
93
+ `key`, `fpe`, `hash`, `email`, `digits`. Everything else stays in Python:
94
+ `redact` needs lookbehind that Rust's regex engine doesn't offer, `shuffle`,
95
+ `dateShift`, `number`, `keep`, `null` and `constant` are already cheap, the
96
+ `fake*` strategies would need a second copy of the name lists, and custom
97
+ strategies are Python by definition.
98
+
@@ -0,0 +1,78 @@
1
+ # bauta-rs
2
+
3
+ The optional native masker for [Bauta](https://github.com/ribeiro11075/bauta).
4
+
5
+ Bauta masks data on its way from production to a copy. Masking `key` and
6
+ `fpe` columns costs tens of microseconds a value in Python, most of it spent in
7
+ the interpreter rather than in cryptography. This computes the same masks in
8
+ Rust, four to five times faster on a whole job.
9
+
10
+ It is optional. Bauta works without it, and produces identical output
11
+ either way.
12
+
13
+ ## Installing
14
+
15
+ ```
16
+ pip install "bauta[native]"
17
+ ```
18
+
19
+ The extra installs the `bauta-rs` released with your version of `bauta`, which
20
+ is the only one Bauta uses; any other is ignored with a warning. Wheels cover
21
+ Linux (x86-64 and ARM) and macOS (Apple silicon and Intel) on every supported
22
+ Python. Elsewhere pip compiles it, which needs Rust 1.83 or newer.
23
+
24
+ ## Layout
25
+
26
+ | | |
27
+ | --- | --- |
28
+ | `core/` | The constructions. No Python dependency, so they are testable without an interpreter. |
29
+ | `py/` | The PyO3 layer: conversions in, results out, and every unsafe boundary. |
30
+ | `vectors/reference.json` | What the Python implementation produces, recorded. The contract between the two. |
31
+ | `generate_vectors.py` | Regenerates that file from the Python implementation. |
32
+
33
+ ## Building
34
+
35
+ From a clone, with Rust 1.83 or newer.
36
+
37
+ ```
38
+ cargo test --release
39
+ cd py && maturin build --release
40
+ pip install ../target/wheels/bauta_rs-*.whl
41
+ ```
42
+
43
+ `--release` matters for the tests: two of them measure SHA-256 and AES
44
+ throughput to catch a backend that has silently fallen back to software, and a
45
+ debug build is indistinguishable from one.
46
+
47
+ ## The rule
48
+
49
+ **Python is the reference.** This crate exists to be faster, not to be
50
+ different. Where the two disagree, Python is right.
51
+
52
+ That is not a style preference. Bauta's masks are deterministic and keyed,
53
+ so a difference between the two implementations would not surface as a wrong
54
+ answer — it would surface as a changed key, months later, as joins between an
55
+ old copy and a new one quietly stopping matching. The key fingerprint would not
56
+ change, because the key did not.
57
+
58
+ So:
59
+
60
+ - Every covered strategy is checked against `vectors/reference.json`, over a
61
+ corpus chosen for boundaries rather than volume: the lengths where a Feistel
62
+ half stops fitting a machine word, domains of exactly 2\*\*128, the maximum
63
+ identifier length, single-character alphabets, mixed-case hex, and every
64
+ refusal with its exact message.
65
+ - Anything whose behaviour depends on Python's own Unicode rules is not
66
+ reimplemented. Non-ASCII text, `str.isspace()` when an address is stripped,
67
+ digits normalised across scripts — those values are handed back, and Python
68
+ masks them.
69
+ - FF1 is checked against NIST SP 800-38G's sample vectors, and the keyed hash
70
+ against RFC 4231.
71
+
72
+ ## What it covers
73
+
74
+ `key`, `fpe`, `hash`, `email`, `digits`. Everything else stays in Python:
75
+ `redact` needs lookbehind that Rust's regex engine doesn't offer, `shuffle`,
76
+ `dateShift`, `number`, `keep`, `null` and `constant` are already cheap, the
77
+ `fake*` strategies would need a second copy of the name lists, and custom
78
+ strategies are Python by definition.
@@ -0,0 +1,25 @@
1
+ [package]
2
+ name = "bauta-core"
3
+ description = "Bauta's masking constructions, byte-for-byte as the Python implementation computes them"
4
+ version.workspace = true
5
+ edition.workspace = true
6
+ rust-version.workspace = true
7
+ license.workspace = true
8
+
9
+ [dependencies]
10
+ aes = "0.9"
11
+ num-bigint = "0.4"
12
+ num-traits = "0.2"
13
+ ring = "0.17.14"
14
+
15
+ [dev-dependencies]
16
+ serde_json = "1"
17
+ hex = "0.4"
18
+
19
+ [[bench]]
20
+ name = "speed"
21
+ harness = false
22
+
23
+ [[bench]]
24
+ name = "backends"
25
+ harness = false