@@ -1149,6 +1149,107 @@ int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y )
11491149 return ( 0 );
11501150}
11511151
1152+ /** Decide if an integer is less than the other, without branches.
1153+ *
1154+ * \param x First integer.
1155+ * \param y Second integer.
1156+ *
1157+ * \return 1 if \p x is less than \p y, 0 otherwise
1158+ */
1159+ static unsigned ct_lt_mpi_uint ( const mbedtls_mpi_uint x ,
1160+ const mbedtls_mpi_uint y )
1161+ {
1162+ mbedtls_mpi_uint ret ;
1163+ mbedtls_mpi_uint cond ;
1164+
1165+ /*
1166+ * Check if the most significant bits (MSB) of the operands are different.
1167+ */
1168+ cond = ( x ^ y );
1169+ /*
1170+ * If the MSB are the same then the difference x-y will be negative (and
1171+ * have its MSB set to 1 during conversion to unsigned) if and only if x<y.
1172+ */
1173+ ret = ( x - y ) & ~cond ;
1174+ /*
1175+ * If the MSB are different, then the operand with the MSB of 1 is the
1176+ * bigger. (That is if y has MSB of 1, then x<y is true and it is false if
1177+ * the MSB of y is 0.)
1178+ */
1179+ ret |= y & cond ;
1180+
1181+
1182+ ret = ret >> ( biL - 1 );
1183+
1184+ return (unsigned ) ret ;
1185+ }
1186+
1187+ /*
1188+ * Compare signed values in constant time
1189+ */
1190+ int mbedtls_mpi_lt_mpi_ct ( const mbedtls_mpi * X , const mbedtls_mpi * Y ,
1191+ unsigned * ret )
1192+ {
1193+ size_t i ;
1194+ /* The value of any of these variables is either 0 or 1 at all times. */
1195+ unsigned cond , done , X_is_negative , Y_is_negative ;
1196+
1197+ MPI_VALIDATE_RET ( X != NULL );
1198+ MPI_VALIDATE_RET ( Y != NULL );
1199+ MPI_VALIDATE_RET ( ret != NULL );
1200+
1201+ if ( X -> n != Y -> n )
1202+ return MBEDTLS_ERR_MPI_BAD_INPUT_DATA ;
1203+
1204+ /*
1205+ * Set sign_N to 1 if N >= 0, 0 if N < 0.
1206+ * We know that N->s == 1 if N >= 0 and N->s == -1 if N < 0.
1207+ */
1208+ X_is_negative = ( X -> s & 2 ) >> 1 ;
1209+ Y_is_negative = ( Y -> s & 2 ) >> 1 ;
1210+
1211+ /*
1212+ * If the signs are different, then the positive operand is the bigger.
1213+ * That is if X is negative (X_is_negative == 1), then X < Y is true and it
1214+ * is false if X is positive (X_is_negative == 0).
1215+ */
1216+ cond = ( X_is_negative ^ Y_is_negative );
1217+ * ret = cond & X_is_negative ;
1218+
1219+ /*
1220+ * This is a constant-time function. We might have the result, but we still
1221+ * need to go through the loop. Record if we have the result already.
1222+ */
1223+ done = cond ;
1224+
1225+ for ( i = X -> n ; i > 0 ; i -- )
1226+ {
1227+ /*
1228+ * If Y->p[i - 1] < X->p[i - 1] then X < Y is true if and only if both
1229+ * X and Y are negative.
1230+ *
1231+ * Again even if we can make a decision, we just mark the result and
1232+ * the fact that we are done and continue looping.
1233+ */
1234+ cond = ct_lt_mpi_uint ( Y -> p [i - 1 ], X -> p [i - 1 ] );
1235+ * ret |= cond & ( 1 - done ) & X_is_negative ;
1236+ done |= cond ;
1237+
1238+ /*
1239+ * If X->p[i - 1] < Y->p[i - 1] then X < Y is true if and only if both
1240+ * X and Y are positive.
1241+ *
1242+ * Again even if we can make a decision, we just mark the result and
1243+ * the fact that we are done and continue looping.
1244+ */
1245+ cond = ct_lt_mpi_uint ( X -> p [i - 1 ], Y -> p [i - 1 ] );
1246+ * ret |= cond & ( 1 - done ) & ( 1 - X_is_negative );
1247+ done |= cond ;
1248+ }
1249+
1250+ return ( 0 );
1251+ }
1252+
11521253/*
11531254 * Compare signed values
11541255 */
0 commit comments