Added cfg_attr everywhere possible, and simplified cfg over std/alloc

This commit is contained in:
Michael Rosenberg 2022-11-26 05:53:28 -05:00
parent 4b08687093
commit a35ca1e9cf
11 changed files with 94 additions and 6 deletions

View file

@ -1,4 +1,4 @@
FEATURES := nightly simd_backend packed_simd FEATURES := simd_backend serde
doc: doc:
cargo +nightly rustdoc --features "$(FEATURES)" -- --html-in-header docs/assets/rustdoc-include-katex-header.html --cfg docsrs cargo +nightly rustdoc --features "$(FEATURES)" -- --html-in-header docs/assets/rustdoc-include-katex-header.html --cfg docsrs

View file

@ -37,4 +37,5 @@
pub mod serial; pub mod serial;
#[cfg(any(feature = "simd_backend", docsrs))] #[cfg(any(feature = "simd_backend", docsrs))]
#[cfg_attr(docsrs, doc(cfg(feature = "simd_backend")))]
pub mod vector; pub mod vector;

View file

@ -23,15 +23,25 @@ use cfg_if::cfg_if;
cfg_if! { cfg_if! {
if #[cfg(feature = "fiat_backend")] { if #[cfg(feature = "fiat_backend")] {
#[cfg(not(target_pointer_width = "64"))] #[cfg(not(target_pointer_width = "64"))]
#[cfg_attr(
docsrs,
doc(cfg(all(feature = "fiat_backend", not(target_pointer_width = "64"))))
)]
pub mod fiat_u32; pub mod fiat_u32;
#[cfg(target_pointer_width = "64")] #[cfg(target_pointer_width = "64")]
#[cfg_attr(
docsrs,
doc(cfg(all(feature = "fiat_backend", target_pointer_width = "64")))
)]
pub mod fiat_u64; pub mod fiat_u64;
} else { } else {
#[cfg(not(target_pointer_width = "64"))] #[cfg(not(target_pointer_width = "64"))]
#[cfg_attr(docsrs, doc(cfg(not(target_pointer_width = "64"))))]
pub mod u32; pub mod u32;
#[cfg(target_pointer_width = "64")] #[cfg(target_pointer_width = "64")]
#[cfg_attr(docsrs, doc(cfg(target_pointer_width = "64")))]
pub mod u64; pub mod u64;
} }
} }
@ -42,4 +52,11 @@ pub mod curve_models;
feature = "simd_backend", feature = "simd_backend",
any(target_feature = "avx2", target_feature = "avx512ifma") any(target_feature = "avx2", target_feature = "avx512ifma")
)))] )))]
#[cfg_attr(
docsrs,
doc(cfg(not(all(
feature = "simd_backend",
any(target_feature = "avx2", target_feature = "avx512ifma")
))))
)]
pub mod scalar_mul; pub mod scalar_mul;

View file

