From 18c5b840efb454d59253d16e764b734bbacf7669 Mon Sep 17 00:00:00 2001 From: aniket-prajapati Date: Wed, 12 Jun 2024 14:09:02 +0530 Subject: [PATCH] updated cargo clippy fix for starknet-crypto, starknet-crypto-codegen and starknet-curve --- starknet-crypto-codegen/Cargo.toml | 3 + starknet-crypto/Cargo.toml | 3 + starknet-crypto/src/ecdsa.rs | 6 +- starknet-crypto/src/pedersen_hash.rs | 2 +- starknet-crypto/src/poseidon_hash.rs | 17 +- starknet-crypto/src/rfc6979.rs | 4 +- starknet-curve/Cargo.toml | 3 + starknet-curve/src/ec_point.rs | 297 +++++++++++++++++++++++++++ 8 files changed, 320 insertions(+), 15 deletions(-) create mode 100644 starknet-curve/src/ec_point.rs diff --git a/starknet-crypto-codegen/Cargo.toml b/starknet-crypto-codegen/Cargo.toml index e8959610..391080c7 100644 --- a/starknet-crypto-codegen/Cargo.toml +++ b/starknet-crypto-codegen/Cargo.toml @@ -19,3 +19,6 @@ proc-macro = true starknet-curve = { version = "0.5.0", path = "../starknet-curve" } syn = "2.0.55" starknet-types-core = { version = "0.1.3", default-features = false, features = ["curve"] } + +[lints] +workspace = true diff --git a/starknet-crypto/Cargo.toml b/starknet-crypto/Cargo.toml index c81cd10b..9b6eafc6 100644 --- a/starknet-crypto/Cargo.toml +++ b/starknet-crypto/Cargo.toml @@ -71,3 +71,6 @@ harness = false [[bench]] name = "rfc6979_generate_k" harness = false + +[lints] +workspace = true \ No newline at end of file diff --git a/starknet-crypto/src/ecdsa.rs b/starknet-crypto/src/ecdsa.rs index ea5c4f7c..ae15e181 100644 --- a/starknet-crypto/src/ecdsa.rs +++ b/starknet-crypto/src/ecdsa.rs @@ -45,7 +45,7 @@ impl From for Signature { #[cfg(feature = "signature-display")] impl core::fmt::Display for Signature { - fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!( f, "{}{}", @@ -57,7 +57,7 @@ impl core::fmt::Display for Signature { #[cfg(feature = "signature-display")] impl core::fmt::Display for ExtendedSignature { - fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!( f, "{}{}{:02x}", @@ -278,7 +278,7 @@ mod tests { serde_json::from_str(json_data).expect("Unable to parse the JSON"); // Iterating over each element in the JSON - for (private_key, expected_public_key) in key_map.into_iter() { + for (private_key, expected_public_key) in key_map { let private_key = if private_key.len() % 2 != 0 { format!("0{}", private_key.trim_start_matches("0x")) } else { diff --git a/starknet-crypto/src/pedersen_hash.rs b/starknet-crypto/src/pedersen_hash.rs index a5026750..02e9621f 100644 --- a/starknet-crypto/src/pedersen_hash.rs +++ b/starknet-crypto/src/pedersen_hash.rs @@ -72,7 +72,7 @@ mod tests { ), ]; - for (in1, in2, expected_hash) in test_data.into_iter() { + for (in1, in2, expected_hash) in test_data { let in1 = field_element_from_be_hex(in1); let in2 = field_element_from_be_hex(in2); let expected_hash = field_element_from_be_hex(expected_hash); diff --git a/starknet-crypto/src/poseidon_hash.rs b/starknet-crypto/src/poseidon_hash.rs index c8b15bd9..28330cac 100644 --- a/starknet-crypto/src/poseidon_hash.rs +++ b/starknet-crypto/src/poseidon_hash.rs @@ -8,7 +8,7 @@ poseidon_consts!(); /// A hasher for Starknet Poseidon hash. /// -/// Using this hasher is the same as calling [poseidon_hash_many]. +/// Using this hasher is the same as calling [`poseidon_hash_many`]. #[derive(Debug, Default)] pub struct PoseidonHasher { state: [Felt; 3], @@ -16,7 +16,7 @@ pub struct PoseidonHasher { } impl PoseidonHasher { - /// Creates a new [PoseidonHasher]. + /// Creates a new [`PoseidonHasher`]. pub fn new() -> Self { Self::default() } @@ -61,7 +61,7 @@ pub fn poseidon_hash(x: Felt, y: Felt) -> Felt { state[0] } -/// Computes the Starknet Poseidon hash of a single [Felt]. +/// Computes the Starknet Poseidon hash of a single [`Felt`]. pub fn poseidon_hash_single(x: Felt) -> Felt { let mut state = [x, Felt::ZERO, Felt::ONE]; poseidon_permute_comp(&mut state); @@ -69,7 +69,7 @@ pub fn poseidon_hash_single(x: Felt) -> Felt { state[0] } -/// Computes the Starknet Poseidon hash of an arbitrary number of [Felt]s. +/// Computes the Starknet Poseidon hash of an arbitrary number of [`Felt`]s. /// /// Using this function is the same as using [PoseidonHasher]. pub fn poseidon_hash_many(msgs: &[Felt]) -> Felt { @@ -132,11 +132,10 @@ fn round_comp(state: &mut [Felt; 3], idx: usize, full: bool) { state[2] += POSEIDON_COMP_CONSTS[idx + 2]; state[0] = state[0] * state[0] * state[0]; state[1] = state[1] * state[1] * state[1]; - state[2] = state[2] * state[2] * state[2]; } else { state[2] += POSEIDON_COMP_CONSTS[idx]; - state[2] = state[2] * state[2] * state[2]; } + state[2] = state[2] * state[2] * state[2]; mix(state); } @@ -167,7 +166,7 @@ mod tests { ), ]; - for (x, y, hash) in test_data.into_iter() { + for (x, y, hash) in test_data { assert_eq!(poseidon_hash(x, y), hash); } } @@ -191,7 +190,7 @@ mod tests { ), ]; - for (x, hash) in test_data.into_iter() { + for (x, hash) in test_data { assert_eq!(poseidon_hash_single(x), hash); } } @@ -243,7 +242,7 @@ mod tests { ), ]; - for (input, hash) in test_data.into_iter() { + for (input, hash) in test_data { // Direct function call assert_eq!(poseidon_hash_many(&input), hash); diff --git a/starknet-crypto/src/rfc6979.rs b/starknet-crypto/src/rfc6979.rs index af2897a9..cd7ea7da 100644 --- a/starknet-crypto/src/rfc6979.rs +++ b/starknet-crypto/src/rfc6979.rs @@ -104,9 +104,9 @@ mod tests { } fn test_generate_k_from_json_str(json_str: &'static str) { - let test_vectors: Vec = serde_json::from_str(json_str).unwrap(); + let test_vectors: Vec> = serde_json::from_str(json_str).unwrap(); - for test_vector in test_vectors.iter() { + for test_vector in &test_vectors { let msg_hash = field_element_from_be_hex(test_vector.msg_hash); let priv_key = field_element_from_be_hex(test_vector.priv_key); let seed = field_element_from_be_hex(test_vector.seed); diff --git a/starknet-curve/Cargo.toml b/starknet-curve/Cargo.toml index 83c291ba..7c01748b 100644 --- a/starknet-curve/Cargo.toml +++ b/starknet-curve/Cargo.toml @@ -14,3 +14,6 @@ keywords = ["ethereum", "starknet", "web3", "no_std"] [dependencies] starknet-types-core = { version = "0.1.3", default-features = false, features = ["curve"] } + +[lints] +workspace = true diff --git a/starknet-curve/src/ec_point.rs b/starknet-curve/src/ec_point.rs new file mode 100644 index 00000000..385c10a4 --- /dev/null +++ b/starknet-curve/src/ec_point.rs @@ -0,0 +1,297 @@ +#![allow(clippy::missing_const_for_fn)] +use starknet_ff::FieldElement; + +use crate::curve_params::{ALPHA, BETA}; + +use core::ops; + +/// A point on an elliptic curve over [`FieldElement`]. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub struct AffinePoint { + pub x: FieldElement, + pub y: FieldElement, + pub infinity: bool, +} + +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub struct ProjectivePoint { + pub x: FieldElement, + pub y: FieldElement, + pub z: FieldElement, + pub infinity: bool, +} + +impl AffinePoint { + pub fn from_x(x: FieldElement) -> Option { + let y_squared = x * x * x + ALPHA * x + BETA; + y_squared.sqrt().map(|y| Self { + x, + y, + infinity: false, + }) + } + + fn identity() -> Self { + Self { + x: FieldElement::ZERO, + y: FieldElement::ZERO, + infinity: true, + } + } + + pub fn double_assign(&mut self) { + if self.infinity { + return; + } + + // l = (3x^2+a)/2y with a=1 from stark curve + let lambda = { + let dividend = FieldElement::THREE * (self.x * self.x) + FieldElement::ONE; + let divisor_inv = self.y.double().invert().unwrap(); + dividend * divisor_inv + }; + + let result_x = (lambda * lambda) - self.x - self.x; + self.y = lambda * (self.x - result_x) - self.y; + self.x = result_x; + } +} + +impl From<&ProjectivePoint> for AffinePoint { + fn from(p: &ProjectivePoint) -> Self { + let zinv = p.z.invert().unwrap(); + Self { + x: p.x * zinv, + y: p.y * zinv, + infinity: false, + } + } +} + +impl ops::Add<&AffinePoint> for &AffinePoint { + type Output = AffinePoint; + + fn add(self, rhs: &AffinePoint) -> Self::Output { + let mut copy = *self; + copy += rhs; + copy + } +} + +impl ops::AddAssign<&Self> for AffinePoint { + fn add_assign(&mut self, rhs: &Self) { + if rhs.infinity { + return; + } + if self.infinity { + *self = *rhs; + return; + } + if self.x == rhs.x { + if self.y == rhs.y { + self.double_assign(); + } else { + *self = Self::identity(); + } + return; + } + + let lambda = (rhs.y - self.y) * (rhs.x - self.x).invert().unwrap(); + + let result_x = lambda * lambda - self.x - rhs.x; + + self.y = lambda * (self.x - result_x) - self.y; + self.x = result_x; + } +} + +impl ops::Neg for &AffinePoint { + type Output = AffinePoint; + + fn neg(self) -> AffinePoint { + AffinePoint { + x: self.x, + y: -self.y, + infinity: self.infinity, + } + } +} + +impl ops::Sub<&AffinePoint> for &AffinePoint { + type Output = AffinePoint; + + fn sub(self, rhs: &AffinePoint) -> Self::Output { + let mut copy = *self; + copy -= rhs; + copy + } +} + +impl ops::SubAssign<&Self> for AffinePoint { + fn sub_assign(&mut self, rhs: &Self) { + *self += &-rhs; + } +} + +impl ops::Mul<&[bool]> for &AffinePoint { + type Output = AffinePoint; + + #[allow(clippy::suspicious_arithmetic_impl)] + fn mul(self, rhs: &[bool]) -> Self::Output { + let mut product = AffinePoint::identity(); + for b in rhs.iter().rev().skip_while(|b| !*b) { + product.double_assign(); + if *b { + product += self; + } + } + + product + } +} + +impl ProjectivePoint { + pub const fn from_affine_point(p: &AffinePoint) -> Self { + Self { + x: p.x, + y: p.y, + z: FieldElement::ONE, + infinity: p.infinity, + } + } + + fn identity() -> Self { + Self { + x: FieldElement::ZERO, + y: FieldElement::ZERO, + z: FieldElement::ONE, + infinity: true, + } + } + + pub fn double_assign(&mut self) { + if self.infinity { + return; + } + + // t=3x^2+az^2 with a=1 from stark curve + let t = FieldElement::THREE * self.x * self.x + self.z * self.z; + let u = self.y.double() * self.z; + let v = u.double() * self.x * self.y; + let w = t * t - v.double(); + + let uy = u * self.y; + + let x = u * w; + let y = t * (v - w) - (uy * uy).double(); + let z = u * u * u; + + self.x = x; + self.y = y; + self.z = z; + } +} + +impl From<&AffinePoint> for ProjectivePoint { + fn from(p: &AffinePoint) -> Self { + Self::from_affine_point(p) + } +} + +impl ops::AddAssign<&AffinePoint> for ProjectivePoint { + fn add_assign(&mut self, rhs: &AffinePoint) { + if rhs.infinity { + return; + } + if self.infinity { + *self = Self::from_affine_point(rhs); + return; + } + let u0 = self.x; + let u1 = rhs.x * self.z; + let t0 = self.y; + let t1 = rhs.y * self.z; + if u0 == u1 { + if t0 != t1 { + self.infinity = true; + } else { + self.double_assign(); + } + return; + } + + let t = t0 - t1; + let u = u0 - u1; + let u2 = u * u; + + let v = self.z; + let w = t * t * v - u2 * (u0 + u1); + let u3 = u * u2; + + let x = u * w; + let y = t * (u0 * u2 - w) - t0 * u3; + let z = u3 * v; + + self.x = x; + self.y = y; + self.z = z; + } +} + +impl ops::AddAssign<&Self> for ProjectivePoint { + fn add_assign(&mut self, rhs: &Self) { + if rhs.infinity { + return; + } + if self.infinity { + *self = *rhs; + return; + } + let u0 = self.x * rhs.z; + let u1 = rhs.x * self.z; + if u0 == u1 { + if self.y == rhs.y { + self.double_assign(); + } else { + *self = Self::identity(); + } + return; + } + + let t0 = self.y * rhs.z; + let t1 = rhs.y * self.z; + let t = t0 - t1; + + let u = u0 - u1; + let u2 = u * u; + + let v = self.z * rhs.z; + let w = t * t * v - u2 * (u0 + u1); + let u3 = u * u2; + + let x = u * w; + let y = t * (u0 * u2 - w) - t0 * u3; + let z = u3 * v; + + self.x = x; + self.y = y; + self.z = z; + } +} + +impl ops::Mul<&[bool]> for &ProjectivePoint { + type Output = ProjectivePoint; + + #[allow(clippy::suspicious_arithmetic_impl)] + fn mul(self, rhs: &[bool]) -> Self::Output { + let mut product = ProjectivePoint::identity(); + for b in rhs.iter().rev().skip_while(|b| !*b) { + product.double_assign(); + if *b { + product += self; + } + } + + product + } +}