@@ -61,8 +61,8 @@ impl QM31 {
61
61
62
62
/// Packs the [QM31] coordinates into a Felt.
63
63
///
64
- /// A QM31 is composed of 4 coordinates each of which can be represented with 36 bits, meaing
65
- /// it can be store in a Felt252. This method packs a given QM31 and stores in the first 144 bits of a Felt252.
64
+ /// A QM31 is composed of 4 coordinates each of which can be represented with 36 bits, meaning
65
+ /// it can be store in a Felt252. This method packs a given QM31 and stores it in the first 144 bits of a Felt252.
66
66
fn pack_into_felt ( & self ) -> Felt {
67
67
let coordinates = self . 0 ;
68
68
@@ -75,6 +75,34 @@ impl QM31 {
75
75
Felt :: from_bytes_le ( & result_bytes)
76
76
}
77
77
78
+ /// Unpacks the reduced coordinates stored in [Felt] and creates a [QM31].
79
+ fn unpack_from_felt ( felt : & Felt ) -> Result < QM31 , QM31Error > {
80
+ let limbs = felt. to_le_digits ( ) ;
81
+
82
+ // Check value fits in 144 bits. This check is only done here
83
+ // because we are trying to convert a Felt into a QM31. This
84
+ // Felt should represent a packed QM31 which is at most 144 bits long.
85
+ if limbs[ 3 ] != 0 || limbs[ 2 ] >= 1 << 16 {
86
+ return Err ( QM31Error :: FeltTooBig ( * felt) ) ;
87
+ }
88
+
89
+ // Check if the coordinates were reduced before.
90
+ let coordinates = [
91
+ ( limbs[ 0 ] & MASK_36 ) ,
92
+ ( ( limbs[ 0 ] >> 36 ) + ( ( limbs[ 1 ] & MASK_8 ) << 28 ) ) ,
93
+ ( ( limbs[ 1 ] >> 8 ) & MASK_36 ) ,
94
+ ( ( limbs[ 1 ] >> 44 ) + ( limbs[ 2 ] << 20 ) ) ,
95
+ ] ;
96
+
97
+ for x in coordinates. iter ( ) {
98
+ if * x >= STWO_PRIME {
99
+ return Err ( QM31Error :: UnreducedFelt ( * felt) ) ;
100
+ }
101
+ }
102
+
103
+ Ok ( QM31 ( coordinates) )
104
+ }
105
+
78
106
/// Computes the addition of two [QM31] elements in reduced form.
79
107
pub fn add ( & self , rhs : & QM31 ) -> QM31 {
80
108
let coordinates1 = self . inner ( ) ;
@@ -239,61 +267,15 @@ impl TryFrom<Felt> for QM31 {
239
267
type Error = QM31Error ;
240
268
241
269
fn try_from ( value : Felt ) -> Result < Self , Self :: Error > {
242
- let limbs = value. to_le_digits ( ) ;
243
-
244
- // Check value fits in 144 bits. This check is only done here
245
- // because we are trying to convert a Felt into a QM31. This
246
- // Felt should represent a packed QM31 which is at most 144 bits long.
247
- if limbs[ 3 ] != 0 || limbs[ 2 ] >= 1 << 16 {
248
- return Err ( QM31Error :: FeltTooBig ( value) ) ;
249
- }
250
-
251
- let coordinates = [
252
- ( limbs[ 0 ] & MASK_36 ) ,
253
- ( ( limbs[ 0 ] >> 36 ) + ( ( limbs[ 1 ] & MASK_8 ) << 28 ) ) ,
254
- ( ( limbs[ 1 ] >> 8 ) & MASK_36 ) ,
255
- ( ( limbs[ 1 ] >> 44 ) + ( limbs[ 2 ] << 20 ) ) ,
256
- ] ;
257
-
258
- // Check if the coordinates were reduced before.
259
- for x in coordinates. iter ( ) {
260
- if * x >= STWO_PRIME {
261
- return Err ( QM31Error :: UnreducedFelt ( value) ) ;
262
- }
263
- }
264
-
265
- Ok ( Self ( coordinates) )
270
+ Self :: unpack_from_felt ( & value)
266
271
}
267
272
}
268
273
269
274
impl TryFrom < & Felt > for QM31 {
270
275
type Error = QM31Error ;
271
276
272
277
fn try_from ( value : & Felt ) -> Result < Self , Self :: Error > {
273
- let limbs = value. to_le_digits ( ) ;
274
-
275
- // Check value fits in 144 bits. This check is only done here
276
- // because we are trying to convert a Felt into a QM31. This
277
- // Felt should represent a packed QM31 which is at most 144 bits long.
278
- if limbs[ 3 ] != 0 || limbs[ 2 ] >= 1 << 16 {
279
- return Err ( QM31Error :: FeltTooBig ( * value) ) ;
280
- }
281
-
282
- // Check if the coordinates were reduced before.
283
- let coordinates = [
284
- ( limbs[ 0 ] & MASK_36 ) ,
285
- ( ( limbs[ 0 ] >> 36 ) + ( ( limbs[ 1 ] & MASK_8 ) << 28 ) ) ,
286
- ( ( limbs[ 1 ] >> 8 ) & MASK_36 ) ,
287
- ( ( limbs[ 1 ] >> 44 ) + ( limbs[ 2 ] << 20 ) ) ,
288
- ] ;
289
-
290
- for x in coordinates. iter ( ) {
291
- if * x >= STWO_PRIME {
292
- return Err ( QM31Error :: UnreducedFelt ( * value) ) ;
293
- }
294
- }
295
-
296
- Ok ( Self ( coordinates) )
278
+ Self :: unpack_from_felt ( value)
297
279
}
298
280
}
299
281
0 commit comments