Add missing comments from original code

This commit is contained in:
Alex Page 2023-06-21 22:12:12 -04:00
parent 063b4b5dc7
commit ede990ae44

View file

@ -71,6 +71,7 @@ static mut f: [uint64_t; 6] = [
fn residue_add(x: uint64_t, y: uint64_t) -> uint64_t { fn residue_add(x: uint64_t, y: uint64_t) -> uint64_t {
let mut z: uint64_t = x.wrapping_add(y); let mut z: uint64_t = x.wrapping_add(y);
//z = z - (z >= MOD ? MOD : 0);
if z >= 0x16a6b036d7f2a79_u64 { if z >= 0x16a6b036d7f2a79_u64 {
z = z.wrapping_sub(0x16a6b036d7f2a79_u64) as uint64_t as uint64_t; z = z.wrapping_sub(0x16a6b036d7f2a79_u64) as uint64_t as uint64_t;
} }
@ -79,6 +80,7 @@ fn residue_add(x: uint64_t, y: uint64_t) -> uint64_t {
fn residue_sub(x: uint64_t, y: uint64_t) -> uint64_t { fn residue_sub(x: uint64_t, y: uint64_t) -> uint64_t {
let mut z: uint64_t = x.wrapping_sub(y); let mut z: uint64_t = x.wrapping_sub(y);
//z += (x < y ? MOD : 0);
if x < y { if x < y {
z = z.wrapping_add(0x16a6b036d7f2a79_u64) as uint64_t as uint64_t; z = z.wrapping_add(0x16a6b036d7f2a79_u64) as uint64_t as uint64_t;
} }
@ -92,6 +94,8 @@ fn umul128(a: u64, b: u64, hi: &mut u64) -> u64 {
r as u64 r as u64
} }
/// `hi:lo * ceil(2**170/MOD) >> (64 + 64 + 42)`
///
/// Confirmed working /// Confirmed working
fn ui128_quotient_mod(lo: u64, hi: u64) -> u64 { fn ui128_quotient_mod(lo: u64, hi: u64) -> u64 {
let mut prod1: u64 = 0; let mut prod1: u64 = 0;
@ -113,6 +117,7 @@ fn ui128_quotient_mod(lo: u64, hi: u64) -> u64 {
} }
fn residue_mul(x: uint64_t, y: uint64_t) -> uint64_t { fn residue_mul(x: uint64_t, y: uint64_t) -> uint64_t {
// * ceil(2**170/MOD) = 0x2d351 c6d04f8b|604fa6a1 c6346a87 for (p-1)*(p-1) max
let mut hi: uint64_t = 0; 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); let quotient: uint64_t = ui128_quotient_mod(lo, hi);
@ -215,6 +220,9 @@ fn residue_sqrt(what: uint64_t) -> uint64_t {
} }
unsafe fn find_divisor_v(mut d: *mut TDivisor) -> i32 { unsafe fn find_divisor_v(mut d: *mut TDivisor) -> i32 {
// u | v^2 - f
// u = u0 + u1*x + x^2
// f%u = f0 + f1*x
let mut v1; let mut v1;
let mut f2: [uint64_t; 6] = [0; 6]; let mut f2: [uint64_t; 6] = [0; 6];
let mut i: i32 = 0_i32; let mut i: i32 = 0_i32;
@ -238,6 +246,13 @@ unsafe fn find_divisor_v(mut d: *mut TDivisor) -> i32 {
); );
f2[(j + 2_i32) as usize] = 0_i32 as uint64_t; f2[(j + 2_i32) as usize] = 0_i32 as uint64_t;
} }
// v = v0 + v1*x
// u | (v0^2 - f0) + (2*v0*v1 - f1)*x + v1^2*x^2 = u0*v1^2 + u1*v1^2*x + v1^2*x^2
// v0^2 - f0 = u0*v1^2
// 2*v0*v1 - f1 = u1*v1^2
// v0^2 = f0 + u0*v1^2 = (f1 + u1*v1^2)^2 / (2*v1)^2
// (f1^2) + 2*(f1*u1-2*f0) * v1^2 + (u1^2-4*u0) * v1^4 = 0
// v1^2 = ((2*f0-f1*u1) +- 2*sqrt(-f0*f1*u1 + f0^2 + f1^2*u0))) / (u1^2-4*u0)
let f0: uint64_t = f2[0_i32 as usize]; let f0: uint64_t = f2[0_i32 as usize];
let f1: uint64_t = f2[1_i32 as usize]; let f1: uint64_t = f2[1_i32 as usize];
let u0double: uint64_t = residue_add(u0, u0); let u0double: uint64_t = residue_add(u0, u0);
@ -289,6 +304,7 @@ unsafe fn find_divisor_v(mut d: *mut TDivisor) -> i32 {
1_i32 1_i32
} }
/// generic short slow code
unsafe fn polynomial_mul( unsafe fn polynomial_mul(
adeg: i32, adeg: i32,
a: *const uint64_t, a: *const uint64_t,
@ -389,6 +405,8 @@ unsafe fn polynomial_xgcd(
*gcd.offset(0_i32 as isize) = *a.offset(0_i32 as isize); *gcd.offset(0_i32 as isize) = *a.offset(0_i32 as isize);
*gcd.offset(1_i32 as isize) = *a.offset(1_i32 as isize); *gcd.offset(1_i32 as isize) = *a.offset(1_i32 as isize);
*gcd.offset(2_i32 as isize) = *a.offset(2_i32 as isize); *gcd.offset(2_i32 as isize) = *a.offset(2_i32 as isize);
// s*u1 + t*u2 = r
// mult1*u1 + mult2*u2 = gcd
while rdeg >= 0_i32 { while rdeg >= 0_i32 {
if rdeg > gcddeg { if rdeg > gcddeg {
let tmp = rdeg as u32; let tmp = rdeg as u32;
@ -427,6 +445,7 @@ unsafe fn polynomial_xgcd(
let delta: i32 = gcddeg - rdeg; let delta: i32 = gcddeg - rdeg;
let mult: uint64_t = let mult: uint64_t =
residue_mul(*gcd.offset(gcddeg as isize), residue_inv(r[rdeg as usize])); residue_mul(*gcd.offset(gcddeg as isize), residue_inv(r[rdeg as usize]));
// quotient = mult * x**delta
let mut i: i32 = 0_i32; let mut i: i32 = 0_i32;
while i <= rdeg { while i <= rdeg {
*gcd.offset((i + delta) as isize) = residue_sub( *gcd.offset((i + delta) as isize) = residue_sub(
@ -468,6 +487,7 @@ unsafe fn polynomial_xgcd(
} }
} }
} }
// d1 = gcd, e1 = mult1, e2 = mult2
*pgcddeg = gcddeg; *pgcddeg = gcddeg;
*pmult1deg = mult1deg; *pmult1deg = mult1deg;
*pmult2deg = mult2deg; *pmult2deg = mult2deg;
@ -502,6 +522,7 @@ unsafe fn divisor_add(src1: *const TDivisor, src2: *const TDivisor, mut dst: *mu
let mut v2: [uint64_t; 2] = [0; 2]; let mut v2: [uint64_t; 2] = [0; 2];
let u1deg: i32 = u2poly(src1, u1.as_mut_ptr(), v1.as_mut_ptr()); let u1deg: i32 = u2poly(src1, u1.as_mut_ptr(), v1.as_mut_ptr());
let u2deg: i32 = u2poly(src2, u2.as_mut_ptr(), v2.as_mut_ptr()); let u2deg: i32 = u2poly(src2, u2.as_mut_ptr(), v2.as_mut_ptr());
// extended gcd: d1 = gcd(u1, u2) = e1*u1 + e2*u2
let mut d1deg: i32 = 0; let mut d1deg: i32 = 0;
let mut e1deg: i32 = 0; let mut e1deg: i32 = 0;
let mut e2deg: i32 = 0; let mut e2deg: i32 = 0;
@ -520,6 +541,7 @@ unsafe fn divisor_add(src1: *const TDivisor, src2: *const TDivisor, mut dst: *mu
&mut e2deg, &mut e2deg,
e2.as_mut_ptr(), e2.as_mut_ptr(),
); );
// extended gcd again: d = gcd(d1, v1+v2) = c1*d1 + c2*(v1+v2)
let mut b: [uint64_t; 3] = [ let mut b: [uint64_t; 3] = [
residue_add(v1[0_i32 as usize], v2[0_i32 as usize]), residue_add(v1[0_i32 as usize], v2[0_i32 as usize]),
residue_add(v1[1_i32 as usize], v2[1_i32 as usize]), residue_add(v1[1_i32 as usize], v2[1_i32 as usize]),
@ -578,8 +600,11 @@ unsafe fn divisor_add(src1: *const TDivisor, src2: *const TDivisor, mut dst: *mu
-1_i32, -1_i32,
u.as_mut_ptr(), u.as_mut_ptr(),
); );
// u is monic
let mut v: [uint64_t; 7] = [0; 7]; let mut v: [uint64_t; 7] = [0; 7];
let mut tmp: [uint64_t; 7] = [0; 7]; let mut tmp: [uint64_t; 7] = [0; 7];
// c1*(e1*u1*v2 + e2*u2*v1) + c2*(v1*v2 + f)
// c1*(e1*u1*(v2-v1) + d1*v1) + c2*(v1*v2 + f)
v[0_i32 as usize] = residue_sub(v2[0_i32 as usize], v1[0_i32 as usize]); v[0_i32 as usize] = residue_sub(v2[0_i32 as usize], v1[0_i32 as usize]);
v[1_i32 as usize] = residue_sub(v2[1_i32 as usize], v1[1_i32 as usize]); v[1_i32 as usize] = residue_sub(v2[1_i32 as usize], v1[1_i32 as usize]);
let mut tmpdeg = polynomial_mul( let mut tmpdeg = polynomial_mul(
@ -674,6 +699,7 @@ unsafe fn divisor_add(src1: *const TDivisor, src2: *const TDivisor, mut dst: *mu
std::ptr::null_mut::<uint64_t>(), std::ptr::null_mut::<uint64_t>(),
); );
while udeg > 2_i32 { while udeg > 2_i32 {
// u' = monic((f-v^2)/u), v'=-v mod u'
tmpdeg = polynomial_mul( tmpdeg = polynomial_mul(
vdeg, vdeg,
v.as_mut_ptr() as *const uint64_t, v.as_mut_ptr() as *const uint64_t,
@ -1007,7 +1033,7 @@ unsafe fn Unmix(buffer: *mut u8, bufSize: size_t, key: *const u8, keySize: size_
} }
unsafe fn Generate(installation_id_str: *const i8, confirmation_id: *mut i8) -> i32 { unsafe fn Generate(installation_id_str: *const i8, confirmation_id: *mut i8) -> i32 {
let mut installation_id: [u8; 19] = [0; 19]; let mut installation_id: [u8; 19] = [0; 19]; // 10**45 < 256**19
let mut installation_id_len: size_t = 0_i32 as size_t; let mut installation_id_len: size_t = 0_i32 as size_t;
let mut p: *const i8 = installation_id_str; let mut p: *const i8 = installation_id_str;
let mut count: size_t = 0_i32 as size_t; let mut count: size_t = 0_i32 as size_t;
@ -1181,6 +1207,7 @@ unsafe fn Generate(installation_id_str: *const i8, confirmation_id: *mut i8) ->
}, },
}; };
if d_0.u[0_i32 as usize] as u64 == 0xffffffffffffffff_u64 { if d_0.u[0_i32 as usize] as u64 == 0xffffffffffffffff_u64 {
// we can not get the zero divisor, actually...
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.wrapping_add(2_i32 as u64) as uint64_t,
0x16a6b036d7f2a79_u64 as uint64_t, 0x16a6b036d7f2a79_u64 as uint64_t,
@ -1226,6 +1253,7 @@ unsafe fn Generate(installation_id_str: *const i8, confirmation_id: *mut i8) ->
.wrapping_add((e.c2rust_unnamed.encoded_lo < x1_0) as i32 as u64) .wrapping_add((e.c2rust_unnamed.encoded_lo < x1_0) as i32 as u64)
as uint64_t as uint64_t; as uint64_t as uint64_t;
} else { } else {
// points (-x1+x2, v(-x1+x2)) and (-x1-x2, v(-x1-x2))
let mut x1a: uint64_t = residue_sub(x1_0, x2_0); let mut x1a: uint64_t = residue_sub(x1_0, x2_0);
let y1: uint64_t = residue_sub( let y1: uint64_t = residue_sub(
d_0.v[0_i32 as usize] as uint64_t, d_0.v[0_i32 as usize] as uint64_t,