Skip to content
Merged
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
9 changes: 9 additions & 0 deletions .github/workflows/dusk_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,12 @@ jobs:
uses: dusk-network/.github/.github/workflows/run-tests.yml@main
with:
test_flags: --no-default-features

compiles_to_wasm_with_serde:
name: Compiles to wasm with serde enabled
runs-on: core
steps:
- uses: actions/checkout@v4
- uses: dsherret/rust-toolchain-file@v1
- run: rustup target add wasm32-unknown-unknown
- run: cargo b --release --no-default-features --features serde --target wasm32-unknown-unknown
11 changes: 6 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,12 @@ default-features = false

[dependencies.serde]
version = "1.0"
optional = true

[dependencies.serde_json]
version = "1.0"
default-features = false
optional = true

[dependencies.hex]
version = "0.4"
default-features = false
optional = true
# End Dusk dependendencies

Expand All @@ -96,12 +94,15 @@ version = "0.9"
[dev-dependencies.rand]
version = "0.8"

[dev-dependencies.serde_json]
version = "1.0"

[features]
default = ["alloc", "bits"]
alloc = ["ff/alloc", "group/alloc"]
bits = ["ff/bits"]
rkyv-impl = ["bytecheck", "dusk-bls12_381/rkyv-impl", "rkyv"]
serde = ["dep:serde", "serde_json", "hex"]
serde = ["serde/alloc", "hex/alloc"]

[[bench]]
name = "fq_bench"
Expand Down
22 changes: 22 additions & 0 deletions src/dusk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,28 @@ mod fuzz {
}
}

#[cfg(all(test, feature = "serde"))]
pub mod test_utils {
use std::boxed::Box;
use std::string::String;

use serde::Serialize;

pub fn assert_canonical_json<T>(
input: &T,
expected: &str,
) -> Result<String, Box<dyn std::error::Error>>
where
T: ?Sized + Serialize,
{
let serialized = serde_json::to_string(input)?;
let input_canonical: serde_json::Value = serialized.parse()?;
let expected_canonical: serde_json::Value = expected.parse()?;
assert_eq!(input_canonical, expected_canonical);
Ok(serialized)
}
}

#[cfg(feature = "zeroize")]
#[test]
fn test_zeroize() {
Expand Down
35 changes: 28 additions & 7 deletions src/dusk/serde_support.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,24 +54,45 @@ impl<'de> Deserialize<'de> for ExtendedPoint {

#[cfg(test)]
mod tests {
use std::boxed::Box;
use std::string::String;

use group::Group;
use rand::rngs::StdRng;
use rand::SeedableRng;

use crate::{AffinePoint, ExtendedPoint};
use super::*;
use crate::{dusk::test_utils, AffinePoint, ExtendedPoint};

#[test]
fn serde_affine_point() {
fn serde_affine_point() -> Result<(), Box<dyn std::error::Error>> {
let mut rng = StdRng::seed_from_u64(0xdead);
let point = ExtendedPoint::random(&mut rng);
let point = AffinePoint::from(point);
let ser = serde_json::to_string(&point).unwrap();
let deser = serde_json::from_str(&ser).unwrap();
let ser = test_utils::assert_canonical_json(
&point,
"\"7bdf072820ef769376583c858687144b0dcaccf8319880627c82eef222f8c6cb\""
)?;
let deser = serde_json::from_str(&ser)?;
assert_eq!(point, deser);
Ok(())
}

#[test]
fn serde_extended_point() -> Result<(), Box<dyn std::error::Error>> {
let mut rng = StdRng::seed_from_u64(0xdead);
let point = ExtendedPoint::random(&mut rng);
let ser = test_utils::assert_canonical_json(
&point,
"\"7bdf072820ef769376583c858687144b0dcaccf8319880627c82eef222f8c6cb\""
)?;
let deser = serde_json::from_str(&ser)?;
assert_eq!(point, deser);
Ok(())
}

#[test]
fn serde_wrong_encoded() {
fn serde_affine_point_wrong_encoded() {
let wrong_encoded = "wrong-encoded";

let affine_point: Result<AffinePoint, _> =
Expand All @@ -80,7 +101,7 @@ mod tests {
}

#[test]
fn serde_too_long_encoded() {
fn serde_affine_point_too_long_encoded() {
let length_33_enc = "\"e4ab9de40283a85d6ea0cd0120500697d8b01c71b7b4b520292252d20937000631\"";

let affine_point: Result<AffinePoint, _> =
Expand All @@ -89,7 +110,7 @@ mod tests {
}

#[test]
fn serde_too_short_encoded() {
fn serde_affine_point_too_short_encoded() {
let length_31_enc = "\"1751c37a1dca7aa4c048fcc6177194243edc3637bae042e167e4285945e046\"";

let affine_point: Result<AffinePoint, _> =
Expand Down
66 changes: 42 additions & 24 deletions src/fr/dusk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -409,32 +409,50 @@ fn test_zeroize() {
assert_eq!(scalar, Fr::zero());
}

#[cfg(feature = "serde")]
#[test]
fn serde_fr() {
#[cfg(all(test, feature = "serde"))]
mod tests {
use std::boxed::Box;

use ff::Field;
use rand::rngs::StdRng;
use rand::SeedableRng;

let mut rng = StdRng::seed_from_u64(0xdead);
let fr = Fr::random(&mut rng);
let ser = serde_json::to_string(&fr).unwrap();
let deser = serde_json::from_str(&ser).unwrap();
assert_eq!(fr, deser);

// Should error when the encoding is wrong
let wrong_encoded = "wrong-encoded";
let fr: Result<Fr, _> = serde_json::from_str(&wrong_encoded);
assert!(fr.is_err());

// Should error when the input is too long
let length_33_enc = "\"e4ab9de40283a85d6ea0cd0120500697d8b01c71b7b4b520292252d20937000631\"";
let fr: Result<Fr, _> = serde_json::from_str(&length_33_enc);
assert!(fr.is_err());

// Should error when the input is too short
let length_31_enc =
"\"1751c37a1dca7aa4c048fcc6177194243edc3637bae042e167e4285945e046\"";
let fr: Result<Fr, _> = serde_json::from_str(&length_31_enc);
assert!(fr.is_err());
use super::*;
use crate::dusk::test_utils;

#[test]
fn serde_fr() -> Result<(), Box<dyn std::error::Error>> {
let mut rng = StdRng::seed_from_u64(0xdead);
let fr = Fr::random(&mut rng);
let ser = test_utils::assert_canonical_json(
&fr,
"\"052385ff7468e23e6cc710b15579e0e7a7181b6cccc658a04d5c85682ee0f405\""
)?;
let deser = serde_json::from_str(&ser).unwrap();
assert_eq!(fr, deser);

Ok(())
}

#[test]
fn serde_fr_wrong_encoded() {
let wrong_encoded = "\"wrong-encoded\"";
let fr: Result<Fr, _> = serde_json::from_str(&wrong_encoded);
assert!(fr.is_err());
}

#[test]
fn serde_fr_too_long() {
let length_33_enc = "\"e4ab9de40283a85d6ea0cd0120500697d8b01c71b7b4b520292252d20937000631\"";
let fr: Result<Fr, _> = serde_json::from_str(&length_33_enc);
assert!(fr.is_err());
}

#[test]
fn serde_fr_too_short() {
let length_31_enc =
"\"1751c37a1dca7aa4c048fcc6177194243edc3637bae042e167e4285945e046\"";
let fr: Result<Fr, _> = serde_json::from_str(&length_31_enc);
assert!(fr.is_err());
}
}