diff --git a/CHANGELOG.md b/CHANGELOG.md index 529953b5b..3b4d22f0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ ### Breaking changes +- [\#593](https://github.com/arkworks-rs/algebra/pull/593) (`ark-ec`) Change `AffineRepr::xy()` to return owned values. + ### Features ### Improvements diff --git a/README.md b/README.md index e62ca3593..a507f3517 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ This repository contains several Rust crates: * [`ark-poly`](poly): Interfaces for univariate, multivariate, and multilinear polynomials, and FFTs over finite fields * [`ark-serialize`](serialize): Efficient interfaces for serialization and point compression for finite fields and elliptic curves -In addition, the [`curves`](https://github.com/arkworks-rs/curves) repository contains concrete implementations of popular elliptic curves; see [here](https://github.com/arkworks-rs/curves/README.md) for details. +In addition, the [`curves`](https://github.com/arkworks-rs/curves) repository contains concrete implementations of popular elliptic curves; see [here](https://github.com/arkworks-rs/curves/blob/master/README.md) for details. ## Build guide diff --git a/bench-templates/src/macros/ec.rs b/bench-templates/src/macros/ec.rs index d561fcfc9..5cb7380c6 100644 --- a/bench-templates/src/macros/ec.rs +++ b/bench-templates/src/macros/ec.rs @@ -214,8 +214,10 @@ macro_rules! ec_bench { let name = format!("{}::{}", $curve_name, stringify!($Group)); let mut rng = ark_std::test_rng(); - let g = <$Group>::rand(&mut rng).into_affine(); - let v: Vec<_> = (0..SAMPLES).map(|_| g).collect(); + let v: Vec<_> = (0..SAMPLES) + .map(|_| <$Group>::rand(&mut rng)) + .collect(); + let v = <$Group>::normalize_batch(&v); let scalars: Vec<_> = (0..SAMPLES) .map(|_| Scalar::rand(&mut rng).into_bigint()) .collect(); diff --git a/ec/README.md b/ec/README.md index eec8bcfd1..f80871a95 100644 --- a/ec/README.md +++ b/ec/README.md @@ -7,7 +7,7 @@

