Sometimes you want to use an integer as a nonce. For example, Alice might send messages to Bob using the numbers 1,3,5, ... as nonces and similarly Bob might use 2,4,6,... for the messages he sends to Alice. Another common case is to select a random nonce to encrypt the first message and then keep incrementing it for subsequent messages (sort of like a counter mode). I propose to include 2 helper functions to saltine to help with these cases:
succNonce :: Nonce -> Nonce
nonceFromInt :: Integral a => a -> Nonce
Care must be taken to make sure that those functions are implemented in an endianness independent fashion.
Here are naive implementation of the above functions, representing integers in little endian form:
succNonce :: Nonce -> Nonce
succNonce n = n'
where
Just n' = SC.decode $ B.pack $ succList $ B.unpack $ SC.encode n
succList :: (Bounded a, Enum a, Eq a) => [a] -> [a]
succList (x : xs)
| x == maxBound = minBound : succList xs
| otherwise = succ x : xs
succList [] = []
and
nonceFromInt :: Integral a => a -> Nonce
nonceFromInt x = n
where
Just n = SC.decode $ B.pack $ take nonceBytes $ littleEndianBytes x
-- this is vert ugly, a #const must be used here
nonceBytes = B.length $ SC.encode $ unsafeDupablePerformIO newNonce
littleEndianBytes :: Integral a => a -> [Word8]
littleEndianBytes x = fromIntegral r : littleEndianBytes q
where
(q, r) = x `quotRem` 256
where SC is Crypto.Saltine.Class and B is Data.ByteString.
Sometimes you want to use an integer as a nonce. For example, Alice might send messages to Bob using the numbers 1,3,5, ... as nonces and similarly Bob might use 2,4,6,... for the messages he sends to Alice. Another common case is to select a random nonce to encrypt the first message and then keep incrementing it for subsequent messages (sort of like a counter mode). I propose to include 2 helper functions to saltine to help with these cases:
Care must be taken to make sure that those functions are implemented in an endianness independent fashion.
Here are naive implementation of the above functions, representing integers in little endian form:
and
where
SCisCrypto.Saltine.ClassandBisData.ByteString.