Skip to content

Commit 4dce0c6

Browse files
implement num_traits and some some primitive conversions
1 parent de462e5 commit 4dce0c6

File tree

3 files changed

+30
-11
lines changed

3 files changed

+30
-11
lines changed

crates/starknet-types-core/src/qm31/mod.rs

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
mod num_traits_impl;
12
mod primitive_conversions;
2-
mod qm31_num_traits_impl;
33

44
use core::fmt;
55

@@ -39,7 +39,7 @@ impl fmt::Display for QM31Error {
3939
}
4040

4141
/// Definition of a Quad M31 in its reduced form. The internal representation
42-
/// is composed by the coordinates of the QM31, following a little endian ordering.
42+
/// is composed by the coordinates of the QM31, following a big endian ordering.
4343
#[repr(transparent)]
4444
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
4545
pub struct QM31([u64; 4]);
@@ -68,26 +68,26 @@ impl QM31 {
6868
/// Packs the [QM31] coordinates into a Felt.
6969
fn pack_into_felt(&self) -> Felt {
7070
let mut felt_bytes = [0; 32];
71-
let bytes = self.to_le_bytes();
71+
let bytes = self.to_bytes_le();
7272

7373
felt_bytes[0..18].copy_from_slice(&bytes);
7474

7575
Felt::from_bytes_le(&felt_bytes)
7676
}
7777

7878
fn to_biguint(&self) -> BigUint {
79-
let bytes = self.to_le_bytes();
80-
81-
BigUint::from_bytes_le(&bytes)
79+
dbg!(self);
80+
let bytes = self.to_bytes_be();
81+
BigUint::from_bytes_be(&bytes)
8282
}
8383

8484
fn to_bigint(&self) -> BigInt {
8585
self.to_biguint().into()
8686
}
8787

8888
/// Convert `self`'s inner into an array of bytes,
89-
/// following the little endian ordering.
90-
pub fn to_le_bytes(&self) -> [u8; 18] {
89+
/// following the big endian ordering.
90+
pub fn to_bytes_le(&self) -> [u8; 18] {
9191
let coordinates = self.inner();
9292

9393
let mut result_bytes = [0u8; 18];
@@ -99,6 +99,22 @@ impl QM31 {
9999
result_bytes
100100
}
101101

102+
/// Convert `self`'s inner into an array of bytes,
103+
/// following the big endian ordering.
104+
pub fn to_bytes_be(&self) -> [u8; 18] {
105+
let coordinates = self.inner();
106+
107+
let mut result_bytes = [0u8; 18];
108+
let bytes_part1 =
109+
(((coordinates[0] as u128) << 36) + (coordinates[1] as u128)).to_be_bytes();
110+
let bytes_part2 =
111+
(((coordinates[2] as u128) << 36) + (coordinates[3] as u128)).to_be_bytes();
112+
result_bytes[0..9].copy_from_slice(&bytes_part1[7..16]);
113+
result_bytes[9..18].copy_from_slice(&bytes_part2[7..16]);
114+
115+
result_bytes
116+
}
117+
102118
/// Computes the addition of two [QM31] elements in reduced form.
103119
pub fn add(&self, rhs: &QM31) -> QM31 {
104120
let coordinates1 = self.inner();

crates/starknet-types-core/src/qm31/qm31_num_traits_impl.rs renamed to crates/starknet-types-core/src/qm31/num_traits_impl.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ mod tests {
120120
assert_eq!(qm31.to_u64().unwrap(), 10u64);
121121
let qm31 = QM31::from(u64::MAX);
122122
assert_eq!(qm31.to_u64().unwrap(), u64::MAX);
123-
123+
124124
let qm31 = QM31::from(0u128);
125125
assert_eq!(qm31.to_u128().unwrap(), 0u128);
126126
let qm31 = QM31::from(10u128);

crates/starknet-types-core/src/qm31/primitive_conversions.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,13 @@ macro_rules! try_from_qm31_to_unsigned {
5555
type Error = PrimitiveFromQM31Error;
5656

5757
fn try_from(value: QM31) -> Result<Self, Self::Error> {
58-
let bytes = value.to_le_bytes();
58+
let bytes = value.to_bytes_be();
5959

60-
let (bytes_return, bytes_check) = bytes.split_at(core::mem::size_of::<$into>());
60+
let (bytes_check, bytes_return) =
61+
bytes.split_at(18 - core::mem::size_of::<$into>());
6162

63+
// A QM31 follows a big-endian ordering. Since it can be represented with 18 bytes (144 bits), we
64+
// need to check that the first size_of::<QM31> - size_of::<$into> bytes are zero.
6265
if bytes_check.iter().all(|&b| b == 0) {
6366
Ok(<$into>::from_be_bytes(bytes_return.try_into().unwrap()))
6467
} else {

0 commit comments

Comments
 (0)