@ -61,7 +61,8 @@ use crate::prelude::*;
/// This algorithm is adapted from section 4 of <https://eprint.iacr.org/2012/549.pdf>. /// This algorithm is adapted from section 4 of <https://eprint.iacr.org/2012/549.pdf>.
pub struct Pippenger; pub struct Pippenger;
#[cfg(any(feature = "alloc", feature = "std"))] #[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "std"))))]
impl VartimeMultiscalarMul for Pippenger { impl VartimeMultiscalarMul for Pippenger {
type Point = EdwardsPoint; type Point = EdwardsPoint;

View file

@ -18,22 +18,36 @@ compile_error!("simd_backend selected without target_feature=+avx2 or +avx512ifm
all(target_feature = "avx2", not(target_feature = "avx512ifma")), all(target_feature = "avx2", not(target_feature = "avx512ifma")),
docsrs docsrs
))] ))]
#[cfg_attr(
docsrs,
doc(cfg(all(target_feature = "avx2", not(target_feature = "avx512ifma")),))
)]
pub mod avx2; pub mod avx2;
#[cfg(any( #[cfg(any(
all(target_feature = "avx2", not(target_feature = "avx512ifma")), all(target_feature = "avx2", not(target_feature = "avx512ifma")),
docsrs docsrs
))] ))]
#[cfg_attr(
docsrs,
doc(cfg(all(target_feature = "avx2", not(target_feature = "avx512ifma")),))
)]
pub(crate) use self::avx2::{ pub(crate) use self::avx2::{
constants::BASEPOINT_ODD_LOOKUP_TABLE, edwards::CachedPoint, edwards::ExtendedPoint, constants::BASEPOINT_ODD_LOOKUP_TABLE, edwards::CachedPoint, edwards::ExtendedPoint,
}; };
#[cfg(any(target_feature = "avx512ifma", docsrs))] #[cfg(any(target_feature = "avx512ifma", docsrs))]
#[cfg_attr(docsrs, doc(cfg(target_feature = "avx512ifma")))]
pub mod ifma; pub mod ifma;
#[cfg(target_feature = "avx512ifma")] #[cfg(target_feature = "avx512ifma")]
#[cfg_attr(docsrs, doc(cfg(target_feature = "avx512ifma")))]
pub(crate) use self::ifma::{ pub(crate) use self::ifma::{
constants::BASEPOINT_ODD_LOOKUP_TABLE, edwards::CachedPoint, edwards::ExtendedPoint, constants::BASEPOINT_ODD_LOOKUP_TABLE, edwards::CachedPoint, edwards::ExtendedPoint,
}; };
#[cfg(any(target_feature = "avx2", target_feature = "avx512ifma", docsrs))] #[cfg(any(target_feature = "avx2", target_feature = "avx512ifma", docsrs))]
#[cfg_attr(
docsrs,
doc(cfg(any(target_feature = "avx2", target_feature = "avx512ifma")))
)]
#[allow(missing_docs)] #[allow(missing_docs)]
pub mod scalar_mul; pub mod scalar_mul;

View file

@ -14,10 +14,13 @@ pub mod variable_base;
pub mod vartime_double_base; pub mod vartime_double_base;
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "std"))))]
pub mod straus; pub mod straus;
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "std"))))]
pub mod precomputed_straus; pub mod precomputed_straus;
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "std"))))]
pub mod pippenger; pub mod pippenger;

View file

