mirror of
https://github.com/ARMmbed/mbedtls.git
synced 2025-06-24 22:29:04 +08:00
Merge pull request #7489 from minosgalanakis/ecp/7246_xtrack_core_shift_l
[Bignum]: Introduce left shift from prototype
This commit is contained in:
commit
f0806bee66
@ -366,6 +366,41 @@ void mbedtls_mpi_core_shift_r(mbedtls_mpi_uint *X, size_t limbs,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mbedtls_mpi_core_shift_l(mbedtls_mpi_uint *X, size_t limbs,
|
||||||
|
size_t count)
|
||||||
|
{
|
||||||
|
size_t i, v0, v1;
|
||||||
|
mbedtls_mpi_uint r0 = 0, r1;
|
||||||
|
|
||||||
|
v0 = count / (biL);
|
||||||
|
v1 = count & (biL - 1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* shift by count / limb_size
|
||||||
|
*/
|
||||||
|
if (v0 > 0) {
|
||||||
|
for (i = limbs; i > v0; i--) {
|
||||||
|
X[i - 1] = X[i - v0 - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; i > 0; i--) {
|
||||||
|
X[i - 1] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* shift by count % limb_size
|
||||||
|
*/
|
||||||
|
if (v1 > 0) {
|
||||||
|
for (i = v0; i < limbs; i++) {
|
||||||
|
r1 = X[i] >> (biL - v1);
|
||||||
|
X[i] <<= v1;
|
||||||
|
X[i] |= r0;
|
||||||
|
r0 = r1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mbedtls_mpi_uint mbedtls_mpi_core_add(mbedtls_mpi_uint *X,
|
mbedtls_mpi_uint mbedtls_mpi_core_add(mbedtls_mpi_uint *X,
|
||||||
const mbedtls_mpi_uint *A,
|
const mbedtls_mpi_uint *A,
|
||||||
const mbedtls_mpi_uint *B,
|
const mbedtls_mpi_uint *B,
|
||||||
|
@ -281,7 +281,7 @@ int mbedtls_mpi_core_write_be(const mbedtls_mpi_uint *A,
|
|||||||
unsigned char *output,
|
unsigned char *output,
|
||||||
size_t output_length);
|
size_t output_length);
|
||||||
|
|
||||||
/** \brief Shift an MPI right in place by a number of bits.
|
/** \brief Shift an MPI in-place right by a number of bits.
|
||||||
*
|
*
|
||||||
* Shifting by more bits than there are bit positions
|
* Shifting by more bits than there are bit positions
|
||||||
* in \p X is valid and results in setting \p X to 0.
|
* in \p X is valid and results in setting \p X to 0.
|
||||||
@ -296,6 +296,21 @@ int mbedtls_mpi_core_write_be(const mbedtls_mpi_uint *A,
|
|||||||
void mbedtls_mpi_core_shift_r(mbedtls_mpi_uint *X, size_t limbs,
|
void mbedtls_mpi_core_shift_r(mbedtls_mpi_uint *X, size_t limbs,
|
||||||
size_t count);
|
size_t count);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Shift an MPI in-place left by a number of bits.
|
||||||
|
*
|
||||||
|
* Shifting by more bits than there are bit positions
|
||||||
|
* in \p X will produce an unspecified result.
|
||||||
|
*
|
||||||
|
* This function's execution time depends on the value
|
||||||
|
* of \p count (and of course \p limbs).
|
||||||
|
* \param[in,out] X The number to shift.
|
||||||
|
* \param limbs The number of limbs of \p X. This must be at least 1.
|
||||||
|
* \param count The number of bits to shift by.
|
||||||
|
*/
|
||||||
|
void mbedtls_mpi_core_shift_l(mbedtls_mpi_uint *X, size_t limbs,
|
||||||
|
size_t count);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Add two fixed-size large unsigned integers, returning the carry.
|
* \brief Add two fixed-size large unsigned integers, returning the carry.
|
||||||
*
|
*
|
||||||
|
@ -80,6 +80,23 @@ def hex_digits_for_limb(limbs: int, bits_in_limb: int) -> int:
|
|||||||
""" Retrun the hex digits need for a number of limbs. """
|
""" Retrun the hex digits need for a number of limbs. """
|
||||||
return 2 * (limbs * bits_in_limb // 8)
|
return 2 * (limbs * bits_in_limb // 8)
|
||||||
|
|
||||||
|
def hex_digits_max_int(val: str, bits_in_limb: int) -> int:
|
||||||
|
""" Return the first number exceeding maximum the limb space
|
||||||
|
required to store the input hex-string value. This method
|
||||||
|
weights on the input str_len rather than numerical value
|
||||||
|
and works with zero-padded inputs"""
|
||||||
|
n = ((1 << (len(val) * 4)) - 1)
|
||||||
|
l = limbs_mpi(n, bits_in_limb)
|
||||||
|
return bound_mpi_limbs(l, bits_in_limb)
|
||||||
|
|
||||||
|
def zfill_match(reference: str, target: str) -> str:
|
||||||
|
""" Zero pad target hex-string to match the limb size of
|
||||||
|
the reference input """
|
||||||
|
lt = len(target)
|
||||||
|
lr = len(reference)
|
||||||
|
target_len = lr if lt < lr else lt
|
||||||
|
return "{:x}".format(int(target, 16)).zfill(target_len)
|
||||||
|
|
||||||
class OperationCommon(test_data_generation.BaseTest):
|
class OperationCommon(test_data_generation.BaseTest):
|
||||||
"""Common features for bignum binary operations.
|
"""Common features for bignum binary operations.
|
||||||
|
|
||||||
|
@ -68,6 +68,68 @@ class BignumCoreShiftR(BignumCoreTarget, test_data_generation.BaseTest):
|
|||||||
for count in counts:
|
for count in counts:
|
||||||
yield cls(input_hex, descr, count).create_test_case()
|
yield cls(input_hex, descr, count).create_test_case()
|
||||||
|
|
||||||
|
|
||||||
|
class BignumCoreShiftL(BignumCoreTarget, bignum_common.ModOperationCommon):
|
||||||
|
"""Test cases for mbedtls_bignum_core_shift_l()."""
|
||||||
|
|
||||||
|
BIT_SHIFT_VALUES = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a',
|
||||||
|
'1f', '20', '21', '3f', '40', '41', '47', '48', '4f',
|
||||||
|
'50', '51', '58', '80', '81', '88']
|
||||||
|
DATA = ["0", "1", "40", "dee5ca1a7ef10a75", "a1055eb0bb1efa1150ff",
|
||||||
|
"002e7ab0070ad57001", "020100000000000000001011121314151617",
|
||||||
|
"1946e2958a85d8863ae21f4904fcc49478412534ed53eaf321f63f2a222"
|
||||||
|
"7a3c63acbf50b6305595f90cfa8327f6db80d986fe96080bcbb5df1bdbe"
|
||||||
|
"9b74fb8dedf2bddb3f8215b54dffd66409323bcc473e45a8fe9d08e77a51"
|
||||||
|
"1698b5dad0416305db7fcf"]
|
||||||
|
arity = 1
|
||||||
|
test_function = "mpi_core_shift_l"
|
||||||
|
test_name = "Core shift(L)"
|
||||||
|
input_style = "arch_split"
|
||||||
|
symbol = "<<"
|
||||||
|
input_values = BIT_SHIFT_VALUES
|
||||||
|
moduli = DATA
|
||||||
|
|
||||||
|
@property
|
||||||
|
def val_n_max_limbs(self) -> int:
|
||||||
|
""" Return the limb count required to store the maximum number that can
|
||||||
|
fit in a the number of digits used by val_n """
|
||||||
|
m = bignum_common.hex_digits_max_int(self.val_n, self.bits_in_limb) - 1
|
||||||
|
return bignum_common.limbs_mpi(m, self.bits_in_limb)
|
||||||
|
|
||||||
|
def arguments(self) -> List[str]:
|
||||||
|
return [bignum_common.quote_str(self.val_n),
|
||||||
|
str(self.int_a)
|
||||||
|
] + self.result()
|
||||||
|
|
||||||
|
def description(self) -> str:
|
||||||
|
""" Format the output as:
|
||||||
|
#{count} {hex input} ({input bits} {limbs capacity}) << {bit shift} """
|
||||||
|
bits = "({} bits in {} limbs)".format(self.int_n.bit_length(), self.val_n_max_limbs)
|
||||||
|
return "{} #{} {} {} {} {}".format(self.test_name,
|
||||||
|
self.count,
|
||||||
|
self.val_n,
|
||||||
|
bits,
|
||||||
|
self.symbol,
|
||||||
|
self.int_a)
|
||||||
|
|
||||||
|
def format_result(self, res: int) -> str:
|
||||||
|
# Override to match zero-pading for leading digits between the output and input.
|
||||||
|
res_str = bignum_common.zfill_match(self.val_n, "{:x}".format(res))
|
||||||
|
return bignum_common.quote_str(res_str)
|
||||||
|
|
||||||
|
def result(self) -> List[str]:
|
||||||
|
result = (self.int_n << self.int_a)
|
||||||
|
# Calculate if there is space for shifting to the left(leading zero limbs)
|
||||||
|
mx = bignum_common.hex_digits_max_int(self.val_n, self.bits_in_limb)
|
||||||
|
# If there are empty limbs ahead, adjust the bitmask accordingly
|
||||||
|
result = result & (mx - 1)
|
||||||
|
return [self.format_result(result)]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_valid(self) -> bool:
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class BignumCoreCTLookup(BignumCoreTarget, test_data_generation.BaseTest):
|
class BignumCoreCTLookup(BignumCoreTarget, test_data_generation.BaseTest):
|
||||||
"""Test cases for mbedtls_mpi_core_ct_uint_table_lookup()."""
|
"""Test cases for mbedtls_mpi_core_ct_uint_table_lookup()."""
|
||||||
test_function = "mpi_core_ct_uint_table_lookup"
|
test_function = "mpi_core_ct_uint_table_lookup"
|
||||||
|
@ -562,6 +562,26 @@ exit:
|
|||||||
}
|
}
|
||||||
/* END_CASE */
|
/* END_CASE */
|
||||||
|
|
||||||
|
/* BEGIN_CASE */
|
||||||
|
void mpi_core_shift_l(char *input, int count, char *result)
|
||||||
|
{
|
||||||
|
mbedtls_mpi_uint *X = NULL;
|
||||||
|
mbedtls_mpi_uint *Y = NULL;
|
||||||
|
size_t limbs, n;
|
||||||
|
|
||||||
|
TEST_EQUAL(0, mbedtls_test_read_mpi_core(&X, &limbs, input));
|
||||||
|
TEST_EQUAL(0, mbedtls_test_read_mpi_core(&Y, &n, result));
|
||||||
|
TEST_EQUAL(limbs, n);
|
||||||
|
|
||||||
|
mbedtls_mpi_core_shift_l(X, limbs, count);
|
||||||
|
ASSERT_COMPARE(X, limbs * ciL, Y, limbs * ciL);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
mbedtls_free(X);
|
||||||
|
mbedtls_free(Y);
|
||||||
|
}
|
||||||
|
/* END_CASE */
|
||||||
|
|
||||||
/* BEGIN_CASE */
|
/* BEGIN_CASE */
|
||||||
void mpi_core_add_and_add_if(char *input_A, char *input_B,
|
void mpi_core_add_and_add_if(char *input_A, char *input_B,
|
||||||
char *input_S, int carry)
|
char *input_S, int carry)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user