Improve context memory usage of Keccak and SHA3

saves up to 72 bytes per context for SHA3-512
This commit is contained in:
Vincent Hanquez 2016-03-26 10:29:33 +00:00
parent f362d50d46
commit 93fad940e4
9 changed files with 62 additions and 31 deletions

View File

@ -1,3 +1,8 @@
## 0.14
* Reduce size of SHA3 context instead of allocating all-size fit memory. save
up to 72 bytes of memory per context for SHA3-512.
## 0.13
* *SECURITY* Fix buffer overflow issue in SHA384, copying 16 extra bytes from

View File

@ -25,7 +25,7 @@ data Keccak_224 = Keccak_224
instance HashAlgorithm Keccak_224 where
hashBlockSize _ = 144
hashDigestSize _ = 28
hashInternalContextSize _ = 360
hashInternalContextSize _ = 352
hashInternalInit p = c_keccak_init p 224
hashInternalUpdate = c_keccak_update
hashInternalFinalize p = c_keccak_finalize p 224
@ -37,7 +37,7 @@ data Keccak_256 = Keccak_256
instance HashAlgorithm Keccak_256 where
hashBlockSize _ = 136
hashDigestSize _ = 32
hashInternalContextSize _ = 360
hashInternalContextSize _ = 344
hashInternalInit p = c_keccak_init p 256
hashInternalUpdate = c_keccak_update
hashInternalFinalize p = c_keccak_finalize p 256
@ -49,7 +49,7 @@ data Keccak_384 = Keccak_384
instance HashAlgorithm Keccak_384 where
hashBlockSize _ = 104
hashDigestSize _ = 48
hashInternalContextSize _ = 360
hashInternalContextSize _ = 312
hashInternalInit p = c_keccak_init p 384
hashInternalUpdate = c_keccak_update
hashInternalFinalize p = c_keccak_finalize p 384
@ -61,7 +61,7 @@ data Keccak_512 = Keccak_512
instance HashAlgorithm Keccak_512 where
hashBlockSize _ = 72
hashDigestSize _ = 64
hashInternalContextSize _ = 360
hashInternalContextSize _ = 280
hashInternalInit p = c_keccak_init p 512
hashInternalUpdate = c_keccak_update
hashInternalFinalize p = c_keccak_finalize p 512

View File

@ -25,7 +25,7 @@ data SHA3_224 = SHA3_224
instance HashAlgorithm SHA3_224 where
hashBlockSize _ = 144
hashDigestSize _ = 28
hashInternalContextSize _ = 360
hashInternalContextSize _ = 352
hashInternalInit p = c_sha3_init p 224
hashInternalUpdate = c_sha3_update
hashInternalFinalize p = c_sha3_finalize p 224
@ -37,7 +37,7 @@ data SHA3_256 = SHA3_256
instance HashAlgorithm SHA3_256 where
hashBlockSize _ = 136
hashDigestSize _ = 32
hashInternalContextSize _ = 360
hashInternalContextSize _ = 344
hashInternalInit p = c_sha3_init p 256
hashInternalUpdate = c_sha3_update
hashInternalFinalize p = c_sha3_finalize p 256
@ -49,7 +49,7 @@ data SHA3_384 = SHA3_384
instance HashAlgorithm SHA3_384 where
hashBlockSize _ = 104
hashDigestSize _ = 48
hashInternalContextSize _ = 360
hashInternalContextSize _ = 312
hashInternalInit p = c_sha3_init p 384
hashInternalUpdate = c_sha3_update
hashInternalFinalize p = c_sha3_finalize p 384
@ -61,7 +61,7 @@ data SHA3_512 = SHA3_512
instance HashAlgorithm SHA3_512 where
hashBlockSize _ = 72
hashDigestSize _ = 64
hashInternalContextSize _ = 360
hashInternalContextSize _ = 280
hashInternalInit p = c_sha3_init p 512
hashInternalUpdate = c_sha3_update
hashInternalFinalize p = c_sha3_finalize p 512

View File