@ -24,7 +24,8 @@ use crate::prelude::*;
/// See the documentation in the serial `scalar_mul::pippenger` module for details. /// See the documentation in the serial `scalar_mul::pippenger` module for details.
pub struct Pippenger; pub struct Pippenger;
#[cfg(any(feature = "alloc", feature = "std"))] #[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "std"))))]
impl VartimeMultiscalarMul for Pippenger { impl VartimeMultiscalarMul for Pippenger {
type Point = EdwardsPoint; type Point = EdwardsPoint;

View file

@ -134,9 +134,9 @@ use crate::traits::BasepointTable;
use crate::traits::ValidityCheck; use crate::traits::ValidityCheck;
use crate::traits::{Identity, IsIdentity}; use crate::traits::{Identity, IsIdentity};
#[cfg(any(feature = "alloc", feature = "std"))] #[cfg(feature = "alloc")]
use crate::traits::MultiscalarMul; use crate::traits::MultiscalarMul;
#[cfg(any(feature = "alloc", feature = "std"))] #[cfg(feature = "alloc")]
use crate::traits::{VartimeMultiscalarMul, VartimePrecomputedMultiscalarMul}; use crate::traits::{VartimeMultiscalarMul, VartimePrecomputedMultiscalarMul};
#[cfg(not(all( #[cfg(not(all(
@ -223,6 +223,7 @@ use serde::de::Visitor;
use serde::{self, Deserialize, Deserializer, Serialize, Serializer}; use serde::{self, Deserialize, Deserializer, Serialize, Serializer};
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
impl Serialize for EdwardsPoint { impl Serialize for EdwardsPoint {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where where
@ -238,6 +239,7 @@ impl Serialize for EdwardsPoint {
} }
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
impl Serialize for CompressedEdwardsY { impl Serialize for CompressedEdwardsY {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where where
@ -253,6 +255,7 @@ impl Serialize for CompressedEdwardsY {
} }
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
impl<'de> Deserialize<'de> for EdwardsPoint { impl<'de> Deserialize<'de> for EdwardsPoint {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where where
@ -288,6 +291,7 @@ impl<'de> Deserialize<'de> for EdwardsPoint {
} }
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
impl<'de> Deserialize<'de> for CompressedEdwardsY { impl<'de> Deserialize<'de> for CompressedEdwardsY {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where where
@ -707,6 +711,7 @@ impl<'a, 'b> Mul<&'b EdwardsPoint> for &'a Scalar {
// forward to a specific backend implementation. // forward to a specific backend implementation.
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "std"))))]
impl MultiscalarMul for EdwardsPoint { impl MultiscalarMul for EdwardsPoint {
type Point = EdwardsPoint; type Point = EdwardsPoint;
@ -739,6 +744,7 @@ impl MultiscalarMul for EdwardsPoint {
} }
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "std"))))]
impl VartimeMultiscalarMul for EdwardsPoint { impl VartimeMultiscalarMul for EdwardsPoint {
type Point = EdwardsPoint; type Point = EdwardsPoint;
@ -778,9 +784,11 @@ impl VartimeMultiscalarMul for EdwardsPoint {
// decouple stability of the inner type from the stability of the // decouple stability of the inner type from the stability of the
// outer type. // outer type.
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "std"))))]
pub struct VartimeEdwardsPrecomputation(scalar_mul::precomputed_straus::VartimePrecomputedStraus); pub struct VartimeEdwardsPrecomputation(scalar_mul::precomputed_straus::VartimePrecomputedStraus);
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "std"))))]
impl VartimePrecomputedMultiscalarMul for VartimeEdwardsPrecomputation { impl VartimePrecomputedMultiscalarMul for VartimeEdwardsPrecomputation {
type Point = EdwardsPoint; type Point = EdwardsPoint;

View file

@ -38,8 +38,16 @@ use crate::constants;
cfg_if! { cfg_if! {
if #[cfg(feature = "fiat_backend")] { if #[cfg(feature = "fiat_backend")] {
#[cfg(not(target_pointer_width = "64"))] #[cfg(not(target_pointer_width = "64"))]
#[cfg_attr(
docsrs,
doc(cfg(all(feature = "fiat_backend", not(target_pointer_width = "64"))))
)]
pub use backend::serial::fiat_u32::field::*; pub use backend::serial::fiat_u32::field::*;
#[cfg(target_pointer_width = "64")] #[cfg(target_pointer_width = "64")]
#[cfg_attr(
docsrs,
doc(cfg(all(feature = "fiat_backend", target_pointer_width = "64")))
)]
pub use backend::serial::fiat_u64::field::*; pub use backend::serial::fiat_u64::field::*;
/// A `FieldElement` represents an element of the field /// A `FieldElement` represents an element of the field
@ -50,6 +58,10 @@ cfg_if! {
/// ///
/// Using formally-verified field arithmetic from fiat-crypto. /// Using formally-verified field arithmetic from fiat-crypto.
#[cfg(not(target_pointer_width = "64"))] #[cfg(not(target_pointer_width = "64"))]
#[cfg_attr(
docsrs,
doc(cfg(all(feature = "fiat_backend", not(target_pointer_width = "64"))))
)]
pub type FieldElement = backend::serial::fiat_u32::field::FieldElement2625; pub type FieldElement = backend::serial::fiat_u32::field::FieldElement2625;
/// A `FieldElement` represents an element of the field /// A `FieldElement` represents an element of the field
@ -60,8 +72,13 @@ cfg_if! {
/// ///
/// Using formally-verified field arithmetic from fiat-crypto. /// Using formally-verified field arithmetic from fiat-crypto.
#[cfg(target_pointer_width = "64")] #[cfg(target_pointer_width = "64")]
#[cfg_attr(
docsrs,
doc(cfg(all(feature = "fiat_backend", target_pointer_width = "64")))
)]
pub type FieldElement = backend::serial::fiat_u64::field::FieldElement51; pub type FieldElement = backend::serial::fiat_u64::field::FieldElement51;
} else if #[cfg(target_pointer_width = "64")] { } else if #[cfg(target_pointer_width = "64")] {
#[cfg_attr(docsrs, doc(cfg(target_pointer_width = "64")))]
pub use crate::backend::serial::u64::field::*; pub use crate::backend::serial::u64::field::*;
/// A `FieldElement` represents an element of the field /// A `FieldElement` represents an element of the field
@ -69,8 +86,10 @@ cfg_if! {
/// ///
/// The `FieldElement` type is an alias for one of the platform-specific /// The `FieldElement` type is an alias for one of the platform-specific
/// implementations. /// implementations.
#[cfg_attr(docsrs, doc(cfg(target_pointer_width = "64")))]
pub type FieldElement = backend::serial::u64::field::FieldElement51; pub type FieldElement = backend::serial::u64::field::FieldElement51;
} else { } else {
#[cfg_attr(docsrs, doc(cfg(not(target_pointer_width = "64"))))]
pub use backend::serial::u32::field::*; pub use backend::serial::u32::field::*;
/// A `FieldElement` represents an element of the field /// A `FieldElement` represents an element of the field
@ -78,6 +97,7 @@ cfg_if! {
/// ///
/// The `FieldElement` type is an alias for one of the platform-specific /// The `FieldElement` type is an alias for one of the platform-specific
/// implementations. /// implementations.
#[cfg_attr(docsrs, doc(cfg(not(target_pointer_width = "64"))))]
pub type FieldElement = backend::serial::u32::field::FieldElement2625; pub type FieldElement = backend::serial::u32::field::FieldElement2625;
} }
} }
@ -167,6 +187,7 @@ impl FieldElement {
/// ///
/// When an input `FieldElement` is zero, its value is unchanged. /// When an input `FieldElement` is zero, its value is unchanged.
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "std"))))]
pub fn batch_invert(inputs: &mut [FieldElement]) { pub fn batch_invert(inputs: &mut [FieldElement]) {
// Montgomerys Trick and Fast Implementation of Masked AES // Montgomerys Trick and Fast Implementation of Masked AES
// Genelle, Prouff and Quisquater // Genelle, Prouff and Quisquater

View file

@ -190,7 +190,7 @@ use crate::scalar::Scalar;
use crate::traits::BasepointTable; use crate::traits::BasepointTable;
use crate::traits::Identity; use crate::traits::Identity;
#[cfg(any(feature = "alloc", feature = "std"))] #[cfg(feature = "alloc")]
use crate::traits::{MultiscalarMul, VartimeMultiscalarMul, VartimePrecomputedMultiscalarMul}; use crate::traits::{MultiscalarMul, VartimeMultiscalarMul, VartimePrecomputedMultiscalarMul};
#[cfg(not(all( #[cfg(not(all(
@ -341,6 +341,7 @@ use serde::de::Visitor;
use serde::{self, Deserialize, Deserializer, Serialize, Serializer}; use serde::{self, Deserialize, Deserializer, Serialize, Serializer};
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
impl Serialize for RistrettoPoint { impl Serialize for RistrettoPoint {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where where
@ -356,6 +357,7 @@ impl Serialize for RistrettoPoint {
} }
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
impl Serialize for CompressedRistretto { impl Serialize for CompressedRistretto {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where where
@ -371,6 +373,7 @@ impl Serialize for CompressedRistretto {
} }
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
impl<'de> Deserialize<'de> for RistrettoPoint { impl<'de> Deserialize<'de> for RistrettoPoint {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where where
@ -406,6 +409,7 @@ impl<'de> Deserialize<'de> for RistrettoPoint {
} }
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
impl<'de> Deserialize<'de> for CompressedRistretto { impl<'de> Deserialize<'de> for CompressedRistretto {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where where
@ -520,6 +524,7 @@ impl RistrettoPoint {
/// # } /// # }
/// ``` /// ```
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "std"))))]
pub fn double_and_compress_batch<'a, I>(points: I) -> Vec<CompressedRistretto> pub fn double_and_compress_batch<'a, I>(points: I) -> Vec<CompressedRistretto>
where where
I: IntoIterator<Item = &'a RistrettoPoint>, I: IntoIterator<Item = &'a RistrettoPoint>,
@ -922,6 +927,7 @@ define_mul_variants!(LHS = Scalar, RHS = RistrettoPoint, Output = RistrettoPoint
// forward to the EdwardsPoint implementations. // forward to the EdwardsPoint implementations.
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "std"))))]
impl MultiscalarMul for RistrettoPoint { impl MultiscalarMul for RistrettoPoint {
type Point = RistrettoPoint; type Point = RistrettoPoint;
@ -938,6 +944,7 @@ impl MultiscalarMul for RistrettoPoint {
} }
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "std"))))]
impl VartimeMultiscalarMul for RistrettoPoint { impl VartimeMultiscalarMul for RistrettoPoint {
type Point = RistrettoPoint; type Point = RistrettoPoint;
@ -958,9 +965,11 @@ impl VartimeMultiscalarMul for RistrettoPoint {
// decouple stability of the inner type from the stability of the // decouple stability of the inner type from the stability of the
// outer type. // outer type.
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "std"))))]
pub struct VartimeRistrettoPrecomputation(scalar_mul::precomputed_straus::VartimePrecomputedStraus); pub struct VartimeRistrettoPrecomputation(scalar_mul::precomputed_straus::VartimePrecomputedStraus);
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "std"))))]
impl VartimePrecomputedMultiscalarMul for VartimeRistrettoPrecomputation { impl VartimePrecomputedMultiscalarMul for VartimeRistrettoPrecomputation {
type Point = RistrettoPoint; type Point = RistrettoPoint;

View file

@ -173,6 +173,10 @@ cfg_if! {
/// This is a type alias for one of the scalar types in the `backend` /// This is a type alias for one of the scalar types in the `backend`
/// module. /// module.
#[cfg(not(target_pointer_width = "64"))] #[cfg(not(target_pointer_width = "64"))]
#[cfg_attr(
docsrs,
doc(cfg(all(feature = "fiat_backend", not(target_pointer_width = "64"))))
)]
type UnpackedScalar = backend::serial::fiat_u32::scalar::Scalar29; type UnpackedScalar = backend::serial::fiat_u32::scalar::Scalar29;
/// An `UnpackedScalar` represents an element of the field GF(l), optimized for speed. /// An `UnpackedScalar` represents an element of the field GF(l), optimized for speed.
@ -180,18 +184,24 @@ cfg_if! {
/// This is a type alias for one of the scalar types in the `backend` /// This is a type alias for one of the scalar types in the `backend`
/// module. /// module.
#[cfg(target_pointer_width = "64")] #[cfg(target_pointer_width = "64")]
#[cfg_attr(
docsrs,
doc(cfg(all(feature = "fiat_backend", target_pointer_width = "64")))
)]
type UnpackedScalar = backend::serial::fiat_u64::scalar::Scalar52; type UnpackedScalar = backend::serial::fiat_u64::scalar::Scalar52;
} else if #[cfg(target_pointer_width = "64")] { } else if #[cfg(target_pointer_width = "64")] {
/// An `UnpackedScalar` represents an element of the field GF(l), optimized for speed. /// An `UnpackedScalar` represents an element of the field GF(l), optimized for speed.
/// ///
/// This is a type alias for one of the scalar types in the `backend` /// This is a type alias for one of the scalar types in the `backend`
/// module. /// module.
#[cfg_attr(docsrs, doc(cfg(target_pointer_width = "64")))]
type UnpackedScalar = backend::serial::u64::scalar::Scalar52; type UnpackedScalar = backend::serial::u64::scalar::Scalar52;
} else { } else {
/// An `UnpackedScalar` represents an element of the field GF(l), optimized for speed. /// An `UnpackedScalar` represents an element of the field GF(l), optimized for speed.
/// ///
/// This is a type alias for one of the scalar types in the `backend` /// This is a type alias for one of the scalar types in the `backend`
/// module. /// module.
#[cfg_attr(docsrs, doc(cfg(not(target_pointer_width = "64"))))]
type UnpackedScalar = backend::serial::u32::scalar::Scalar29; type UnpackedScalar = backend::serial::u32::scalar::Scalar29;
} }
} }
@ -401,6 +411,7 @@ use serde::de::Visitor;
use serde::{self, Deserialize, Deserializer, Serialize, Serializer}; use serde::{self, Deserialize, Deserializer, Serialize, Serializer};
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
impl Serialize for Scalar { impl Serialize for Scalar {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where where
@ -416,6 +427,7 @@ impl Serialize for Scalar {
} }
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
impl<'de> Deserialize<'de> for Scalar { impl<'de> Deserialize<'de> for Scalar {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where where
@ -773,6 +785,7 @@ impl Scalar {
/// # } /// # }
/// ``` /// ```
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "std"))))]
pub fn batch_invert(inputs: &mut [Scalar]) -> Scalar { pub fn batch_invert(inputs: &mut [Scalar]) -> Scalar {
// This code is essentially identical to the FieldElement // This code is essentially identical to the FieldElement
// implementation, and is documented there. Unfortunately, // implementation, and is documented there. Unfortunately,