Skip to main content

wnaf/
traits.rs

1//! Trait definitions.
2
3use array::{
4    ArraySize,
5    typenum::{U1, U2, U3, U4, U5, U6, U7, U8, U16, U32, U64, Unsigned},
6};
7use ff::PrimeField;
8use group::Group;
9
10/// Allowed wNAF window size: we use this to precompute the window point sizes, because it's
11/// currently not possible to write bounds for them.
12pub trait WindowSize: Unsigned {
13    /// Number of precomputed points in the window table: `1 << (Self::USIZE - 2)`.
14    type TableSize: ArraySize;
15}
16
17/// Extension trait on a [`Group`] that provides helpers used by [`crate::BoxedWnaf`].
18pub trait WnafGroup: Group {
19    /// Recommends a wNAF window size given the number of scalars you intend to multiply
20    /// a base by. Always returns a number between 2 and [`W_MAX`][`crate::W_MAX`], inclusive.
21    fn recommended_wnaf_for_num_scalars(num_scalars: usize) -> usize;
22}
23
24/// Size of the wNAF representation: this should be the type-level equivalent of
25/// `PrimeField::NUM_BITS + 1`, which includes an extra entry for any remaining carry.
26pub trait WnafSize: PrimeField {
27    /// Number of digits in the wNAF representation.
28    type StorageSize: ArraySize;
29}
30
31// TODO(tarcieri): compute or failing that test window sizes
32macro_rules! impl_window_sizes {
33    ($($window_size:ty => $table_size:ty),+) => {
34        $(
35            impl WindowSize for $window_size {
36                type TableSize = $table_size;
37            }
38        )+
39    };
40}
41
42// NOTE: the maximum size supported here should match the `W_MAX` constant
43impl_window_sizes!(U2 => U1, U3 => U2, U4 => U4, U5 => U8, U6 => U16, U7 => U32, U8 => U64);
44
45/// Write an impl of the `WnafSize` trait automatically based on the `PrimeField` impl.
46#[macro_export]
47macro_rules! impl_wnaf_size_for_scalar {
48    ($fe:ty) => {
49        impl $crate::WnafSize for $fe {
50            type StorageSize = $crate::array::typenum::U<{ (Self::NUM_BITS + 1) as usize }>;
51        }
52    };
53}