@ -99,8 +99,9 @@ static inline void keccak_do_chunk(uint64_t state[25], uint64_t buf[], int bufsz
void cryptonite_keccak_init(struct keccak_ctx *ctx, uint32_t hashlen)
{
memset(ctx, 0, sizeof(*ctx));
ctx->bufsz = 200 - 2 * (hashlen / 8);
int bufsz = 200 - 2 * (hashlen / 8);
memset(ctx, 0, sizeof(*ctx) + bufsz);
ctx->bufsz = bufsz;
}
void cryptonite_keccak_update(struct keccak_ctx *ctx, uint8_t *data, uint32_t len)

View File

@ -31,7 +31,7 @@ struct keccak_ctx
uint32_t bufindex;
uint32_t bufsz;
uint64_t state[25];
uint8_t buf[144]; /* minimum SHA3-224, otherwise buffer need increases */
uint8_t buf[0]; /* maximum SHA3-224 = 144, otherwise buffer need decrease */
};
#define SHA3_CTX_SIZE sizeof(struct keccak_ctx)

View File

@ -99,8 +99,9 @@ static inline void sha3_do_chunk(uint64_t state[25], uint64_t buf[], int bufsz)
void cryptonite_sha3_init(struct sha3_ctx *ctx, uint32_t hashlen)
{
memset(ctx, 0, sizeof(*ctx));
ctx->bufsz = 200 - 2 * (hashlen / 8);
int bufsz = 200 - 2 * (hashlen / 8);
memset(ctx, 0, sizeof(*ctx) + bufsz);
ctx->bufsz = bufsz;
}
void cryptonite_sha3_update(struct sha3_ctx *ctx, const uint8_t *data, uint32_t len)

View File

@ -31,7 +31,7 @@ struct sha3_ctx
uint32_t bufindex;
uint32_t bufsz;
uint64_t state[25];
uint8_t buf[144]; /* minimum SHA3-224, otherwise buffer need increases */
uint8_t buf[0]; /* maximum SHA3-224 is 144 bytes, otherwise buffer can be decreases */
};
#define SHA3_CTX_SIZE sizeof(struct sha3_ctx)

View File

