Skip to content

Commit ba80125

Browse files
committed
Core: Internal: add module Truncation
1 parent 78f3a26 commit ba80125

File tree

3 files changed

+45
-20
lines changed

3 files changed

+45
-20
lines changed

hnix-store-core/hnix-store-core.cabal

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,10 @@ library
3333
, System.Nix.Build
3434
, System.Nix.Derivation
3535
, System.Nix.Hash
36+
, System.Nix.Internal.Base
3637
, System.Nix.Internal.Base32
38+
, System.Nix.Internal.Truncation
3739
, System.Nix.Internal.Hash
38-
, System.Nix.Internal.Base
3940
, System.Nix.Internal.Nar.Parser
4041
, System.Nix.Internal.Nar.Streamer
4142
, System.Nix.Internal.Nar.Effects

hnix-store-core/src/System/Nix/Internal/Hash.hs

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,21 @@ import qualified Crypto.Hash.SHA1 as SHA1
1919
import qualified Crypto.Hash.SHA256 as SHA256
2020
import qualified Crypto.Hash.SHA512 as SHA512
2121
import qualified Data.ByteString as BS
22-
import Data.Bits (xor)
2322
import qualified Data.ByteString.Lazy as BSL
2423
import qualified Data.Hashable as DataHashable
2524
import Data.List (foldl')
2625
import Data.Proxy (Proxy(Proxy))
2726
import Data.Text (Text)
2827
import qualified Data.Text as T
29-
import Data.Word (Word8)
3028
import qualified GHC.TypeLits as Kind
3129
(Nat, KnownNat, natVal)
3230
import System.Nix.Internal.Base
3331
( BaseEncoding(Base16,NixBase32,Base64)
3432
, encodeWith
3533
, decodeWith
3634
)
37-
import Data.Bool (bool)
3835
import Data.Coerce (coerce)
36+
import System.Nix.Internal.Truncation (truncateInNixWay)
3937

4038
-- | The universe of supported hash algorithms.
4139
--
@@ -202,22 +200,7 @@ instance (ValidAlgo a, Kind.KnownNat n) => ValidAlgo ('Truncated n a) where
202200
truncateDigestInNixWay
203201
:: forall n a .(Kind.KnownNat n) => Digest a -> Digest ('Truncated n a)
204202
-- 2021-06-07: NOTE: ^ This is why all the cookery with DataKinds, trunkation length (if allowed arbitrary) needs to be represented in type.
205-
-- 2021-06-07: NOTE: Renamed function, since truncation can be done in a lot of ways, there is no practice of truncting hashes this way, moreover: <https://crypto.stackexchange.com/questions/56337/strength-of-hash-obtained-by-xor-of-parts-of-sha3>
206203
truncateDigestInNixWay (Digest c) =
207-
Digest $ BS.pack $ fmap truncOutputByte [0.. n-1]
204+
Digest $ truncateInNixWay n c
208205
where
209206
n = fromIntegral $ Kind.natVal $ Proxy @n
210-
211-
truncOutputByte :: Int -> Word8
212-
truncOutputByte i = foldl' (aux i) 0 [0 .. BS.length c - 1]
213-
214-
inputByte :: Int -> Word8
215-
inputByte j = BS.index c j
216-
217-
aux :: Int -> Word8 -> Int -> Word8
218-
aux i x j =
219-
bool
220-
id
221-
(`xor` inputByte j)
222-
(j `mod` n == i)
223-
x
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{-# LANGUAGE ScopedTypeVariables #-}
2+
{-# LANGUAGE TypeApplications #-}
3+
{-# LANGUAGE DataKinds #-}
4+
5+
module System.Nix.Internal.Truncation where
6+
7+
import qualified Data.ByteString as Bytes
8+
import Data.Bits (xor)
9+
import Data.List (foldl')
10+
import Data.Word (Word8)
11+
import Data.Bool (bool)
12+
13+
-- | Bytewise truncation of a 'Digest'.
14+
--
15+
-- When truncation length is greater than the length of the bytestring
16+
-- but less than twice the bytestring length, truncation splits the
17+
-- bytestring into a head part (truncation length) and tail part
18+
-- (leftover part), right-pads the leftovers with 0 to the truncation
19+
-- length, and combines the two strings bytewise with 'xor'.
20+
truncateInNixWay
21+
:: Int -> Bytes.ByteString -> Bytes.ByteString
22+
-- 2021-06-07: NOTE: Renamed function, since truncation can be done in a lot of ways, there is no practice of truncting hashes this way, moreover:
23+
-- 1. <https://crypto.stackexchange.com/questions/56337/strength-of-hash-obtained-by-xor-of-parts-of-sha3>
24+
-- 2. <https://www.reddit.com/r/crypto/comments/6olqfm/ways_to_truncated_hash/>
25+
truncateInNixWay n c =
26+
Bytes.pack $ fmap truncOutputByte [0 .. n-1]
27+
where
28+
29+
truncOutputByte :: Int -> Word8
30+
truncOutputByte i = foldl' (aux i) 0 [0 .. Bytes.length c - 1]
31+
32+
inputByte :: Int -> Word8
33+
inputByte j = Bytes.index c j
34+
35+
aux :: Int -> Word8 -> Int -> Word8
36+
aux i x j =
37+
bool
38+
id
39+
(`xor` inputByte j)
40+
(j `mod` n == i)
41+
x

0 commit comments

Comments
 (0)