Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/backend-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ jobs:
- backend: zkcrypto
support_wasm: true
support_ckzg: true
clippy-flag: --all-features
- backend: arkworks4
support_wasm: true
support_ckzg: true
Expand Down
3 changes: 3 additions & 0 deletions arkworks3/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ c_bindings = []
diskcache = [
"kzg/diskcache"
]
bos_coster = [
"kzg/bos_coster"
]

[[bench]]
name = "fft"
Expand Down
3 changes: 3 additions & 0 deletions arkworks4/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ rand = [
bgmw = [
"kzg/bgmw"
]
bos_coster = [
"kzg/bos_coster"
]
wbits = [
"kzg/wbits"
]
Expand Down
3 changes: 3 additions & 0 deletions arkworks5/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ rand = [
bgmw = [
"kzg/bgmw"
]
bos_coster = [
"kzg/bos_coster"
]
arkmsm = [
"kzg/arkmsm"
]
Expand Down
3 changes: 3 additions & 0 deletions blst/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ parallel = [
bgmw = [
"kzg/bgmw"
]
bos_coster = [
"kzg/bos_coster"
]
arkmsm = [
"kzg/arkmsm"
]
Expand Down
3 changes: 3 additions & 0 deletions constantine/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ constantine_msm = []
bgmw = [
"kzg/bgmw"
]
bos_coster = [
"kzg/bos_coster"
]
arkmsm = [
"kzg/arkmsm"
]
Expand Down
6 changes: 6 additions & 0 deletions fuzz/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ parallel = [
"rust-kzg-constantine/parallel",
"rust-kzg-mcl/parallel",
]
bos_coster = [
"rust-kzg-blst/bos_coster",
Comment thread
mykolas-alt marked this conversation as resolved.
"rust-kzg-arkworks4/bos_coster",
"rust-kzg-arkworks5/bos_coster",
"rust-kzg-constantine/bos_coster",
]

# backends
arkworks3=["dep:rust-kzg-arkworks3"]
Expand Down
3 changes: 2 additions & 1 deletion kzg/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ edition = "2021"
[dependencies]
sha2 = { version = "0.10.6", default-features = false }
num_cpus = { version = "1.16.0", optional = true }
rayon = { version = "1.8.0", optional = true }
rayon = { version = "1.8.0", optional = true }
threadpool = { version = "^1.8.1", optional = true }
siphasher = { version = "1.0.0", default-features = false }
hashbrown = "0.15.2"
Expand All @@ -32,6 +32,7 @@ std = [
rand = []
arkmsm = []
bgmw = []
bos_coster = []
sppark = []
wbits = []
diskcache = [
Expand Down
171 changes: 170 additions & 1 deletion kzg/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ extern crate alloc;

use alloc::{borrow::ToOwned, string::String, vec::Vec};
use arbitrary::Arbitrary;
use core::fmt::Debug;
use core::{
cmp::Ordering,
fmt::Debug,
ops::{Shl, Sub},
};
use msm::precompute::PrecomputationTable;

pub mod common_utils;
Expand Down Expand Up @@ -393,6 +397,80 @@ impl Scalar256 {
}
}
}

#[inline(always)]
fn leading_zeros(&self) -> u32 {
for i in (0..4).rev() {
if self.data[i] != 0 {
return (i as u32) * 64 + (64 - self.data[i].leading_zeros());
}
}
0
}
}

impl Ord for Scalar256 {
#[inline(always)]
fn cmp(&self, other: &Self) -> Ordering {
for i in (0..4).rev() {
if self.data[i] < other.data[i] {
return Ordering::Less;
} else if self.data[i] > other.data[i] {
return Ordering::Greater;
}
}
Ordering::Equal
}
}

impl Shl<u32> for Scalar256 {
type Output = Scalar256;

// This function was generated with ChatGPT
#[inline(always)]
fn shl(self, n: u32) -> Scalar256 {
Comment thread
mykolas-alt marked this conversation as resolved.
if n == 0 {
return self;
}
let limb_shift = (n / 64) as usize;
let bit_shift = n % 64;
let mut res = [0u64; 4];

for i in (0..4).rev() {
if i < limb_shift {
continue;
}
let mut val = self.data[i - limb_shift] << bit_shift;
if bit_shift != 0 && i - limb_shift > 0 {
val |= self.data[i - limb_shift - 1] >> (64 - bit_shift);
}
res[i] = val;
}
Scalar256::from_u64(res)
}
}

impl PartialOrd for Scalar256 {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}

impl Sub for Scalar256 {
type Output = Scalar256;

#[inline(always)]
fn sub(self, rhs: Scalar256) -> Scalar256 {
let mut result = Scalar256::ZERO;
let mut borrow = 0u64;
for i in 0..4 {
let (rhs_with_borrow, overflow_add) = rhs.data[i].overflowing_add(borrow);
let (res, overflow_sub) = self.data[i].overflowing_sub(rhs_with_borrow);
result.data[i] = res;
borrow = if overflow_add || overflow_sub { 1 } else { 0 };
}
result
}
}

pub trait G2: Clone + Default {
Expand Down Expand Up @@ -645,3 +723,94 @@ pub trait FK20MultiSettings<

fn data_availability_optimized(&self, p: &Polynomial) -> Result<Vec<Coeff2>, String>;
}

#[cfg(test)]
mod test {
use crate::Scalar256;

#[test]
fn shl_must_shift_2_bits() {
let scalar = Scalar256::from_u64_s(0b101);
let expected = Scalar256::from_u64_s(0b10100);
let received = scalar << 2;
assert_eq!(expected, received);
}

#[test]
fn shl_must_shift_2_bits_over_array_bounds() {
let scalar = Scalar256::from_u64([
0b1101000000000000000000000000000000000000000000000000000000000000,
0,
0,
0,
]);
let expected = Scalar256::from_u64([
0b0100000000000000000000000000000000000000000000000000000000000000,
0b0000000000000000000000000000000000000000000000000000000000000011,
0,
0,
]);
let received = scalar << 2;
assert_eq!(expected, received);
}

#[test]
fn shl_must_shift_2_bits_over_two_array_bounds() {
let scalar = Scalar256::from_u64([
0b1101000000000000000000000000000000000000000000000000000000000000,
0,
0b1101000000000000000000000000000000000000000000000000000000000000,
0,
]);
let expected = Scalar256::from_u64([
0b0100000000000000000000000000000000000000000000000000000000000000,
0b0000000000000000000000000000000000000000000000000000000000000011,
0b0100000000000000000000000000000000000000000000000000000000000000,
0b0000000000000000000000000000000000000000000000000000000000000011,
]);
let received = scalar << 2;
assert_eq!(expected, received);
}

#[test]
fn shl_must_shift_2_bits_overflowing_scalar256() {
let scalar = Scalar256::from_u64([
0,
0,
0,
0b1101000000000000000000000000000000000000000000000000000000000000,
]);
let expected = Scalar256::from_u64([
0,
0,
0,
0b0100000000000000000000000000000000000000000000000000000000000000,
]);
let received = scalar << 2;
assert_eq!(expected, received);
}

#[test]
fn shl_must_null_any_number_if_shifted_256_times() {
let scalar = Scalar256::from_u64([
0b1111111111111111111111111111111111111111111111111111111111111111,
0b1111111111111111111111111111111111111111111111111111111111111111,
0b1111111111111111111111111111111111111111111111111111111111111111,
0b1111111111111111111111111111111111111111111111111111111111111111,
]);
let expected = Scalar256::from_u64([0, 0, 0, 0]);
let received = scalar << 256;
assert_eq!(expected, received);
}

#[test]
fn shl_is_the_same_as_doubling() {
let mut current_integer = 1u64;
let mut current_scalar = Scalar256::from_u64_s(current_integer);
for _ in 0..63 {
current_scalar = current_scalar << 1;
current_integer *= 2;
assert_eq!(Scalar256::from_u64_s(current_integer), current_scalar);
}
}
}
Loading
Loading