Add from_bytes() and to_bytes() to CryptoNum, and do a basic implementation of from_bytes().
This commit is contained in:
@@ -4,6 +4,7 @@ module UnsignedBase(
|
||||
where
|
||||
|
||||
import Control.Monad(forM_)
|
||||
import Data.List(intercalate)
|
||||
import File
|
||||
import Gen
|
||||
|
||||
@@ -56,6 +57,36 @@ declareBaseStructure bitsize =
|
||||
wrapIndent ("if idx >= " ++ show entries) $
|
||||
out "return false;"
|
||||
out "(self.value[idx] & (1u64 << offset)) != 0"
|
||||
blank
|
||||
wrapIndent ("fn from_bytes(&self, bytes: &[u8]) -> Self") $
|
||||
do let bytes = bitsize `div` 8;
|
||||
forM_ [0..bytes-1] $ \ idx ->
|
||||
out ("let byte" ++ show idx ++ " = " ++
|
||||
"if " ++ show idx ++ " < bytes.len() { " ++
|
||||
"bytes[" ++ show idx ++ "] as u64 } else { 0 };")
|
||||
blank
|
||||
let byteNames = map (\ x -> "byte" ++ show x) [0..bytes-1]
|
||||
byteGroups = groupCount 8 (reverse byteNames)
|
||||
forM_ (zip byteGroups [0..bytes-1]) $ \ (byteGroup, idx) ->
|
||||
do let shiftAmts = [0,8..56]
|
||||
shifts = zipWith (\ n s -> n ++ " << " ++ show s)
|
||||
byteGroup shiftAmts
|
||||
shift0 = head shifts
|
||||
shiftL = last shifts
|
||||
middles = reverse (drop 1 (reverse (drop 1 shifts)))
|
||||
prefix = "let word" ++ show idx ++ " "
|
||||
blankPrefix = map (const ' ') prefix
|
||||
out (prefix ++ " = " ++ shift0)
|
||||
forM_ middles $ \ s -> out (blankPrefix ++ " | " ++ s)
|
||||
out (blankPrefix ++ " | " ++ shiftL ++ ";")
|
||||
blank
|
||||
wrapIndent name $
|
||||
do out ("value: [")
|
||||
let vwords = map (\ x -> "word" ++ show x) [0..top]
|
||||
linewords = groupCount 4 vwords
|
||||
vlines = map (intercalate ", ") linewords
|
||||
forM_ vlines $ \ l -> out (" " ++ l ++ ",")
|
||||
out ("]")
|
||||
blank
|
||||
implFor "PartialEq" name $
|
||||
wrapIndent "fn eq(&self, other: &Self) -> bool" $
|
||||
@@ -122,3 +153,8 @@ declareBaseStructure bitsize =
|
||||
out ("x.mask(usize::from(&m));")
|
||||
out ("assert_eq!(x, r);")
|
||||
out ("});")
|
||||
|
||||
groupCount :: Int -> [a] -> [[a]]
|
||||
groupCount x ls
|
||||
| x >= length ls = [ls]
|
||||
| otherwise = take x ls : groupCount x (drop x ls)
|
||||
12
src/lib.rs
12
src/lib.rs
@@ -20,5 +20,17 @@ pub trait CryptoNum {
|
||||
/// 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;
|
||||
/// Convert a slice into a CryptoNum, assuming big-endian memory layout.
|
||||
/// If you pass in a slice bigger than the bit size of the numeric type,
|
||||
/// this will assume that the number is in the first `n` bits of the
|
||||
/// memory layout. If you pass in a smaller buffer, it will use the bits
|
||||
/// available as the low `n` bits of the number.
|
||||
fn from_bytes(&self, bytes: &[u8]) -> Self;
|
||||
/// Write the cryptonum into the provide slice. If the provided slice
|
||||
/// is greater than or equal to `n` bits in length, `to_bytes` will
|
||||
/// write to the first `n` bits. If the slice is less than `n` bits
|
||||
/// in length, `to_bytes` will write the lower-order bits that fit
|
||||
/// into the provided slice.
|
||||
fn to_bytes(&self, bytes: &mut [u8]);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user