Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  bignum32.rs

  Sprache: Rust
 

#![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[yle='color: green'>0usize..len as usize]);
    ((&mut b_copy)[0usize..len as usize]).copy_from_slice(&b[yle='color: green'>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, &<span style='color:red'>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[='color: green'>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
}

Messung V0.5 in Prozent
C=88 H=99 G=93

¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.27Angebot  ¤

*Eine klare Vorstellung vom Zielzustand






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

letze Version des Elbe Quellennavigators


Jenseits des Üblichen ....
    

Besucher

Besucher

Statistik
#Sources=277311
#Domains=752002