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
|
where
|
||||||
|
|
||||||
import Control.Monad(forM_)
|
import Control.Monad(forM_)
|
||||||
|
import Data.List(intercalate)
|
||||||
import File
|
import File
|
||||||
import Gen
|
import Gen
|
||||||
|
|
||||||
@@ -57,6 +58,36 @@ declareBaseStructure bitsize =
|
|||||||
out "return false;"
|
out "return false;"
|
||||||
out "(self.value[idx] & (1u64 << offset)) != 0"
|
out "(self.value[idx] & (1u64 << offset)) != 0"
|
||||||
blank
|
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 $
|
implFor "PartialEq" name $
|
||||||
wrapIndent "fn eq(&self, other: &Self) -> bool" $
|
wrapIndent "fn eq(&self, other: &Self) -> bool" $
|
||||||
do forM_ (reverse [1..top]) $ \ i ->
|
do forM_ (reverse [1..top]) $ \ i ->
|
||||||
@@ -122,3 +153,8 @@ declareBaseStructure bitsize =
|
|||||||
out ("x.mask(usize::from(&m));")
|
out ("x.mask(usize::from(&m));")
|
||||||
out ("assert_eq!(x, r);")
|
out ("assert_eq!(x, r);")
|
||||||
out ("});")
|
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
|
/// Test if the given bit is zero, where bits are numbered in
|
||||||
/// least-significant order (0 is the LSB, etc.).
|
/// least-significant order (0 is the LSB, etc.).
|
||||||
fn testbit(&self, bit: usize) -> bool;
|
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