ec_gpu/
lib.rs

1/// The name that is used in the GPU source code to identify the item that is used.
2pub trait GpuName {
3    /// A unique name for the item.
4    ///
5    /// To make the uniqueness easier to implement, use the [`name`] macro. It produces a unique
6    /// name, based on the module path and the type of the item itself. That identifier might not
7    /// be stable across different versions of a crate, but this is OK as kernel sources/binaries
8    /// are always bundled with a library and not re-used between versions.
9    ///
10    /// # Example
11    ///
12    /// ```
13    /// struct Fp;
14    ///
15    /// impl ec_gpu::GpuName for Fp {
16    ///     fn name() -> String {
17    ///         ec_gpu::name!()
18    ///     }
19    /// }
20    /// ```
21    fn name() -> String;
22}
23
24/// A prime field that returns the values in a representation that is suited for the use on a GPU.
25pub trait GpuField: GpuName {
26    /// Returns `1` as a vector of 32-bit limbs in little-endian non-Montgomery form (least
27    /// significant limb first).
28    fn one() -> Vec<u32>;
29
30    /// Returns `R ^ 2 mod P` as a vector of 32-bit limbs in little-endian non-Montgomery form
31    /// (least significant limb first).
32    fn r2() -> Vec<u32>;
33
34    /// Returns the field modulus as a vector of 32-bit limbs in non-Montgomery form (least
35    /// significant limb first).
36    fn modulus() -> Vec<u32>;
37
38    /// If the field is an extension field, then the name of the sub-field is returned.
39    fn sub_field_name() -> Option<String> {
40        None
41    }
42}
43
44/// Macro to get a unique name of an item.
45///
46/// The name is a string that consists of the module path and the type name. All non-alphanumeric
47/// characters are replaced with underscores, so that it's an identifier that doesn't cause any
48/// issues with C compilers.
49#[macro_export]
50macro_rules! name {
51    () => {{
52        let mod_path = module_path!();
53        let type_name = core::any::type_name::<Self>();
54        let name = if type_name.starts_with(mod_path) {
55            type_name.into()
56        } else {
57            [mod_path, "__", type_name].concat()
58        };
59        name.replace(|c: char| !c.is_ascii_alphanumeric(), "_")
60    }};
61}