From 74ce37250e17bc48de4e687712fcaa4a3b4f6b07 Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Mon, 5 Apr 2021 11:39:16 -0700 Subject: [PATCH] Avoid separate exp calls --- src/field/cosets.rs | 4 ++-- src/field/field.rs | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/field/cosets.rs b/src/field/cosets.rs index d53a2ff6..5ef8566b 100644 --- a/src/field/cosets.rs +++ b/src/field/cosets.rs @@ -14,8 +14,8 @@ pub(crate) fn get_unique_coset_shifts( // Let g be a generator of the entire multiplicative group. Let n be the order of the subgroup. // The subgroup can be written as . We can use g^0, ..., g^(num_shifts - 1) as our // shifts, since g^i are distinct cosets provided i < |F*| / n, which we checked. - (0..num_shifts) - .map(|i| F::MULTIPLICATIVE_GROUP_GENERATOR.exp_usize(i)) + F::MULTIPLICATIVE_GROUP_GENERATOR.powers() + .take(num_shifts) .collect() } diff --git a/src/field/field.rs b/src/field/field.rs index b28972c3..869b3f6e 100644 --- a/src/field/field.rs +++ b/src/field/field.rs @@ -143,6 +143,10 @@ pub trait Field: 'static self.exp(Self::from_canonical_usize(power)) } + fn powers(&self) -> Powers { + Powers { base: *self, current: Self::ONE } + } + fn rand_from_rng(rng: &mut R) -> Self { Self::from_canonical_u64(rng.gen_range(0, Self::ORDER)) } @@ -151,3 +155,19 @@ pub trait Field: 'static Self::rand_from_rng(&mut OsRng) } } + +/// An iterator over the powers of a certain base element `b`: `b^0, b^1, b^2, ...`. +pub struct Powers { + base: F, + current: F, +} + +impl Iterator for Powers { + type Item = F; + + fn next(&mut self) -> Option { + let result = self.current; + self.current *= self.base; + Some(result) + } +}