Add a testbit() operationg.

This commit is contained in:
2018-12-23 21:05:27 -08:00
parent 85165c7f68
commit 70a082363a
62 changed files with 429542 additions and 311395 deletions

View File

@@ -87,6 +87,10 @@ macro_rules! signed_impls {
fn mask(&mut self, len: usize) {
self.value.mask(len);
}
fn testbit(&self, bit: usize) -> bool {
self.value.testbit(bit)
}
}
#[cfg(test)]

View File

@@ -13,6 +13,9 @@ pub trait CryptoNum {
/// Mask off the high parts of the number. In particular, it
/// zeros the bits above (len * 64).
fn mask(&mut self, len: usize);
/// Test if the given bit is zero, where bits are numbered in
/// least-significant order (0 is the LSB, etc.).
fn testbit(&self, bit: usize) -> bool;
}
macro_rules! generate_base
@@ -50,6 +53,17 @@ macro_rules! generate_base
self.value[i] = 0;
}
}
fn testbit(&self, bit: usize) -> bool {
let idx = bit / 64;
let offset = bit % 64;
println!("Testing bit {} of {:X}", bit, self);
if idx >= $size {
return false;
}
println!("{:x} & {:x} == {:x}", self.value[idx], 1u64 << offset, self.value[idx] & (1u64 << offset));
(self.value[idx] & (1u64 << offset)) != 0
}
}
#[cfg(test)]
@@ -93,23 +107,31 @@ macro_rules! generate_base_tests
};
(body $name: ident, $lname: ident) => {
let fname = build_test_path("base", stringify!($name));
run_test(fname.to_string(), 6, |case| {
run_test(fname.to_string(), 8, |case| {
let (neg0, xbytes) = case.get("x").unwrap();
let (neg1, mbytes) = case.get("m").unwrap();
let (neg2, zbytes) = case.get("z").unwrap();
let (neg3, ebytes) = case.get("e").unwrap();
let (neg4, obytes) = case.get("o").unwrap();
let (neg5, rbytes) = case.get("r").unwrap();
assert!(!neg0 && !neg1 && !neg2 && !neg3 && !neg4 && !neg5);
let (neg6, bbytes) = case.get("b").unwrap();
let (neg7, tbytes) = case.get("t").unwrap();
assert!(!neg0&&!neg1&&!neg2&&!neg3&&!neg4&&!neg5&&!neg6&&!neg7);
let mut x = $name::from_bytes(xbytes);
println!("---------");
println!("x: {:x}", x);
let m = $name::from_bytes(mbytes);
let z = 1 == zbytes[0];
let e = 1 == ebytes[0];
let o = 1 == obytes[0];
let r = $name::from_bytes(rbytes);
assert_eq!(x.is_zero(), z);
assert_eq!(x.is_even(), e);
assert_eq!(x.is_odd(), o);
let b = usize::from($name::from_bytes(bbytes));
println!("b: {:x}", b);
let t = 1 == tbytes[0];
assert_eq!(x.is_zero(), z);
assert_eq!(x.is_even(), e);
assert_eq!(x.is_odd(), o);
assert_eq!(x.testbit(b), t);
x.mask(usize::from(&m));
assert_eq!(x, r);
});