`ark-ec` defines traits and algorithms for working with different kinds of additive groups, with a focus on groups arising from elliptic curves. It further provides concrete instantiations of these traits for various elliptic curve models, including popular families of pairing-friendly curves such as the BLS12 family of curves. -Implementations of particular curves using these curve models can be found in [`arkworks-rs/curves`](https://github.com/arkworks-rs/curves/README.md). +Implementations of particular curves using these curve models can be found in [`arkworks-rs/curves`](https://github.com/arkworks-rs/curves/blob/master/README.md). ## Usage diff --git a/ec/src/hashing/curve_maps/wb/mod.rs b/ec/src/hashing/curve_maps/wb/mod.rs index 4e2644009..10ddbb0f7 100644 --- a/ec/src/hashing/curve_maps/wb/mod.rs +++ b/ec/src/hashing/curve_maps/wb/mod.rs @@ -53,10 +53,10 @@ where let y_num = DensePolynomial::from_coefficients_slice(self.y_map_numerator); let y_den = DensePolynomial::from_coefficients_slice(self.y_map_denominator); - let mut v: [BaseField; 2] = [x_den.evaluate(x), y_den.evaluate(x)]; + let mut v: [BaseField; 2] = [x_den.evaluate(&x), y_den.evaluate(&x)]; batch_inversion(&mut v); - let img_x = x_num.evaluate(x) * v[0]; - let img_y = (y_num.evaluate(x) * y) * v[1]; + let img_x = x_num.evaluate(&x) * v[0]; + let img_y = (y_num.evaluate(&x) * y) * v[1]; Ok(Affine::::new_unchecked(img_x, img_y)) }, None => Ok(Affine::identity()), diff --git a/ec/src/hashing/map_to_curve_hasher.rs b/ec/src/hashing/map_to_curve_hasher.rs index 59fe4bbf5..4cdfb017f 100644 --- a/ec/src/hashing/map_to_curve_hasher.rs +++ b/ec/src/hashing/map_to_curve_hasher.rs @@ -42,10 +42,10 @@ where }) } - // Produce a hash of the message, using the hash to field and map to curve - // traits. This uses the IETF hash to curve's specification for Random - // oracle encoding (hash_to_curve) defined by combining these components. - // See https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-09#section-3 + /// Produce a hash of the message, using the hash to field and map to curve + /// traits. This uses the IETF hash to curve's specification for Random + /// oracle encoding (hash_to_curve) defined by combining these components. + /// See fn hash(&self, msg: &[u8]) -> Result { // IETF spec of hash_to_curve, from hash_to_field and map_to_curve // sub-components diff --git a/ec/src/lib.rs b/ec/src/lib.rs index daf169566..af5a0eb68 100644 --- a/ec/src/lib.rs +++ b/ec/src/lib.rs @@ -205,15 +205,15 @@ pub trait AffineRepr: + MulAssign; // needed due to https://github.com/rust-lang/rust/issues/69640 /// Returns the x and y coordinates of this affine point. - fn xy(&self) -> Option<(&Self::BaseField, &Self::BaseField)>; + fn xy(&self) -> Option<(Self::BaseField, Self::BaseField)>; /// Returns the x coordinate of this affine point. - fn x(&self) -> Option<&Self::BaseField> { + fn x(&self) -> Option { self.xy().map(|(x, _)| x) } /// Returns the y coordinate of this affine point. - fn y(&self) -> Option<&Self::BaseField> { + fn y(&self) -> Option { self.xy().map(|(_, y)| y) } diff --git a/ec/src/models/bls12/g2.rs b/ec/src/models/bls12/g2.rs index 661486351..f8068cecb 100644 --- a/ec/src/models/bls12/g2.rs +++ b/ec/src/models/bls12/g2.rs @@ -20,8 +20,8 @@ pub type G2Projective

= Projective<

::G2Config>; Eq(bound = "P: Bls12Config") )] pub struct G2Prepared { - // Stores the coefficients of the line evaluations as calculated in - // https://eprint.iacr.org/2013/722.pdf + /// Stores the coefficients of the line evaluations as calculated in + /// pub ell_coeffs: Vec>, pub infinity: bool, } @@ -57,7 +57,7 @@ impl From> for G2Prepared

{ ell_coeffs: vec![], infinity: true, }; - q.xy().map_or(zero, |(&q_x, &q_y)| { + q.xy().map_or(zero, |(q_x, q_y)| { let mut ell_coeffs = vec![]; let mut r = G2HomProjective::

{ x: q_x, @@ -133,7 +133,7 @@ impl G2HomProjective

{ } fn add_in_place(&mut self, q: &G2Affine

) -> EllCoeff

{ - let (&qx, &qy) = q.xy().unwrap(); + let (qx, qy) = q.xy().unwrap(); // Formula for line function when working with // homogeneous projective coordinates. let theta = self.y - &(qy * &self.z); diff --git a/ec/src/models/bls12/mod.rs b/ec/src/models/bls12/mod.rs index ca8a66351..f5275f697 100644 --- a/ec/src/models/bls12/mod.rs +++ b/ec/src/models/bls12/mod.rs @@ -178,13 +178,13 @@ impl Bls12

{ match P::TWIST_TYPE { TwistType::M => { - c2.mul_assign_by_fp(py); - c1.mul_assign_by_fp(px); + c2.mul_assign_by_fp(&py); + c1.mul_assign_by_fp(&px); f.mul_by_014(&c0, &c1, &c2); }, TwistType::D => { - c0.mul_assign_by_fp(py); - c1.mul_assign_by_fp(px); + c0.mul_assign_by_fp(&py); + c1.mul_assign_by_fp(&px); f.mul_by_034(&c0, &c1, &c2); }, } diff --git a/ec/src/models/bn/g2.rs b/ec/src/models/bn/g2.rs index 231b74402..434624520 100644 --- a/ec/src/models/bn/g2.rs +++ b/ec/src/models/bn/g2.rs @@ -21,8 +21,8 @@ pub type G2Projective

= Projective<

::G2Config>; Eq(bound = "P: BnConfig") )] pub struct G2Prepared { - // Stores the coefficients of the line evaluations as calculated in - // https://eprint.iacr.org/2013/722.pdf + /// Stores the coefficients of the line evaluations as calculated in + /// pub ell_coeffs: Vec>, pub infinity: bool, } diff --git a/ec/src/models/bw6/g2.rs b/ec/src/models/bw6/g2.rs index 02430bead..8c826efcd 100644 --- a/ec/src/models/bw6/g2.rs +++ b/ec/src/models/bw6/g2.rs @@ -21,8 +21,8 @@ pub type G2Projective

= Projective<

::G2Config>; Eq(bound = "P: BW6Config") )] pub struct G2Prepared { - // Stores the coefficients of the line evaluations as calculated in - // https://eprint.iacr.org/2013/722.pdf + /// Stores the coefficients of the line evaluations as calculated in + /// pub ell_coeffs_1: Vec<(P::Fp, P::Fp, P::Fp)>, pub ell_coeffs_2: Vec<(P::Fp, P::Fp, P::Fp)>, pub infinity: bool, @@ -127,7 +127,8 @@ impl G2Prepared

{ impl G2HomProjective

{ fn double_in_place(&mut self) -> (P::Fp, P::Fp, P::Fp) { // Formula for line function when working with - // homogeneous projective coordinates, as described in https://eprint.iacr.org/2013/722.pdf. + // homogeneous projective coordinates, as described in + // . let a = self.x * &self.y; let b = self.y.square(); diff --git a/ec/src/models/short_weierstrass/affine.rs b/ec/src/models/short_weierstrass/affine.rs index b1340de3a..7633d321a 100644 --- a/ec/src/models/short_weierstrass/affine.rs +++ b/ec/src/models/short_weierstrass/affine.rs @@ -205,8 +205,8 @@ impl AffineRepr for Affine

{ type ScalarField = P::ScalarField; type Group = Projective

; - fn xy(&self) -> Option<(&Self::BaseField, &Self::BaseField)> { - (!self.infinity).then(|| (&self.x, &self.y)) + fn xy(&self) -> Option<(Self::BaseField, Self::BaseField)> { + (!self.infinity).then(|| (self.x, self.y)) } #[inline] diff --git a/ec/src/models/short_weierstrass/group.rs b/ec/src/models/short_weierstrass/group.rs index ad043f892..d94e20cba 100644 --- a/ec/src/models/short_weierstrass/group.rs +++ b/ec/src/models/short_weierstrass/group.rs @@ -330,10 +330,10 @@ impl Neg for Projective

{ } impl>> AddAssign for Projective

{ - /// Using http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl + /// Using fn add_assign(&mut self, other: T) { let other = other.borrow(); - if let Some((&other_x, &other_y)) = other.xy() { + if let Some((other_x, other_y)) = other.xy() { if self.is_zero() { self.x = other_x; self.y = other_y; @@ -564,7 +564,7 @@ impl> Mul for Projective

{ impl From> for Projective

{ #[inline] fn from(p: Affine

) -> Projective

{ - p.xy().map_or(Projective::zero(), |(&x, &y)| Self { + p.xy().map_or(Projective::zero(), |(x, y)| Self { x, y, z: P::BaseField::one(), diff --git a/ec/src/models/twisted_edwards/affine.rs b/ec/src/models/twisted_edwards/affine.rs index a6c908e31..4bf186721 100644 --- a/ec/src/models/twisted_edwards/affine.rs +++ b/ec/src/models/twisted_edwards/affine.rs @@ -166,8 +166,8 @@ impl AffineRepr for Affine

{ type ScalarField = P::ScalarField; type Group = Projective

; - fn xy(&self) -> Option<(&Self::BaseField, &Self::BaseField)> { - (!self.is_zero()).then(|| (&self.x, &self.y)) + fn xy(&self) -> Option<(Self::BaseField, Self::BaseField)> { + (!self.is_zero()).then(|| (self.x, self.y)) } fn generator() -> Self { diff --git a/ff-macros/src/lib.rs b/ff-macros/src/lib.rs index d642d1a79..9d90d5840 100644 --- a/ff-macros/src/lib.rs +++ b/ff-macros/src/lib.rs @@ -131,6 +131,47 @@ fn fetch_attr(name: &str, attrs: &[syn::Attribute]) -> Option { #[test] fn test_str_to_limbs() { + use num_bigint::Sign::*; + for i in 0..100 { + for sign in [Plus, Minus] { + let number = 1i128 << i; + let signed_number = match sign { + Minus => -number, + Plus | _ => number, + }; + for base in [2, 8, 16, 10] { + let mut string = match base { + 2 => format!("{:#b}", number), + 8 => format!("{:#o}", number), + 16 => format!("{:#x}", number), + 10 => format!("{}", number), + _ => unreachable!(), + }; + if sign == Minus { + string.insert(0, '-'); + } + let (is_positive, limbs) = utils::str_to_limbs(&format!("{}", string)); + assert_eq!( + limbs[0], + format!("{}u64", signed_number.abs() as u64), + "{signed_number}, {i}" + ); + if i > 63 { + assert_eq!( + limbs[1], + format!("{}u64", (signed_number.abs() >> 64) as u64), + "{signed_number}, {i}" + ); + } + + assert_eq!(is_positive, sign == Plus); + } + } + } + let (is_positive, limbs) = utils::str_to_limbs("0"); + assert!(is_positive); + assert_eq!(&limbs, &["0u64".to_string()]); + let (is_positive, limbs) = utils::str_to_limbs("-5"); assert!(!is_positive); assert_eq!(&limbs, &["5u64".to_string()]); diff --git a/ff-macros/src/utils.rs b/ff-macros/src/utils.rs index dde73e1a9..055fbf79f 100644 --- a/ff-macros/src/utils.rs +++ b/ff-macros/src/utils.rs @@ -1,6 +1,7 @@ use std::str::FromStr; use num_bigint::{BigInt, Sign}; +use num_traits::Num; use proc_macro::TokenStream; use syn::{Expr, Lit}; @@ -26,9 +27,25 @@ pub fn str_to_limbs(num: &str) -> (bool, Vec) { } pub fn str_to_limbs_u64(num: &str) -> (bool, Vec) { - let (sign, digits) = BigInt::from_str(num) - .expect("could not parse to bigint") - .to_radix_le(16); + let is_negative = num.starts_with('-'); + let num = if is_negative { &num[1..] } else { num }; + let number = if num.starts_with("0x") || num.starts_with("0X") { + // We are in hexadecimal + BigInt::from_str_radix(&num[2..], 16) + } else if num.starts_with("0o") || num.starts_with("0O") { + // We are in octal + BigInt::from_str_radix(&num[2..], 8) + } else if num.starts_with("0b") || num.starts_with("0B") { + // We are in binary + BigInt::from_str_radix(&num[2..], 2) + } else { + // We are in decimal + BigInt::from_str(num) + } + .expect("could not parse to bigint"); + let number = if is_negative { -number } else { number }; + let (sign, digits) = number.to_radix_le(16); + let limbs = digits .chunks(16) .map(|chunk| { diff --git a/ff/README.md b/ff/README.md index ce246ca73..389a1cc83 100644 --- a/ff/README.md +++ b/ff/README.md @@ -7,7 +7,7 @@

This crate defines Finite Field traits and useful abstraction models that follow these traits. -Implementations of concrete finite fields for some popular elliptic curves can be found in [`arkworks-rs/curves`](https://github.com/arkworks-rs/curves/README.md) under `arkworks-rs/curves//src/fields/`. +Implementations of concrete finite fields for some popular elliptic curves can be found in [`arkworks-rs/curves`](https://github.com/arkworks-rs/curves/blob/master/README.md) under `arkworks-rs/curves//src/fields/`. This crate contains two types of traits: diff --git a/ff/src/fields/field_hashers/expander/mod.rs b/ff/src/fields/field_hashers/expander/mod.rs index 4f927aa82..8b1ef0a12 100644 --- a/ff/src/fields/field_hashers/expander/mod.rs +++ b/ff/src/fields/field_hashers/expander/mod.rs @@ -77,9 +77,9 @@ impl Expander for ExpanderXmd { let dst_prime = self.construct_dst_prime(); let z_pad: Vec = vec![0; self.block_size]; - // // Represent `len_in_bytes` as a 2-byte array. - // // As per I2OSP method outlined in https://tools.ietf.org/pdf/rfc8017.pdf, - // // The program should abort if integer that we're trying to convert is too large. + // Represent `len_in_bytes` as a 2-byte array. + // As per I2OSP method outlined in https://tools.ietf.org/pdf/rfc8017.pdf, + // The program should abort if integer that we're trying to convert is too large. assert!(n < (1 << 16), "Length should be smaller than 2^16"); let lib_str: [u8; 2] = (n as u16).to_be_bytes(); diff --git a/ff/src/fields/mod.rs b/ff/src/fields/mod.rs index 4463953dd..27efa9771 100644 --- a/ff/src/fields/mod.rs +++ b/ff/src/fields/mod.rs @@ -402,7 +402,10 @@ mod no_std_tests { // TODO: only Fr & FrConfig should need to be imported. // The rest of imports are caused by cargo not resolving the deps properly // from this crate and from ark_test_curves - use ark_test_curves::{batch_inversion, batch_inversion_and_mul, bls12_381::Fr, PrimeField}; + use ark_test_curves::{ + ark_ff::{batch_inversion, batch_inversion_and_mul, PrimeField}, + bls12_381::Fr, + }; #[test] fn test_batch_inversion() { @@ -457,7 +460,7 @@ mod no_std_tests { // TODO: Eventually generate all the test vector bytes via computation with the // modulus use ark_std::{rand::Rng, string::ToString}; - use ark_test_curves::BigInteger; + use ark_test_curves::ark_ff::BigInteger; use num_bigint::BigUint; let ref_modulus = BigUint::from_bytes_be(&Fr::MODULUS.to_bytes_be()); diff --git a/ff/src/fields/models/cubic_extension.rs b/ff/src/fields/models/cubic_extension.rs index ff4203f03..c7e56fe2f 100644 --- a/ff/src/fields/models/cubic_extension.rs +++ b/ff/src/fields/models/cubic_extension.rs @@ -700,9 +700,9 @@ mod cube_ext_tests { use super::*; use ark_std::test_rng; use ark_test_curves::{ + ark_ff::Field, bls12_381::{Fq, Fq2, Fq6}, mnt6_753::Fq3, - Field, }; #[test] diff --git a/ff/src/fields/models/fp/montgomery_backend.rs b/ff/src/fields/models/fp/montgomery_backend.rs index 76344227c..3ea75b884 100644 --- a/ff/src/fields/models/fp/montgomery_backend.rs +++ b/ff/src/fields/models/fp/montgomery_backend.rs @@ -574,9 +574,9 @@ pub const fn sqrt_precomputation>( /// # Usage /// /// ```rust -/// # use ark_test_curves::{MontFp, One}; +/// # use ark_test_curves::MontFp; /// # use ark_test_curves::bls12_381 as ark_bls12_381; -/// # use ark_std::str::FromStr; +/// # use ark_std::{One, str::FromStr}; /// use ark_bls12_381::Fq; /// const ONE: Fq = MontFp!("1"); /// const NEG_ONE: Fq = MontFp!("-1"); diff --git a/ff/src/fields/models/quadratic_extension.rs b/ff/src/fields/models/quadratic_extension.rs index f62c7d353..8e7f9b825 100644 --- a/ff/src/fields/models/quadratic_extension.rs +++ b/ff/src/fields/models/quadratic_extension.rs @@ -772,8 +772,8 @@ mod quad_ext_tests { use super::*; use ark_std::test_rng; use ark_test_curves::{ + ark_ff::Field, bls12_381::{Fq, Fq2}, - Field, }; #[test] diff --git a/ff/src/lib.rs b/ff/src/lib.rs index 5a1b71096..fce601ab8 100644 --- a/ff/src/lib.rs +++ b/ff/src/lib.rs @@ -18,7 +18,10 @@ extern crate derivative; #[macro_use] pub mod biginteger; -pub use self::biginteger::*; +pub use biginteger::{ + signed_mod_reduction, BigInt, BigInteger, BigInteger128, BigInteger256, BigInteger320, + BigInteger384, BigInteger448, BigInteger64, BigInteger768, BigInteger832, +}; #[macro_use] pub mod fields; diff --git a/poly/src/polynomial/univariate/dense.rs b/poly/src/polynomial/univariate/dense.rs index d2b3f3606..345b790b3 100644 --- a/poly/src/polynomial/univariate/dense.rs +++ b/poly/src/polynomial/univariate/dense.rs @@ -353,8 +353,8 @@ impl<'a, F: Field> AddAssign<&'a DensePolynomial> for DensePolynomial { .for_each(|(a, b)| { *a += b; }); - self.truncate_leading_zeros(); } + self.truncate_leading_zeros(); } } @@ -584,7 +584,7 @@ impl<'a, 'b, F: FftField> Mul<&'a DensePolynomial> for &'b DensePolynomial if self.is_zero() || other.is_zero() { DensePolynomial::zero() } else { - let domain = GeneralEvaluationDomain::new(self.coeffs.len() + other.coeffs.len()) + let domain = GeneralEvaluationDomain::new(self.coeffs.len() + other.coeffs.len() - 1) .expect("field is not smooth enough to construct domain"); let mut self_evals = self.evaluate_over_domain_by_ref(domain); let other_evals = other.evaluate_over_domain_by_ref(domain); diff --git a/serialize/README.md b/serialize/README.md index b95e6003c..d38517240 100644 --- a/serialize/README.md +++ b/serialize/README.md @@ -14,13 +14,13 @@ Most types in `arkworks-rs` implement these traits. To use `ark-serialize`, add the following to your `Cargo.toml`: ```toml -ark_serialize = "0.4" +ark-serialize = "0.4" ``` If you additionally want to derive implementations of the `CanonicalSerialize` and `CanonicalDeserialize` traits for your own types, you can enable the `derive` feature: ```toml -ark_serialize = { version = "0.4", features = ["derive"] } +ark-serialize = { version = "0.4", features = ["derive"] } ``` ### Examples diff --git a/test-curves/src/lib.rs b/test-curves/src/lib.rs index 388864139..4e9a30200 100644 --- a/test-curves/src/lib.rs +++ b/test-curves/src/lib.rs @@ -1,9 +1,9 @@ #![no_std] -extern crate ark_ff; -pub use ark_ff::*; +pub use ark_ff; +pub use ark_ff::{fields::models::*, FftField, Field, LegendreSymbol, MontFp, PrimeField}; -extern crate ark_ec; +pub use ark_ec; pub use ark_ec::*; #[cfg(any(feature = "bls12_381_scalar_field", feature = "bls12_381_curve"))] diff --git a/test-templates/src/groups.rs b/test-templates/src/groups.rs index b223443d2..04630a1f3 100644 --- a/test-templates/src/groups.rs +++ b/test-templates/src/groups.rs @@ -122,6 +122,8 @@ macro_rules! __test_group { let mut rng = ark_std::test_rng(); + // Test that serializing and deserializing random elements + // works. for _ in 0..ITERATIONS { let a = <$group>::rand(&mut rng); { @@ -133,29 +135,37 @@ macro_rules! __test_group { let b = <$group>::deserialize_with_mode(&mut cursor, compress, validate).unwrap(); assert_eq!(a, b); } + } - { - let a = <$group>::zero(); - let mut serialized = vec![0; buf_size]; - let mut cursor = Cursor::new(&mut serialized[..]); - a.serialize_with_mode(&mut cursor, compress).unwrap(); - let mut cursor = Cursor::new(&serialized[..]); - let b = <$group>::deserialize_with_mode(&mut cursor, compress, validate).unwrap(); - assert_eq!(a, b); - } + // Test that serializing and deserializing the identity element + // works. + { + let a = <$group>::zero(); + let mut serialized = vec![0; buf_size]; + let mut cursor = Cursor::new(&mut serialized[..]); + a.serialize_with_mode(&mut cursor, compress).unwrap(); + let mut cursor = Cursor::new(&serialized[..]); + let b = <$group>::deserialize_with_mode(&mut cursor, compress, validate).unwrap(); + assert_eq!(a, b); + } - { - let a = <$group>::zero(); - let mut serialized = vec![0; buf_size - 1]; - let mut cursor = Cursor::new(&mut serialized[..]); - a.serialize_with_mode(&mut cursor, compress).unwrap_err(); - } + // Test that serializing the identity point into a buffer that + // is not big enough will yield an error. + { + let a = <$group>::zero(); + let mut serialized = vec![0; buf_size - 1]; + let mut cursor = Cursor::new(&mut serialized[..]); + a.serialize_with_mode(&mut cursor, compress).unwrap_err(); + } - { - let serialized = vec![0; buf_size - 1]; - let mut cursor = Cursor::new(&serialized[..]); - <$group>::deserialize_with_mode(&mut cursor, compress, validate).unwrap_err(); - } + // Test that deserializing from a buffer that is not big enough + // will yield and error. + // This test does not explicitly check that the error is due to + // a buffer that is not big enough. + { + let serialized = vec![0; buf_size - 1]; + let mut cursor = Cursor::new(&serialized[..]); + <$group>::deserialize_with_mode(&mut cursor, compress, validate).unwrap_err(); } } }