@ -23,6 +23,9 @@ newtype Bits = Bits Int
newtype Bytes = Bytes Int
deriving (Show,Eq,Num)
bitsToBytes :: Bits -> Bytes
bitsToBytes (Bits b) = Bytes (b `divSafe` 8)
class SizedNum a where
showBytes :: a -> String
showBits :: a -> String
@ -43,20 +46,22 @@ data GenHashModule = GenHashModule
, ghmHashName :: String
, ghmContextSize :: Bytes
, ghmCustomizable :: HashCustom
} deriving (Show,Eq)
}
data Prop =
VarCtx (Bits -> Bytes)
data HashCustom =
HashSimple Bits -- digest size in bits
Bytes -- block length in bytes
| HashMulti [(Bits, Bytes)] -- list of (digest output size in *bits*, block size in bytes)
deriving (Show,Eq)
| HashMulti [Prop] [(Bits, Bytes)] -- list of (digest output size in *bits*, block size in bytes)
hashModules =
-- module header hash ctx dg blk
[ GenHashModule "Blake2s" "blake2.h" "blake2s" 185 (HashMulti [(224,64), (256,64)])
, GenHashModule "Blake2sp" "blake2.h" "blake2sp" 2185 (HashMulti [(224,64), (256,64)])
, GenHashModule "Blake2b" "blake2.h" "blake2b" 361 (HashMulti [(512,128)])
, GenHashModule "Blake2bp" "blake2.h" "blake2sp" 2325 (HashMulti [(512,128)])
[ GenHashModule "Blake2s" "blake2.h" "blake2s" 185 (HashMulti [] [(224,64), (256,64)])
, GenHashModule "Blake2sp" "blake2.h" "blake2sp" 2185 (HashMulti [] [(224,64), (256,64)])
, GenHashModule "Blake2b" "blake2.h" "blake2b" 361 (HashMulti [] [(512,128)])
, GenHashModule "Blake2bp" "blake2.h" "blake2sp" 2325 (HashMulti [] [(512,128)])
, GenHashModule "MD2" "md2.h" "md2" 96 (HashSimple 128 16)
, GenHashModule "MD4" "md4.h" "md4" 96 (HashSimple 128 64)
, GenHashModule "MD5" "md5.h" "md5" 96 (HashSimple 128 64)
@ -65,16 +70,23 @@ hashModules =
, GenHashModule "SHA256" "sha256.h" "sha256" 192 (HashSimple 256 64)
, GenHashModule "SHA384" "sha512.h" "sha384" 256 (HashSimple 384 128)
, GenHashModule "SHA512" "sha512.h" "sha512" 256 (HashSimple 512 128)
, GenHashModule "SHA512t" "sha512.h" "sha512t" 256 (HashMulti [(224,128),(256,128)])
, GenHashModule "Keccak" "keccak.h" "keccak" 352 (HashMulti [(224,144),(256,136),(384,104),(512,72)])
, GenHashModule "SHA3" "sha3.h" "sha3" 352 (HashMulti [(224,144),(256,136),(384,104),(512,72)])
, GenHashModule "SHA512t" "sha512.h" "sha512t" 256 (HashMulti [] [(224,128),(256,128)])
, GenHashModule "Keccak" "keccak.h" "keccak" 352 (HashMulti [VarCtx sha3CtxSize] [(224,144),(256,136),(384,104),(512,72)])
, GenHashModule "SHA3" "sha3.h" "sha3" 352 (HashMulti [VarCtx sha3CtxSize] [(224,144),(256,136),(384,104),(512,72)])
, GenHashModule "RIPEMD160" "ripemd.h" "ripemd160" 128 (HashSimple 160 64)
, GenHashModule "Skein256" "skein256.h" "skein256" 96 (HashMulti [(224,32),(256,32)])
, GenHashModule "Skein512" "skein512.h" "skein512" 160 (HashMulti [(224,64),(256,64),(384,64),(512,64)])
, GenHashModule "Skein256" "skein256.h" "skein256" 96 (HashMulti [] [(224,32),(256,32)])
, GenHashModule "Skein512" "skein512.h" "skein512" 160 (HashMulti [] [(224,64),(256,64),(384,64),(512,64)])
, GenHashModule "Tiger" "tiger.h" "tiger" 96 (HashSimple 192 64)
, GenHashModule "Whirlpool" "whirlpool.h" "whirlpool" 168 (HashSimple 512 64)
]
sha3CtxSize :: Bits -> Bytes
sha3CtxSize bitLen = 4 + 4 + 8 * 25 -- generic context
+ sha3BlockSize bitLen -- variable buffer
sha3BlockSize :: Bits -> Bytes
sha3BlockSize bitLen = 200 - 2 * bitsToBytes bitLen
renderHashModules genOpts = do
hashTemplate <- readTemplate "template/hash.hs"
hashLenTemplate <- readTemplate "template/hash-len.hs"
@ -101,17 +113,29 @@ renderHashModules genOpts = do
]
, []
)
HashMulti customSizes ->
(hashLenTemplate, [],
HashMulti props customSizes ->
let customCtxSize =
let getVarCtx _ (VarCtx p) = Just p
getVarCtx x _ = x
in case foldl getVarCtx Nothing props of
Nothing -> \_ ->
[ ("CUSTOM_CTX_SIZE_BYTES" , showBytes (ghmContextSize ghm))
, ("CUSTOM_CTX_SIZE_WORD64" , showW64 (ghmContextSize ghm))
]
Just prop -> \outputSize ->
[ ("CUSTOM_CTX_SIZE_BYTES" , showBytes $ prop outputSize)
, ("CUSTOM_CTX_SIZE_WORD64" , showW64 $ prop outputSize)
]
in (hashLenTemplate, [],
[ ("CUSTOMIZABLE", map (\(outputSizeBits, customBlockSize) ->
[ ("CUSTOM_BITSIZE", showBits outputSizeBits)
, ("CUSTOM_DIGEST_SIZE_BITS", showBits outputSizeBits)
, ("CUSTOM_DIGEST_SIZE_BYTES", showBytes outputSizeBits)
, ("CUSTOM_BLOCK_SIZE_BYTES", showBytes customBlockSize)
]) customSizes
] ++ customCtxSize outputSizeBits) customSizes
)
]
)
)
writeTemplate mainName (baseVars ++ addVars) multiVars tpl

View File

@ -25,7 +25,7 @@ data %%MODULENAME%%_%%CUSTOM_BITSIZE%% = %%MODULENAME%%_%%CUSTOM_BITSIZE%%
instance HashAlgorithm %%MODULENAME%%_%%CUSTOM_BITSIZE%% where
hashBlockSize _ = %%CUSTOM_BLOCK_SIZE_BYTES%%
hashDigestSize _ = %%CUSTOM_DIGEST_SIZE_BYTES%%
hashInternalContextSize _ = %%CTX_SIZE_BYTES%%
hashInternalContextSize _ = %%CUSTOM_CTX_SIZE_BYTES%%
hashInternalInit p = c_%%HASHNAME%%_init p %%CUSTOM_BITSIZE%%
hashInternalUpdate = c_%%HASHNAME%%_update
hashInternalFinalize p = c_%%HASHNAME%%_finalize p %%CUSTOM_BITSIZE%%