Skip to content

Commit b8cc199

Browse files
authored
Merge pull request #209 from WizardOfMenlo/recmo/update-spongefish
Update spongefish
2 parents cf1599b + 42fd01d commit b8cc199

43 files changed

Lines changed: 3611 additions & 2084 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Cargo.lock

Lines changed: 689 additions & 341 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -38,27 +38,28 @@ ark-ff = { version = "0.5", features = ["asm", "std"] }
3838
ark-serialize = "0.5"
3939
ark-crypto-primitives = { version = "0.5", features = ["merkle_tree"] }
4040
ark-poly = "0.5"
41-
blake3 = "1.5.0"
42-
sha3 = "0.10"
43-
rand = "0.8"
44-
clap = { version = "4.4.17", features = ["derive"] }
41+
blake3 = { version = "1.5", features = ["digest"] }
42+
sha3 = { version = "0.10.7", features = ["asm", "oid"] }
43+
clap = { version = "4.4", features = ["derive"] }
4544
serde = { version = "1.0", features = ["derive"] }
4645
serde_json = "1.0"
47-
spongefish = { git = "https://github.com/arkworks-rs/spongefish", features = [
48-
"arkworks-algebra",
49-
], rev = "ecb4f08373ed930175585c856517efdb1851fb47"}
50-
spongefish-pow = { git = "https://github.com/arkworks-rs/spongefish" , rev = "ecb4f08373ed930175585c856517efdb1851fb47" }
51-
rayon = { version = "1.10.0", optional = true }
46+
spongefish = { git = "https://github.com/arkworks-rs/spongefish", features = ["ark-ff"], rev = "fcc277f8a857fdeeadd7cca92ab08de63b1ff1a1"}
47+
rayon = { version = "1.10", optional = true }
5248
thiserror = "2.0"
5349
itertools = "0.14"
54-
tracing = { version = "0.1.41", optional = true }
55-
hex = "0.4.3"
50+
tracing = { version = "0.1", optional = true }
51+
hex = "0.4"
52+
static_assertions = "1.1.0"
53+
ciborium = "0.2"
54+
digest = { version = "0.10.7", features = ["oid"] }
55+
sha2 = { version = "0.10.9", features = ["oid", "asm"] }
56+
zerocopy = "0.8.33"
57+
hex-literal = "0.4.1"
5658

5759
[dev-dependencies]
5860
proptest = "1.0"
5961
serde_json = "1.0"
60-
postcard = { version = "1.1", features = ["alloc"] }
61-
divan = { version = "2.10.0", package = "codspeed-divan-compat" }
62+
divan = { version = "4.2", package = "codspeed-divan-compat" }
6263

6364
[profile.release]
6465
debug = true
@@ -82,3 +83,17 @@ harness = false
8283
[[bench]]
8384
name = "sumcheck"
8485
harness = false
86+
87+
[profile.dev]
88+
debug = 1
89+
opt-level = 1
90+
codegen-units = 16
91+
incremental = true
92+
93+
# Enable a large amount of optimization in the dev profile for dependencies.
94+
[profile.dev.package."*"]
95+
opt-level = 3
96+
97+
[profile.samply]
98+
inherits = "release"
99+
debug = true

src/ark_serde.rs

Lines changed: 199 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,212 @@
11
//! Workaround for `ark_ff` lacking Serde support.
22
//! See <https://github.com/arkworks-rs/algebra/pull/506>
33
4-
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
54
use serde::{de::Error as _, ser::Error as _, Deserialize as _, Deserializer, Serializer};
65

