Open tarcieri opened 1 year ago
I should probably add some context that these semantics are necessarily different from your typical num-bigint
-style arbitrary precision library.
Notably in cryptographic cases we want all of the values to be the same precision, or if not that, then known/fixed precisions at every point in the program. In the case of an algorithm like RSA, that would be the number of bits of precision in the RSA modulus. This means preserving leading zero limbs in such cases, so that we don't wind up with value-dependent timing variability with respect to the number of limbs.
Automatic widening when instantiating BoxedMontyForm
should also be considered here. BoxedMontyForm::new
currently panics if integer
and params
have different precision, but I think it makes sense to automatically widen the integer if it is less precise than the params. I am not sure if we should consider widening the params since it has more moving parts.
Arithmetic with
BoxedUint
needs to deal with values whose number of limbs don't match. This is true ofUint
as well, but there everything is nicely type safe.So far the internal
BoxedUint::chain
operation (which addition and subtraction are implemented in terms of) handles widening to the widest of the two inputs.The
wrapping_*
andchecked_*
functions use theself
/left-hand side argument as the overflow width.The
mul_wide
operation widens to as many limbs as are in the sum of the number of limbs in the operands (though should perhaps be renamed to justBoxedUint::mul
for consistency withUint::mul
, which is also a widening multiply.This seems like a reasonable enough approach, but whatever one we take should be thoroughly documented, both as an overall policy and on the individual functions.
We should also ensure it's consistent with how
Uint
performs widening, where applicable.