Revision control

Copy as Markdown

Other Tools

#![allow(non_snake_case)]
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(unused_assignments)]
#![allow(unreachable_patterns)]
use crate::prelude::*;
pub type pbn_mont_ctx_u32<'a> = &'a [super::base::bn_mont_ctx_u32];
/**
Write `a + b mod 2 ^ (32 * len)` in `res`.
This function returns the carry.
@param[in] len Number of limbs.
@param[in] a Points to `len` number of limbs, i.e. `uint32_t[len]`. Must not
partially overlap the memory locations of `b` or `res`. May have exactly equal memory
location to `b` or `res`.
@param[in] b Points to `len` number of limbs, i.e. `uint32_t[len]`. Must not
partially overlap the memory locations of `a` or `res`. May have exactly
equal memory location to `a` or `res`.
@param[out] res Points to `len` number of limbs where the carry is written, i.e. `uint32_t[len]`.
Must not partially overlap the memory locations of `a` or `b`. May have
exactly equal memory location to `a` or `b`.
*/
pub fn add(len: u32, a: &[u32], b: &[u32], res: &mut [u32]) -> u32 {
super::bignum_base::bn_add_eq_len_u32(len, a, b, res)
}
/**
Write `a - b mod 2 ^ (32 * len)` in `res`.
This functions returns the carry.
@param[in] len Number of limbs.
@param[in] a Points to `len` number of limbs, i.e. `uint32_t[len]`. Must not
partially overlap the memory locations of `b` or `res`. May have exactly
equal memory location to `b` or `res`.
@param[in] b Points to `len` number of limbs, i.e. `uint32_t[len]`. Must not
partially overlap the memory locations of `a` or `res`. May have exactly
equal memory location to `a` or `res`.
@param[out] res Points to `len` number of limbs where the carry is written, i.e. `uint32_t[len]`.
Must not partially overlap the memory locations of `a` or `b`. May have
exactly equal memory location to `a` or `b`.
*/
pub fn sub(len: u32, a: &[u32], b: &[u32], res: &mut [u32]) -> u32 {
super::bignum_base::bn_sub_eq_len_u32(len, a, b, res)
}
/**
Write `(a + b) mod n` in `res`.
@param[in] len Number of limbs.
@param[in] a Points to `len` number of limbs, i.e. `uint32_t[len]`. Must not
partially overlap the memory locations of `b` or `res`. May have exactly
equal memory location to `b` or `res`.
@param[in] b Points to `len` number of limbs, i.e. `uint32_t[len]`. Must not
partially overlap the memory locations of `a` or `res`. May have exactly
equal memory location to `a` or `res`.
@param[in] n Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be
disjoint from the memory locations of `a`, `b`, and `res`.
@param[out] res Points to `len` number of limbs where the result is written, i.e. `uint32_t[len]`.
Must not partially overlap the memory locations of `a` or `b`. May have
exactly equal memory location to `a` or `b`.
@pre Before calling this function, the caller will need to ensure that the following
preconditions are observed:
- `a < n`
- `b < n`
*/
pub fn add_mod(len: u32, n: &[u32], a: &[u32], b: &[u32], res: &mut [u32]) {
let mut a_copy: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice();
let mut b_copy: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice();
((&mut a_copy)[0usize..len as usize]).copy_from_slice(&a[0usize..len as usize]);
((&mut b_copy)[0usize..len as usize]).copy_from_slice(&b[0usize..len as usize]);
super::base::bn_add_mod_n_u32(len, n, &a_copy, &b_copy, res)
}
/**
Write `(a - b) mod n` in `res`.
@param[in] len Number of limbs.
@param[in] a Points to `len` number of limbs, i.e. `uint32_t[len]`. Must not
partially overlap the memory locations of `b` or `res`. May have exactly
equal memory location to `b` or `res`.
@param[in] b Points to `len` number of limbs, i.e. `uint32_t[len]`. Must not
partially overlap the memory locations of `a` or `res`. May have exactly
equal memory location to `a` or `res`.
@param[in] n Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be
disjoint from the memory locations of `a`, `b`, and `res`.
@param[out] res Points to `len` number of limbs where the result is written, i.e. `uint32_t[len]`.
Must not partially overlap the memory locations of `a` or `b`. May have
exactly equal memory location to `a` or `b`.
@pre Before calling this function, the caller will need to ensure that the following
preconditions are observed:
- `a < n`
- `b < n`
*/
pub fn sub_mod(len: u32, n: &[u32], a: &[u32], b: &[u32], res: &mut [u32]) {
super::base::bn_sub_mod_n_u32(len, n, a, b, res)
}
/**
Write `a * b` in `res`.
@param[in] len Number of limbs.
@param[in] a Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be
disjoint from the memory location of `b` and `res`.
@param[in] b Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be
disjoint from the memory location of `a` and `res`.
@param[out] res Points to `2*len` number of limbs where the result is written, i.e. `uint32_t[2*len]`.
Must be disjoint from the memory locations of `a` and `b`.
*/
pub fn mul(len: u32, a: &[u32], b: &[u32], res: &mut [u32]) {
let mut tmp: Box<[u32]> = vec![0u32; 4u32.wrapping_mul(len) as usize].into_boxed_slice();
super::base::bn_karatsuba_mul_uint32(len, a, b, &mut tmp, res)
}
/**
Write `a * a` in `res`.
@param[in] a Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be
disjoint from the memory location of `res`.
@param[out] res Points to `2*len` number of limbs where the result is written, i.e. `uint32_t[2*len]`.
Must be disjoint from the memory location of `a`.
*/
pub fn sqr(len: u32, a: &[u32], res: &mut [u32]) {
let mut tmp: Box<[u32]> = vec![0u32; 4u32.wrapping_mul(len) as usize].into_boxed_slice();
super::base::bn_karatsuba_sqr_uint32(len, a, &mut tmp, res)
}
#[inline]
fn bn_slow_precomp(len: u32, n: &[u32], mu: u32, r2: &[u32], a: &[u32], res: &mut [u32]) {
let mut a_mod: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice();
let mut a1: Box<[u32]> = vec![0u32; len.wrapping_add(len) as usize].into_boxed_slice();
((&mut a1)[0usize..len.wrapping_add(len) as usize])
.copy_from_slice(&a[0usize..len.wrapping_add(len) as usize]);
super::base::bn_almost_mont_reduction_u32(len, n, mu, &mut a1, &mut a_mod);
super::base::bn_to_mont_u32(len, n, mu, r2, &a_mod, res)
}
/**
Write `a mod n` in `res`.
@param[in] a Points to `2*len` number of limbs, i.e. `uint32_t[2*len]`. Must be
disjoint from the memory location of `res`.
@param[in] n Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be
disjoint from the memory location of `res`.
@param[out] res Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be
disjoint from the memory locations of `a` and `n`.
@return `false` if any precondition is violated, `true` otherwise.
@pre Before calling this function, the caller will need to ensure that the following
preconditions are observed:
- `1 < n`
- `n % 2 = 1`
*/
pub fn r#mod(len: u32, n: &[u32], a: &[u32], res: &mut [u32]) -> bool {
let mut one: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice();
((&mut one)[0usize..len as usize])
.copy_from_slice(&vec![0u32; len as usize].into_boxed_slice());
(&mut one)[0usize] = 1u32;
let bit0: u32 = n[0usize] & 1u32;
let m0: u32 = 0u32.wrapping_sub(bit0);
let mut acc: [u32; 1] = [0u32; 1usize];
for i in 0u32..len {
let beq: u32 = fstar::uint32::eq_mask((&one)[i as usize], n[i as usize]);
let blt: u32 = !fstar::uint32::gte_mask((&one)[i as usize], n[i as usize]);
(&mut acc)[0usize] = beq & (&acc)[0usize] | !beq & blt
}
let m1: u32 = (&acc)[0usize];
let is_valid_m: u32 = m0 & m1;
let nBits: u32 = 32u32.wrapping_mul(super::bignum_base::bn_get_top_index_u32(len, n));
if is_valid_m == 0xFFFFFFFFu32 {
let mut r2: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice();
super::base::bn_precomp_r2_mod_n_u32(len, nBits, n, &mut r2);
let mu: u32 = super::base::mod_inv_uint32(n[0usize]);
super::bignum32::bn_slow_precomp(len, n, mu, &r2, a, res)
} else {
(res[0usize..len as usize]).copy_from_slice(&vec![0u32; len as usize].into_boxed_slice())
};
is_valid_m == 0xFFFFFFFFu32
}
/**
Write `a ^ b mod n` in `res`.
This function is *NOT* constant-time on the argument `b`. See the
`mod_exp_consttime_*` functions for constant-time variants.
@param[in] a Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be
disjoint from the memory locations of `n` and `res`.
@param[in] n Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be
disjoint from the memory locations of `a` and `res`.
@param[in] b Points to a bignum of any size, with an upper bound of `bBits` number of
significant bits. Must be disjoint from the memory location of `res`.
@param[in] bBits An upper bound on the number of significant bits of `b`.
A tighter bound results in faster execution time. When in doubt, the number
of bits for the bignum size is always a safe default, e.g. if `b` is a 4096-bit
bignum, `bBits` should be `4096`.
@param[out] res Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be
disjoint from the memory locations of `a`, `b`, and `n`.
@return `false` if any preconditions are violated, `true` otherwise.
@pre Before calling this function, the caller will need to ensure that the following
preconditions are observed:
- `n % 2 = 1`
- `1 < n`
- `b < pow2 bBits`
- `a < n`
*/
pub fn mod_exp_vartime(
len: u32,
n: &[u32],
a: &[u32],
bBits: u32,
b: &[u32],
res: &mut [u32],
) -> bool {
let is_valid_m: u32 = super::base::bn_check_mod_exp_u32(len, n, a, bBits, b);
let nBits: u32 = 32u32.wrapping_mul(super::bignum_base::bn_get_top_index_u32(len, n));
if is_valid_m == 0xFFFFFFFFu32 {
super::base::bn_mod_exp_vartime_u32(len, nBits, n, a, bBits, b, res)
} else {
(res[0usize..len as usize]).copy_from_slice(&vec![0u32; len as usize].into_boxed_slice())
};
is_valid_m == 0xFFFFFFFFu32
}
/**
Write `a ^ b mod n` in `res`.
This function is constant-time over its argument `b`, at the cost of a slower
execution time than `mod_exp_vartime_*`.
@param[in] a Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be
disjoint from the memory locations of `n` and `res`.
@param[in] n Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be
disjoint from the memory locations of `a` and `res`.
@param[in] b Points to a bignum of any size, with an upper bound of `bBits` number of
significant bits. Must be disjoint from the memory location of `res`.
@param[in] bBits An upper bound on the number of significant bits of `b`.
A tighter bound results in faster execution time. When in doubt, the number
of bits for the bignum size is always a safe default, e.g. if `b` is a 4096-bit
bignum, `bBits` should be `4096`.
@param[out] res Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be
disjoint from the memory locations of `a`, `b`, and `n`.
@return `false` if any preconditions are violated, `true` otherwise.
@pre Before calling this function, the caller will need to ensure that the following
preconditions are observed:
- `n % 2 = 1`
- `1 < n`
- `b < pow2 bBits`
- `a < n`
*/
pub fn mod_exp_consttime(
len: u32,
n: &[u32],
a: &[u32],
bBits: u32,
b: &[u32],
res: &mut [u32],
) -> bool {
let is_valid_m: u32 = super::base::bn_check_mod_exp_u32(len, n, a, bBits, b);
let nBits: u32 = 32u32.wrapping_mul(super::bignum_base::bn_get_top_index_u32(len, n));
if is_valid_m == 0xFFFFFFFFu32 {
super::base::bn_mod_exp_consttime_u32(len, nBits, n, a, bBits, b, res)
} else {
(res[0usize..len as usize]).copy_from_slice(&vec![0u32; len as usize].into_boxed_slice())
};
is_valid_m == 0xFFFFFFFFu32
}
/**
Write `a ^ (-1) mod n` in `res`.
@param[in] a Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be
disjoint from the memory locations of `n` and `res`.
@param[in] n Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be
disjoint from the memory locations of `a` and `res`.
@param[out] res Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be
disjoint from the memory location of `a` and `n`.
@return `false` if any preconditions (except the precondition: `n` is a prime)
are violated, `true` otherwise.
@pre Before calling this function, the caller will need to ensure that the following
preconditions are observed:
- `n` is a prime
- `n % 2 = 1`
- `1 < n`
- `0 < a`
- `a < n`
*/
pub fn mod_inv_prime_vartime(len: u32, n: &[u32], a: &[u32], res: &mut [u32]) -> bool {
let mut one: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice();
((&mut one)[0usize..len as usize])
.copy_from_slice(&vec![0u32; len as usize].into_boxed_slice());
(&mut one)[0usize] = 1u32;
let bit0: u32 = n[0usize] & 1u32;
let m0: u32 = 0u32.wrapping_sub(bit0);
let mut acc: [u32; 1] = [0u32; 1usize];
for i in 0u32..len {
let beq: u32 = fstar::uint32::eq_mask((&one)[i as usize], n[i as usize]);
let blt: u32 = !fstar::uint32::gte_mask((&one)[i as usize], n[i as usize]);
(&mut acc)[0usize] = beq & (&acc)[0usize] | !beq & blt
}
let m1: u32 = (&acc)[0usize];
let m00: u32 = m0 & m1;
let bn_zero: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice();
let mut mask: [u32; 1] = [0xFFFFFFFFu32; 1usize];
for i in 0u32..len {
let uu____0: u32 = fstar::uint32::eq_mask(a[i as usize], (&bn_zero)[i as usize]);
(&mut mask)[0usize] = uu____0 & (&mask)[0usize]
}
let mask1: u32 = (&mask)[0usize];
let res1: u32 = mask1;
let m10: u32 = res1;
let mut acc0: [u32; 1] = [0u32; 1usize];
for i in 0u32..len {
let beq: u32 = fstar::uint32::eq_mask(a[i as usize], n[i as usize]);
let blt: u32 = !fstar::uint32::gte_mask(a[i as usize], n[i as usize]);
(&mut acc0)[0usize] = beq & (&acc0)[0usize] | !beq & blt
}
let m2: u32 = (&acc0)[0usize];
let is_valid_m: u32 = m00 & !m10 & m2;
let nBits: u32 = 32u32.wrapping_mul(super::bignum_base::bn_get_top_index_u32(len, n));
if is_valid_m == 0xFFFFFFFFu32 {
let mut n2: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice();
let c0: u32 = lib::inttypes_intrinsics::sub_borrow_u32(
0u32,
n[0usize],
2u32,
&mut (&mut n2)[0usize..],
);
let c: u32 = if 1u32 < len {
let a1: (&[u32], &[u32]) = n.split_at(1usize);
let res10: (&mut [u32], &mut [u32]) = n2.split_at_mut(1usize);
let mut c: [u32; 1] = [c0; 1usize];
for i in 0u32..len.wrapping_sub(1u32).wrapping_div(4u32) {
let t1: u32 = a1.1[4u32.wrapping_mul(i) as usize];
let res_i: (&mut [u32], &mut [u32]) =
res10.1.split_at_mut(4u32.wrapping_mul(i) as usize);
(&mut c)[0usize] =
lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t1, 0u32, res_i.1);
let t10: u32 = a1.1[4u32.wrapping_mul(i).wrapping_add(1u32) as usize];
let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize);
(&mut c)[0usize] =
lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t10, 0u32, res_i0.1);
let t11: u32 = a1.1[4u32.wrapping_mul(i).wrapping_add(2u32) as usize];
let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize);
(&mut c)[0usize] =
lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t11, 0u32, res_i1.1);
let t12: u32 = a1.1[4u32.wrapping_mul(i).wrapping_add(3u32) as usize];
let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize);
(&mut c)[0usize] =
lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t12, 0u32, res_i2.1)
}
for i in
len.wrapping_sub(1u32).wrapping_div(4u32).wrapping_mul(4u32)..len.wrapping_sub(1u32)
{
let t1: u32 = a1.1[i as usize];
let res_i: (&mut [u32], &mut [u32]) = res10.1.split_at_mut(i as usize);
(&mut c)[0usize] =
lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t1, 0u32, res_i.1)
}
let c1: u32 = (&c)[0usize];
c1
} else {
c0
};
lowstar::ignore::ignore::<u32>(c);
super::base::bn_mod_exp_vartime_u32(len, nBits, n, a, 32u32.wrapping_mul(len), &n2, res)
} else {
(res[0usize..len as usize]).copy_from_slice(&vec![0u32; len as usize].into_boxed_slice())
};
is_valid_m == 0xFFFFFFFFu32
}
/**
Heap-allocate and initialize a montgomery context.
@param n Points to `len` number of limbs, i.e. `uint32_t[len]`.
@return A pointer to an allocated and initialized Montgomery context is returned.
Clients will need to call `Hacl_Bignum32_mont_ctx_free` on the return value to
avoid memory leaks.
@pre Before calling this function, the caller will need to ensure that the following
preconditions are observed:
- `n % 2 = 1`
- `1 < n`
*/
pub fn mont_ctx_init(len: u32, n: &[u32]) -> Box<[super::base::bn_mont_ctx_u32]> {
let mut r2: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice();
let mut n1: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice();
let r21: &mut [u32] = &mut r2;
let n11: &mut [u32] = &mut n1;
(n11[0usize..len as usize]).copy_from_slice(&n[0usize..len as usize]);
let nBits: u32 = 32u32.wrapping_mul(super::bignum_base::bn_get_top_index_u32(len, n));
super::base::bn_precomp_r2_mod_n_u32(len, nBits, n, r21);
let mu: u32 = super::base::mod_inv_uint32(n[0usize]);
let res: super::base::bn_mont_ctx_u32 = super::base::bn_mont_ctx_u32 {
len,
n: (*n11).into(),
mu,
r2: (*r21).into(),
};
let buf: Box<[super::base::bn_mont_ctx_u32]> = vec![res].into_boxed_slice();
buf
}
/**
Write `a mod n` in `res`.
@param[in] k Points to a Montgomery context obtained from `Hacl_Bignum32_mont_ctx_init`.
@param[in] a Points to `2*len` number of limbs, i.e. `uint32_t[2*len]`. Must be
disjoint from the memory location of `res`.
@param[out] res Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be
disjoint from the memory location of `a`.
*/
pub fn mod_precomp(k: &[super::base::bn_mont_ctx_u32], a: &[u32], res: &mut [u32]) {
let len1: u32 = (k[0usize]).len;
let n: &[u32] = &(k[0usize]).n;
let mu: u32 = (k[0usize]).mu;
let r2: &[u32] = &(k[0usize]).r2;
super::bignum32::bn_slow_precomp(len1, n, mu, r2, a, res)
}
/**
Write `a ^ b mod n` in `res`.
This function is *NOT* constant-time on the argument `b`. See the
`mod_exp_consttime_*` functions for constant-time variants.
@param[in] k Points to a Montgomery context obtained from `Hacl_Bignum32_mont_ctx_init`.
@param[in] a Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be
disjoint from the memory location of `res`.
@param[in] b Points to a bignum of any size, with an upper bound of `bBits` number of
significant bits. Must be disjoint from the memory location of `res`.
@param[in] bBits An upper bound on the number of significant bits of `b`.
A tighter bound results in faster execution time. When in doubt, the number
of bits for the bignum size is always a safe default, e.g. if `b` is a 4096-bit
bignum, `bBits` should be `4096`.
@param[out] res Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be
disjoint from the memory locations of `a` and `b`.
@pre Before calling this function, the caller will need to ensure that the following
preconditions are observed:
- `b < pow2 bBits`
- `a < n`
*/
pub fn mod_exp_vartime_precomp(
k: &[super::base::bn_mont_ctx_u32],
a: &[u32],
bBits: u32,
b: &[u32],
res: &mut [u32],
) {
let len1: u32 = (k[0usize]).len;
let n: &[u32] = &(k[0usize]).n;
let mu: u32 = (k[0usize]).mu;
let r2: &[u32] = &(k[0usize]).r2;
super::base::bn_mod_exp_vartime_precomp_u32(len1, n, mu, r2, a, bBits, b, res)
}
/**
Write `a ^ b mod n` in `res`.
This function is constant-time over its argument b, at the cost of a slower
execution time than `mod_exp_vartime_*`.
@param[in] k Points to a Montgomery context obtained from `Hacl_Bignum32_mont_ctx_init`.
@param[in] a Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be
disjoint from the memory location of `res`.
@param[in] b Points to a bignum of any size, with an upper bound of `bBits` number of
significant bits. Must be disjoint from the memory location of `res`.
@param[in] bBits An upper bound on the number of significant bits of `b`.
A tighter bound results in faster execution time. When in doubt, the number
of bits for the bignum size is always a safe default, e.g. if `b` is a 4096-bit
bignum, `bBits` should be `4096`.
@param[out] res Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be
disjoint from the memory locations of `a` and `b`.
@pre Before calling this function, the caller will need to ensure that the following
preconditions are observed:
- `b < pow2 bBits`
- `a < n`
*/
pub fn mod_exp_consttime_precomp(
k: &[super::base::bn_mont_ctx_u32],
a: &[u32],
bBits: u32,
b: &[u32],
res: &mut [u32],
) {
let len1: u32 = (k[0usize]).len;
let n: &[u32] = &(k[0usize]).n;
let mu: u32 = (k[0usize]).mu;
let r2: &[u32] = &(k[0usize]).r2;
super::base::bn_mod_exp_consttime_precomp_u32(len1, n, mu, r2, a, bBits, b, res)
}
/**
Write `a ^ (-1) mod n` in `res`.
@param[in] k Points to a Montgomery context obtained through `Hacl_Bignum32_mont_ctx_init`.
@param[in] a Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be
disjoint from the memory location of `res`.
@param[out] res Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be
disjoint from the memory location of `a`.
@pre Before calling this function, the caller will need to ensure that the following
preconditions are observed:
- `n` is a prime
- `0 < a`
- `a < n`
*/
pub fn mod_inv_prime_vartime_precomp(
k: &[super::base::bn_mont_ctx_u32],
a: &[u32],
res: &mut [u32],
) {
let len1: u32 = (k[0usize]).len;
let n: &[u32] = &(k[0usize]).n;
let mu: u32 = (k[0usize]).mu;
let r2: &[u32] = &(k[0usize]).r2;
let mut n2: Box<[u32]> = vec![0u32; len1 as usize].into_boxed_slice();
let c0: u32 =
lib::inttypes_intrinsics::sub_borrow_u32(0u32, n[0usize], 2u32, &mut (&mut n2)[0usize..]);
let c: u32 = if 1u32 < len1 {
let a1: (&[u32], &[u32]) = n.split_at(1usize);
let res1: (&mut [u32], &mut [u32]) = n2.split_at_mut(1usize);
let mut c: [u32; 1] = [c0; 1usize];
for i in 0u32..len1.wrapping_sub(1u32).wrapping_div(4u32) {
let t1: u32 = a1.1[4u32.wrapping_mul(i) as usize];
let res_i: (&mut [u32], &mut [u32]) =
res1.1.split_at_mut(4u32.wrapping_mul(i) as usize);
(&mut c)[0usize] =
lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t1, 0u32, res_i.1);
let t10: u32 = a1.1[4u32.wrapping_mul(i).wrapping_add(1u32) as usize];
let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize);
(&mut c)[0usize] =
lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t10, 0u32, res_i0.1);
let t11: u32 = a1.1[4u32.wrapping_mul(i).wrapping_add(2u32) as usize];
let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize);
(&mut c)[0usize] =
lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t11, 0u32, res_i1.1);
let t12: u32 = a1.1[4u32.wrapping_mul(i).wrapping_add(3u32) as usize];
let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize);
(&mut c)[0usize] =
lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t12, 0u32, res_i2.1)
}
for i in len1
.wrapping_sub(1u32)
.wrapping_div(4u32)
.wrapping_mul(4u32)..len1.wrapping_sub(1u32)
{
let t1: u32 = a1.1[i as usize];
let res_i: (&mut [u32], &mut [u32]) = res1.1.split_at_mut(i as usize);
(&mut c)[0usize] =
lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t1, 0u32, res_i.1)
}
let c1: u32 = (&c)[0usize];
c1
} else {
c0
};
lowstar::ignore::ignore::<u32>(c);
super::base::bn_mod_exp_vartime_precomp_u32(
len1,
n,
mu,
r2,
a,
32u32.wrapping_mul(len1),
&n2,
res,
)
}
/**
Load a bid-endian bignum from memory.
@param len Size of `b` as number of bytes.
@param b Points to `len` number of bytes, i.e. `uint8_t[len]`.
@return A heap-allocated bignum of size sufficient to hold the result of
loading `b`. Otherwise, `NULL`, if either the allocation failed, or the amount
of required memory would exceed 4GB. Clients must `free(3)` any non-null return
value to avoid memory leaks.
*/
pub fn new_bn_from_bytes_be(len: u32, b: &[u8]) -> Box<[u32]> {
if len == 0u32 || len.wrapping_sub(1u32).wrapping_div(4u32).wrapping_add(1u32) > 1073741823u32 {
[].into()
} else {
let mut res: Box<[u32]> =
vec![0u32; len.wrapping_sub(1u32).wrapping_div(4u32).wrapping_add(1u32) as usize]
.into_boxed_slice();
if false {
res
} else {
let res1: &mut [u32] = &mut res;
let res2: &mut [u32] = res1;
let bnLen: u32 = len.wrapping_sub(1u32).wrapping_div(4u32).wrapping_add(1u32);
let tmpLen: u32 = 4u32.wrapping_mul(bnLen);
let mut tmp: Box<[u8]> = vec![0u8; tmpLen as usize].into_boxed_slice();
((&mut tmp)[tmpLen.wrapping_sub(len) as usize
..tmpLen.wrapping_sub(len) as usize + len as usize])
.copy_from_slice(&b[0usize..len as usize]);
for i in 0u32..bnLen {
let u: u32 = lowstar::endianness::load32_be(
&(&tmp)[bnLen.wrapping_sub(i).wrapping_sub(1u32).wrapping_mul(4u32) as usize..],
);
let x: u32 = u;
let os: (&mut [u32], &mut [u32]) = res2.split_at_mut(0usize);
os.1[i as usize] = x
}
(*res2).into()
}
}
}
/**
Load a little-endian bignum from memory.
@param len Size of `b` as number of bytes.
@param b Points to `len` number of bytes, i.e. `uint8_t[len]`.
@return A heap-allocated bignum of size sufficient to hold the result of
loading `b`. Otherwise, `NULL`, if either the allocation failed, or the amount
of required memory would exceed 4GB. Clients must `free(3)` any non-null return
value to avoid memory leaks.
*/
pub fn new_bn_from_bytes_le(len: u32, b: &[u8]) -> Box<[u32]> {
if len == 0u32 || len.wrapping_sub(1u32).wrapping_div(4u32).wrapping_add(1u32) > 1073741823u32 {
[].into()
} else {
let mut res: Box<[u32]> =
vec![0u32; len.wrapping_sub(1u32).wrapping_div(4u32).wrapping_add(1u32) as usize]
.into_boxed_slice();
if false {
res
} else {
let res1: &mut [u32] = &mut res;
let res2: &mut [u32] = res1;
let bnLen: u32 = len.wrapping_sub(1u32).wrapping_div(4u32).wrapping_add(1u32);
let tmpLen: u32 = 4u32.wrapping_mul(bnLen);
let mut tmp: Box<[u8]> = vec![0u8; tmpLen as usize].into_boxed_slice();
((&mut tmp)[0usize..len as usize]).copy_from_slice(&b[0usize..len as usize]);
for i in 0u32..len.wrapping_sub(1u32).wrapping_div(4u32).wrapping_add(1u32) {
let bj: (&[u8], &[u8]) = tmp.split_at(i.wrapping_mul(4u32) as usize);
let u: u32 = lowstar::endianness::load32_le(bj.1);
let r1: u32 = u;
let x: u32 = r1;
let os: (&mut [u32], &mut [u32]) = res2.split_at_mut(0usize);
os.1[i as usize] = x
}
(*res2).into()
}
}
}
/**
Serialize a bignum into big-endian memory.
@param[in] len Size of `b` as number of bytes.
@param[in] b Points to a bignum of `ceil(len/4)` size. Must be disjoint from
the memory location of `res`.
@param[out] res Points to `len` number of bytes, i.e. `uint8_t[len]`. Must be
disjoint from the memory location of `b`.
*/
pub fn bn_to_bytes_be(len: u32, b: &[u32], res: &mut [u8]) {
let bnLen: u32 = len.wrapping_sub(1u32).wrapping_div(4u32).wrapping_add(1u32);
let tmpLen: u32 = 4u32.wrapping_mul(bnLen);
let mut tmp: Box<[u8]> = vec![0u8; tmpLen as usize].into_boxed_slice();
for i in 0u32..bnLen {
lowstar::endianness::store32_be(
&mut (&mut tmp)[i.wrapping_mul(4u32) as usize..],
b[bnLen.wrapping_sub(i).wrapping_sub(1u32) as usize],
)
}
(res[0usize..len as usize])
.copy_from_slice(&(&(&tmp)[tmpLen.wrapping_sub(len) as usize..])[0usize..len as usize])
}
/**
Serialize a bignum into little-endian memory.
@param[in] len Size of `b` as number of bytes.
@param[in] b Points to a bignum of `ceil(len/4)` size. Must be disjoint from
the memory location of `res`.
@param[out] res Points to `len` number of bytes, i.e. `uint8_t[len]`. Must be
disjoint from the memory location of `b`.
*/
pub fn bn_to_bytes_le(len: u32, b: &[u32], res: &mut [u8]) {
let bnLen: u32 = len.wrapping_sub(1u32).wrapping_div(4u32).wrapping_add(1u32);
let tmpLen: u32 = 4u32.wrapping_mul(bnLen);
let mut tmp: Box<[u8]> = vec![0u8; tmpLen as usize].into_boxed_slice();
for i in 0u32..bnLen {
lowstar::endianness::store32_le(
&mut (&mut tmp)[i.wrapping_mul(4u32) as usize..],
b[i as usize],
)
}
(res[0usize..len as usize]).copy_from_slice(&(&(&tmp)[0usize..])[0usize..len as usize])
}
/**
Returns 2^32 - 1 if a < b, otherwise returns 0.
@param len Number of limbs.
@param a Points to `len` number of limbs, i.e. `uint32_t[len]`.
@param b Points to `len` number of limbs, i.e. `uint32_t[len]`.
@return `2^32 - 1` if `a < b`, otherwise, `0`.
*/
pub fn lt_mask(len: u32, a: &[u32], b: &[u32]) -> u32 {
let mut acc: [u32; 1] = [0u32; 1usize];
for i in 0u32..len {
let beq: u32 = fstar::uint32::eq_mask(a[i as usize], b[i as usize]);
let blt: u32 = !fstar::uint32::gte_mask(a[i as usize], b[i as usize]);
(&mut acc)[0usize] = beq & (&acc)[0usize] | !beq & blt
}
(&acc)[0usize]
}
/**
Returns 2^32 - 1 if a = b, otherwise returns 0.
@param len Number of limbs.
@param a Points to `len` number of limbs, i.e. `uint32_t[len]`.
@param b Points to `len` number of limbs, i.e. `uint32_t[len]`.
@return `2^32 - 1` if a = b, otherwise, `0`.
*/
pub fn eq_mask(len: u32, a: &[u32], b: &[u32]) -> u32 {
let mut mask: [u32; 1] = [0xFFFFFFFFu32; 1usize];
for i in 0u32..len {
let uu____0: u32 = fstar::uint32::eq_mask(a[i as usize], b[i as usize]);
(&mut mask)[0usize] = uu____0 & (&mask)[0usize]
}
let mask1: u32 = (&mask)[0usize];
mask1
}