7-
pub fn serialize<T, S>(obj: &T, serializer: S) -> Result<S::Ok, S::Error>
8-
where
9-
T: CanonicalSerialize,
10-
S: Serializer,
11-
{
12-
// Convert to bytes
13-
let mut buf = Vec::with_capacity(obj.compressed_size());
14-
obj.serialize_compressed(&mut buf)
15-
.map_err(|e| S::Error::custom(format!("Failed to serialize: {e}")))?;
16-
17-
// Write bytes
18-
if serializer.is_human_readable() {
19-
// ark_serialize doesn't have human-readable serialization. And Serde
20-
// doesn't have good defaults for [u8]. So we manually implement hexadecimal
21-
// serialization.
22-
let hex = hex::encode(buf);
23-
serializer.serialize_str(&hex)
24-
} else {
25-
serializer.serialize_bytes(&buf)
6+
/// Serialize using ark_serialize
7+
pub mod canonical {
8+
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
9+
10+
use super::*;
11+
12+
pub fn serialize<T, S>(obj: &T, serializer: S) -> Result<S::Ok, S::Error>
13+
where
14+
T: CanonicalSerialize,
15+
S: Serializer,
16+
{
17+
let mut buf = Vec::with_capacity(obj.compressed_size());
18+
obj.serialize_compressed(&mut buf)
19+
.map_err(|e| S::Error::custom(format!("Failed to serialize: {e}")))?;
20+
super::bytes::serialize(&buf, serializer)
21+
}
22+
23+
pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
24+
where
25+
T: CanonicalDeserialize,
26+
D: Deserializer<'de>,
27+
{
28+
let bytes = super::bytes::deserialize(deserializer)?;
29+
let mut reader = &*bytes;
30+
let obj = T::deserialize_compressed(&mut reader)
31+
.map_err(|e| D::Error::custom(format!("while deserializing: {e}")))?;
32+
if !reader.is_empty() {
33+
return Err(D::Error::custom("while deserializing: trailing bytes"));
34+
}
35+
36+
Ok(obj)
2637
}
2738
}
2839

29-
pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
30-
where
31-
T: CanonicalDeserialize,
32-
D: Deserializer<'de>,
33-
{
34-
// Read bytes
35-
let bytes = if deserializer.is_human_readable() {
36-
let hex = String::deserialize(deserializer)?;
37-
hex::decode(hex).map_err(|e| D::Error::custom(format!("while deserializing bytes: {e}")))?
38-
} else {
39-
<Vec<u8>>::deserialize(deserializer)?
40+
pub mod bytes {
41+
use super::*;
42+
43+
pub fn serialize<S>(value: &[u8], serializer: S) -> Result<S::Ok, S::Error>
44+
where
45+
S: Serializer,
46+
{
47+
if serializer.is_human_readable() {
48+
let hex = hex::encode(value);
49+
serializer.serialize_str(&hex)
50+
} else {
51+
serializer.serialize_bytes(value)
52+
}
53+
}
54+
55+
pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
56+
where
57+
D: Deserializer<'de>,
58+
{
59+
if deserializer.is_human_readable() {
60+
let hex = String::deserialize(deserializer)?;
61+
hex::decode(hex)
62+
.map_err(|e| D::Error::custom(format!("while deserializing bytes: {e}")))
63+
} else {
64+
<Vec<u8>>::deserialize(deserializer)
65+
}
66+
}
67+
}
68+
69+
pub mod bigint {
70+
use std::iter::repeat;
71+
72+
use ark_ff::BigInteger;
73+
use zerocopy::IntoBytes;
74+
75+
use super::*;
76+
77+
pub fn serialize<T, S>(obj: &T, serializer: S) -> Result<S::Ok, S::Error>
78+
where
79+
T: BigInteger,
80+
S: Serializer,
81+
{
82+
// Encode as big endian bytes without leading zeros.
83+
let value = obj.to_bytes_be();
84+
let leading_zeros = value.iter().take_while(|&&b| b == 0).count();
85+
let value = &value[leading_zeros..];
86+
bytes::serialize(value, serializer)
87+
}
88+
89+
pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
90+
where
91+
T: BigInteger,
92+
D: Deserializer<'de>,
93+
{
94+
let bytes = super::bytes::deserialize(deserializer)?;
95+
if bytes[0] == 0 {
96+
return Err(D::Error::custom("Bigint has leading zeros."));
97+
}
98+
if bytes.len() > T::NUM_LIMBS * 8 {
99+
return Err(D::Error::custom("Value exceeds target size."));
100+
}
101+
let le_bytes = bytes.into_iter().rev().chain(repeat(0_u8));
102+
103+
let mut result = T::default();
104+
#[cfg(target_endian = "little")]
105+
let bytes = result.as_mut().as_mut_bytes();
106+
for (dst, src) in bytes.iter_mut().zip(le_bytes) {
107+
*dst = src;
108+
}
109+
Ok(result)
110+
}
111+
}
112+
113+
pub mod field {
114+
use ark_ff::{Field, PrimeField};
115+
use serde::{ser::SerializeSeq, Deserialize, Serialize};
116+
117+
use super::*;
118+
119+
struct Wrapper<F: Field>(F);
120+
121+
impl<F: Field> Serialize for Wrapper<F> {
122+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
123+
where
124+
S: Serializer,
125+
{
126+
serialize(&self.0, serializer)
127+
}
128+
}
129+
130+
impl<'de, F: Field> Deserialize<'de> for Wrapper<F> {
131+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
132+
where
133+
D: Deserializer<'de>,
134+
{
135+
deserialize(deserializer).map(Wrapper)
136+
}
137+
}
138+
139+
pub fn serialize<T, S>(obj: &T, serializer: S) -> Result<S::Ok, S::Error>
140+
where
141+
T: Field,
142+
S: Serializer,
143+
{
144+
if T::extension_degree() == 1 {
145+
// For prime fields encode the element directly
146+
let base = obj.to_base_prime_field_elements().next().unwrap();
147+
super::bigint::serialize(&base.into_bigint(), serializer)
148+
} else {
149+
// For extension fields encode a sequence of base field elements.
150+
let mut seq = serializer.serialize_seq(Some(T::extension_degree() as usize))?;
151+
for coeff in obj.to_base_prime_field_elements() {
152+
seq.serialize_element(&Wrapper(coeff))?;
153+
}
154+
seq.end()
155+
}
156+
}
157+
158+
pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
159+
where
160+
T: Field,
161+
D: Deserializer<'de>,
162+
{
163+
if T::extension_degree() == 1 {
164+
let bigint = super::bigint::deserialize(deserializer)?;
165+
let base = T::BasePrimeField::from_bigint(bigint)
166+
.ok_or_else(|| D::Error::custom("Prime field element not reduced."))?;
167+
Ok(T::from_base_prime_field(base))
168+
} else {
169+
let coeffs = <Vec<Wrapper<T::BasePrimeField>>>::deserialize(deserializer)?;
170+
let num_coeffs = coeffs.len();
171+
let coeffs = coeffs.into_iter().map(|c| c.0);
172+
T::from_base_prime_field_elems(coeffs).ok_or_else(|| {
173+
D::Error::custom(format!(
174+
"Incorrect number of elements {num_coeffs} for extension degree {}",
175+
T::extension_degree()
176+
))
177+
})
178+
}
179+
}
180+
}
181+
182+
#[cfg(test)]
183+
mod tests {
184+
use ark_ff::{BigInteger, Field, PrimeField, UniformRand};
185+
use serde::{Deserialize, Serialize};
186+
187+
use crate::{
188+
crypto::fields::{Field256, Field64, Field64_3},
189+
utils::test_serde,
40190
};
41191

42-
// Convert to object
43-
let mut reader = &*bytes;
44-
let obj = T::deserialize_compressed(&mut reader)
45-
.map_err(|e| D::Error::custom(format!("while deserializing: {e}")))?;
46-
if !reader.is_empty() {
47-
return Err(D::Error::custom("while deserializing: trailing bytes"));
192+
#[test]
193+
fn test_bigint() {
194+
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
195+
struct Wrapper<T: BigInteger>(#[serde(with = "crate::ark_serde::bigint")] T);
196+
197+
test_serde(&Wrapper(Field256::MODULUS));
198+
test_serde(&Wrapper(Field64::MODULUS));
48199
}
49200

50-
Ok(obj)
201+
#[test]
202+
fn test_field() {
203+
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
204+
struct Wrapper<T: Field>(#[serde(with = "crate::ark_serde::field")] T);
205+
206+
let mut rng = ark_std::rand::thread_rng();
207+
208+
test_serde(&Wrapper(Field256::rand(&mut rng)));
209+
test_serde(&Wrapper(Field64::rand(&mut rng)));
210+
test_serde(&Wrapper(Field64_3::rand(&mut rng)));
211+
}
51212
}

0 commit comments

Comments
 (0)