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}