-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #28 from Andenis-Bu/eip-7594
Arkworks3 Eip-7594 implementation
- Loading branch information
Showing
34 changed files
with
1,753 additions
and
951 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,87 +1,91 @@ | ||
use crate::kzg_proofs::FFTSettings; | ||
use crate::kzg_proofs::LFFTSettings; | ||
use crate::kzg_types::ArkFr as BlstFr; | ||
use kzg::{Fr, DAS}; | ||
use std::cmp::Ordering; | ||
|
||
impl FFTSettings { | ||
fn das_fft_extension_stride(&self, ab: &mut [BlstFr], stride: usize) { | ||
match ab.len().cmp(&2_usize) { | ||
Ordering::Less => {} | ||
Ordering::Greater => { | ||
let half = ab.len(); | ||
let halfhalf = half / 2; | ||
impl LFFTSettings { | ||
pub fn das_fft_extension_stride(&self, evens: &mut [BlstFr], stride: usize) { | ||
match evens.len().cmp(&2) { | ||
Ordering::Less => { | ||
return; | ||
} | ||
Ordering::Equal => { | ||
let x = evens[0].add(&evens[1]); | ||
let y = evens[0].sub(&evens[1]); | ||
let y_times_root = y.mul(&self.roots_of_unity[stride]); | ||
|
||
for i in 0..halfhalf { | ||
let tmp1 = ab[i].add(&ab[halfhalf + i]); | ||
let tmp2 = ab[i].sub(&ab[halfhalf + i]); | ||
ab[halfhalf + i] = tmp2.mul(&self.reverse_roots_of_unity[i * 2 * stride]); | ||
ab[i] = tmp1; | ||
} | ||
evens[0] = x.add(&y_times_root); | ||
evens[1] = x.sub(&y_times_root); | ||
|
||
#[cfg(feature = "parallel")] | ||
{ | ||
if ab.len() > 32 { | ||
let (lo, hi) = ab.split_at_mut(halfhalf); | ||
rayon::join( | ||
|| self.das_fft_extension_stride(hi, stride * 2), | ||
|| self.das_fft_extension_stride(lo, stride * 2), | ||
); | ||
} else { | ||
self.das_fft_extension_stride(&mut ab[..halfhalf], stride * 2); | ||
self.das_fft_extension_stride(&mut ab[halfhalf..], stride * 2); | ||
} | ||
} | ||
#[cfg(not(feature = "parallel"))] | ||
{ | ||
self.das_fft_extension_stride(&mut ab[..halfhalf], stride * 2); | ||
self.das_fft_extension_stride(&mut ab[halfhalf..], stride * 2); | ||
} | ||
for i in 0..halfhalf { | ||
let x = ab[i]; | ||
let y = ab[halfhalf + i]; | ||
let y_times_root = y.mul(&self.expanded_roots_of_unity[(1 + 2 * i) * stride]); | ||
ab[i] = x.add(&y_times_root); | ||
ab[halfhalf + i] = x.sub(&y_times_root); | ||
} | ||
return; | ||
} | ||
Ordering::Equal => { | ||
let x = ab[0].add(&ab[1]); | ||
let y = ab[0].sub(&ab[1]); | ||
let tmp = y.mul(&self.expanded_roots_of_unity[stride]); | ||
Ordering::Greater => {} | ||
} | ||
|
||
let half: usize = evens.len() / 2; | ||
for i in 0..half { | ||
let tmp1 = evens[i].add(&evens[half + i]); | ||
let tmp2 = evens[i].sub(&evens[half + i]); | ||
evens[half + i] = tmp2.mul(&self.reverse_roots_of_unity[i * 2 * stride]); | ||
|
||
ab[0] = x.add(&tmp); | ||
ab[1] = x.sub(&tmp); | ||
evens[i] = tmp1; | ||
} | ||
|
||
#[cfg(feature = "parallel")] | ||
{ | ||
if evens.len() > 32 { | ||
let (lo, hi) = evens.split_at_mut(half); | ||
rayon::join( | ||
|| self.das_fft_extension_stride(hi, stride * 2), | ||
|| self.das_fft_extension_stride(lo, stride * 2), | ||
); | ||
} else { | ||
// Recurse | ||
self.das_fft_extension_stride(&mut evens[..half], stride * 2); | ||
self.das_fft_extension_stride(&mut evens[half..], stride * 2); | ||
} | ||
} | ||
} | ||
} | ||
|
||
impl DAS<BlstFr> for FFTSettings { | ||
fn das_fft_extension(&self, vals: &[BlstFr]) -> Result<Vec<BlstFr>, String> { | ||
if vals.is_empty() { | ||
return Err(String::from("vals can not be empty")); | ||
#[cfg(not(feature = "parallel"))] | ||
{ | ||
// Recurse | ||
self.das_fft_extension_stride(&mut evens[..half], stride * 2); | ||
self.das_fft_extension_stride(&mut evens[half..], stride * 2); | ||
} | ||
if !vals.len().is_power_of_two() { | ||
return Err(String::from("vals lenght has to be power of 2")); | ||
|
||
for i in 0..half { | ||
let x = evens[i]; | ||
let y = evens[half + i]; | ||
let y_times_root: BlstFr = y.mul(&self.roots_of_unity[(1 + 2 * i) * stride]); | ||
|
||
evens[i] = x.add(&y_times_root); | ||
evens[half + i] = x.sub(&y_times_root); | ||
} | ||
if vals.len() * 2 > self.max_width { | ||
} | ||
} | ||
|
||
impl DAS<BlstFr> for LFFTSettings { | ||
fn das_fft_extension(&self, evens: &[BlstFr]) -> Result<Vec<BlstFr>, String> { | ||
Check failure on line 68 in arkworks3/src/das.rs GitHub Actions / backend_ci (ubuntu-latest, arkworks3)
Check failure on line 68 in arkworks3/src/das.rs GitHub Actions / benchmarks (ubuntu-latest, arkworks3)
Check failure on line 68 in arkworks3/src/das.rs GitHub Actions / benchmarks (windows-latest, arkworks3)
Check failure on line 68 in arkworks3/src/das.rs GitHub Actions / backend_ci (windows-latest, arkworks3)
Check failure on line 68 in arkworks3/src/das.rs GitHub Actions / backend_ci (macos-latest, arkworks3)
|
||
if evens.is_empty() { | ||
return Err(String::from("A non-zero list ab expected")); | ||
} else if !evens.len().is_power_of_two() { | ||
return Err(String::from("A list with power-of-two length expected")); | ||
} else if evens.len() * 2 > self.max_width { | ||
return Err(String::from( | ||
"vals lenght * 2 has to equal or less than FFTSetings max width", | ||
"Supplied list is longer than the available max width", | ||
)); | ||
} | ||
|
||
let mut vals = vals.to_vec(); | ||
let stride = self.max_width / (vals.len() * 2); | ||
|
||
self.das_fft_extension_stride(&mut vals, stride); | ||
// In case more roots are provided with fft_settings, use a larger stride | ||
let stride = self.max_width / (evens.len() * 2); | ||
let mut odds = evens.to_vec(); | ||
self.das_fft_extension_stride(&mut odds, stride); | ||
|
||
let invlen = BlstFr::from_u64(vals.len() as u64); | ||
let invlen = invlen.inverse(); | ||
|
||
for val in &mut vals { | ||
val.fr *= invlen.fr | ||
} | ||
// TODO: explain why each odd member is multiplied by euclidean inverse of length | ||
let mut inv_len = BlstFr::from_u64(odds.len() as u64); | ||
inv_len = inv_len.eucl_inverse(); | ||
let odds = odds.iter().map(|f| f.mul(&inv_len)).collect(); | ||
|
||
Ok(vals) | ||
Ok(odds) | ||
} | ||
} |
Oops, something went wrong.