Fix up two functions with tested code

This commit is contained in:
Alex Page 2023-06-21 21:52:52 -04:00
parent 7d35fe36fe
commit 43caccc8b7

View file

@ -85,51 +85,36 @@ unsafe fn residue_sub(x: uint64_t, y: uint64_t) -> uint64_t {
z
}
unsafe fn __umul128(
multiplier: uint64_t,
multiplicand: uint64_t,
product_hi: *mut uint64_t,
) -> uint64_t {
let a: uint64_t = multiplier >> 32_i32;
let b: uint64_t = multiplier & 0xffffffff_u32 as u64;
let c: uint64_t = multiplicand >> 32_i32;
let d: uint64_t = multiplicand & 0xffffffff_u32 as u64;
let ad: uint64_t = a.wrapping_mul(d);
let bd: uint64_t = b.wrapping_mul(d);
let adbc: uint64_t = ad.wrapping_add(b.wrapping_mul(c));
let adbc_carry: uint64_t = (if adbc < ad { 1_i32 } else { 0_i32 }) as uint64_t;
let product_lo: uint64_t = bd.wrapping_add(adbc << 32_i32);
let product_lo_carry: uint64_t = (if product_lo < bd { 1_i32 } else { 0_i32 }) as uint64_t;
*product_hi = a
.wrapping_mul(c)
.wrapping_add(adbc >> 32_i32)
.wrapping_add(adbc_carry << 32_i32)
.wrapping_add(product_lo_carry);
product_lo
/// Confirmed working
fn umul128(a: u64, b: u64, hi: &mut u64) -> u64 {
let r: u128 = a as u128 * b as u128;
*hi = (r >> 64) as u64;
r as u64
}
unsafe fn ui128_quotient_mod(lo: uint64_t, hi: uint64_t) -> uint64_t {
let mut prod1: uint64_t = 0;
__umul128(lo, 0x604fa6a1c6346a87_i64 as uint64_t, &mut prod1);
let mut part1hi: uint64_t = 0;
let part1lo: uint64_t = __umul128(lo, 0x2d351c6d04f8b_i64 as uint64_t, &mut part1hi);
let mut part2hi: uint64_t = 0;
let part2lo: uint64_t = __umul128(hi, 0x604fa6a1c6346a87_i64 as uint64_t, &mut part2hi);
let mut sum1: uint64_t = part1lo.wrapping_add(part2lo);
/// Confirmed working
fn ui128_quotient_mod(lo: u64, hi: u64) -> u64 {
let mut prod1: u64 = 0;
umul128(lo, 0x604fa6a1c6346a87_i64 as u64, &mut prod1);
let mut part1hi: u64 = 0;
let part1lo: u64 = umul128(lo, 0x2d351c6d04f8b_i64 as u64, &mut part1hi);
let mut part2hi: u64 = 0;
let part2lo: u64 = umul128(hi, 0x604fa6a1c6346a87_i64 as u64, &mut part2hi);
let mut sum1: u64 = part1lo.wrapping_add(part2lo);
let mut sum1carry: u32 = (sum1 < part1lo) as i32 as u32;
sum1 = sum1.wrapping_add(prod1) as uint64_t as uint64_t;
sum1 = sum1.wrapping_add(prod1);
sum1carry = sum1carry.wrapping_add((sum1 < prod1) as i32 as u32);
let prod2: uint64_t = part1hi.wrapping_add(part2hi).wrapping_add(sum1carry as u64);
let mut prod3hi: uint64_t = 0;
let mut prod3lo: uint64_t = __umul128(hi, 0x2d351c6d04f8b_i64 as uint64_t, &mut prod3hi);
prod3lo = prod3lo.wrapping_add(prod2) as uint64_t as uint64_t;
prod3hi = prod3hi.wrapping_add((prod3lo < prod2) as i32 as u64) as uint64_t as uint64_t;
let prod2: u64 = part1hi.wrapping_add(part2hi).wrapping_add(sum1carry as u64);
let mut prod3hi: u64 = 0;
let mut prod3lo: u64 = umul128(hi, 0x2d351c6d04f8b_i64 as u64, &mut prod3hi);
prod3lo = prod3lo.wrapping_add(prod2);
prod3hi = prod3hi.wrapping_add((prod3lo < prod2) as i32 as u64);
prod3lo >> 42_i32 | prod3hi << 22_i32
}
unsafe fn residue_mul(x: uint64_t, y: uint64_t) -> uint64_t {
let mut hi: uint64_t = 0;
let lo: uint64_t = __umul128(x, y, &mut hi);
let lo: uint64_t = umul128(x, y, &mut hi);
let quotient: uint64_t = ui128_quotient_mod(lo, hi);
lo.wrapping_sub(quotient.wrapping_mul(0x16a6b036d7f2a79_u64)) as uint64_t
}
@ -1196,13 +1181,13 @@ unsafe fn Generate(installation_id_str: *const i8, confirmation_id: *mut i8) ->
},
};
if d_0.u[0_i32 as usize] as u64 == 0xffffffffffffffff_u64 {
e.c2rust_unnamed.encoded_lo = __umul128(
e.c2rust_unnamed.encoded_lo = umul128(
0x16a6b036d7f2a79_u64.wrapping_add(2_i32 as u64) as uint64_t,
0x16a6b036d7f2a79_u64 as uint64_t,
&mut e.c2rust_unnamed.encoded_hi,
);
} else if d_0.u[1_i32 as usize] as u64 == 0xffffffffffffffff_u64 {
e.c2rust_unnamed.encoded_lo = __umul128(
e.c2rust_unnamed.encoded_lo = umul128(
0x16a6b036d7f2a79_u64.wrapping_add(1_i32 as u64) as uint64_t,
d_0.u[0_i32 as usize] as uint64_t,
&mut e.c2rust_unnamed.encoded_hi,
@ -1228,7 +1213,7 @@ unsafe fn Generate(installation_id_str: *const i8, confirmation_id: *mut i8) ->
let mut x2_0: uint64_t = residue_sqrt(x2sqr);
if x2_0 == 0xffffffffffffffff_u64 {
x2_0 = residue_sqrt(residue_mul(x2sqr, residue_inv(43_i32 as uint64_t)));
e.c2rust_unnamed.encoded_lo = __umul128(
e.c2rust_unnamed.encoded_lo = umul128(
0x16a6b036d7f2a79_u64.wrapping_add(1_i32 as u64) as uint64_t,
0x16a6b036d7f2a79_u64.wrapping_add(x2_0) as uint64_t,
&mut e.c2rust_unnamed.encoded_hi,
@ -1257,7 +1242,7 @@ unsafe fn Generate(installation_id_str: *const i8, confirmation_id: *mut i8) ->
if (y1 ^ y2) & 1_i32 as u64 != 0 {
std::mem::swap(&mut x1a, &mut x2a);
}
e.c2rust_unnamed.encoded_lo = __umul128(
e.c2rust_unnamed.encoded_lo = umul128(
0x16a6b036d7f2a79_u64.wrapping_add(1_i32 as u64) as uint64_t,
x1a,
&mut e.c2rust_unnamed.encoded_hi,