You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

85 lines
2.1 KiB

use std::os::unix::thread;
use rand::{thread_rng, Rng};
fn decomposer(mut value: u64, q: u64, d: usize, logb: u64) -> Vec<u64> {
let b = 1u64 << logb;
let full_mask = b - 1u64;
let bby2 = b >> 1;
if value >= (q >> 1) {
value = !(q - value) + 1;
}
// let mut carry = 0;
// let mut out = Vec::with_capacity(d);
// for _ in 0..d {
// let k_i = carry + (value & full_mask);
// value = (value) >> logb;
// if k_i > bby2 {
// // if (k_i == bby2 && ((value & 1) == 1)) {
// // println!("AA");
// // }
// out.push(q - (b - k_i));
// carry = 1;
// } else {
// // if (k_i == bby2) {
// // println!("BB");
// // }
// out.push(k_i);
// carry = 0;
// }
// }
// return out;
let mut out = Vec::with_capacity(d);
for _ in 0..d {
let k_i = value & full_mask;
value = (value - k_i) >> logb;
if k_i > bby2 || (k_i == bby2 && ((value & 1) == 1)) {
// if (k_i == bby2 && ((value & 1) == 1)) {
// println!("AA");
// }
out.push(q - (b - k_i));
value += 1;
} else {
// if (k_i == bby2) {
// println!("BB");
// }
out.push(k_i);
}
}
return out;
}
fn recompose(limbs: &[u64], q: u64, logb: u64) -> u64 {
let mut out = 0;
limbs.iter().enumerate().for_each(|(i, l)| {
let a = 1u128 << (logb * (i as u64));
let a = ((a * (*l as u128)) % (q as u128)) as u64;
out = (out + a) % q;
});
out % q
}
fn main() {
// let mut v = Vec::with_capacity(10);
// v[0] = 1;
// println!("Hello, world!");
let mut rng = thread_rng();
let q = 36028797018820609u64;
let logb = 11;
let d = 5;
for _ in 0..100000 {
let value = rng.gen_range(0..q);
let limbs = decomposer(value, q, d, logb);
// println!("{:?}", &limbs);
let value_back = recompose(&limbs, q, logb);
assert_eq!(value, value_back)
}
}