Skip to content

Commit

Permalink
p521: Improve Debug for unsaturated math (#949)
Browse files Browse the repository at this point in the history
When using p521, the limbs can be populated differently which when
deriving [`Debug`] shows up as different values for equal FieldElements,
this can lead to confusion.

See:
-
#946 (comment),
equal field elements were considered as unequal.
-
#946 (comment),
assert_eq! wasn't meaningful.

Signed-off-by: Arvind Mukund <[email protected]>
  • Loading branch information
MasterAwesome authored Nov 2, 2023
1 parent f9916b2 commit 81f6087
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 1 deletion.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions p521/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ sha2 = { version = "0.10", optional = true, default-features = false }
# optional dependencies
hex-literal = { version = "0.4", optional = true }
primeorder = { version = "0.13.1", optional = true, path = "../primeorder" }
base16ct = "0.2.0"

[dev-dependencies]
hex-literal = "0.4"
Expand Down
36 changes: 35 additions & 1 deletion p521/src/arithmetic/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,43 @@ const MODULUS_HEX: &str = "00000000000001fffffffffffffffffffffffffffffffffffffff
const MODULUS: U576 = U576::from_be_hex(MODULUS_HEX);

/// Element of the secp521r1 base field used for curve coordinates.
#[derive(Clone, Copy, Debug)]
#[derive(Clone, Copy)]
pub struct FieldElement(fiat_p521_tight_field_element);

impl core::fmt::Debug for FieldElement {
/// Formatting machinery for [`FieldElement`]
///
/// # Why
/// ```ignore
/// let fe1 = FieldElement([9, 0, 0, 0, 0, 0, 0, 0, 0]);
/// let fe2 = FieldElement([
/// 8,
/// 0,
/// 288230376151711744,
/// 288230376151711743,
/// 288230376151711743,
/// 288230376151711743,
/// 288230376151711743,
/// 288230376151711743,
/// 144115188075855871,
/// ]);
/// ```
///
/// For the above example, deriving [`core::fmt::Debug`] will result in returning 2 different strings,
/// which are in reality the same due to p521's unsaturated math, instead print the output as a hex string in
/// big-endian
///
/// This makes debugging easier.
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let mut bytes = fiat_p521_to_bytes(&self.0);
bytes.reverse();
let formatter = base16ct::HexDisplay(&bytes);
f.debug_tuple("FieldElement")
.field(&format_args!("0x{formatter:X}"))
.finish()
}
}

impl FieldElement {
/// Zero element.
pub const ZERO: Self = Self::from_u64(0);
Expand Down

0 comments on commit 81f6087

Please sign in to comment.