Skip to content
Snippets Groups Projects
Commit 4d7cd68b authored by Herbert Valerio Riedel's avatar Herbert Valerio Riedel :man_dancing:
Browse files

Add side-channel attack resilient `powModSecInteger`


This is a follow-up to 97c101b7 which
introduced the "ordinary" `powModInteger` operation.

Signed-off-by: Herbert Valerio Riedel's avatarHerbert Valerio Riedel <hvr@gnu.org>
parent ed55293b
No related branches found
No related tags found
No related merge requests found
{-# LANGUAGE NoImplicitPrelude #-}
module GHC.Integer.GMP.Internals (Integer(..), gcdInt, gcdInteger, gcdExtInteger, lcmInteger, powInteger, powModInteger, recipModInteger)
module GHC.Integer.GMP.Internals (Integer(..), gcdInt, gcdInteger, gcdExtInteger, lcmInteger, powInteger, powModInteger, powModSecInteger, recipModInteger)
where
import GHC.Integer.Type
......
......@@ -43,6 +43,7 @@ module GHC.Integer.GMP.Prim (
powInteger#,
powModInteger#,
powModSecInteger#,
recipModInteger#,
#if WORD_SIZE_IN_BITS < 64
......@@ -196,6 +197,11 @@ foreign import prim "integer_cmm_powIntegerzh" powInteger#
foreign import prim "integer_cmm_powModIntegerzh" powModInteger#
:: Int# -> ByteArray# -> Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
-- |
--
foreign import prim "integer_cmm_powModSecIntegerzh" powModSecInteger#
:: Int# -> ByteArray# -> Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
-- |
--
foreign import prim "integer_cmm_recipModIntegerzh" recipModInteger#
......
......@@ -45,7 +45,7 @@ import GHC.Integer.GMP.Prim (
int2Integer#, integer2Int#, word2Integer#, integer2Word#,
andInteger#, orInteger#, xorInteger#, complementInteger#,
testBitInteger#, mul2ExpInteger#, fdivQ2ExpInteger#,
powInteger#, powModInteger#, recipModInteger#,
powInteger#, powModInteger#, powModSecInteger#, recipModInteger#,
#if WORD_SIZE_IN_BITS < 64
int64ToInteger#, integerToInt64#,
word64ToInteger#, integerToWord64#,
......@@ -616,6 +616,20 @@ powModInteger (J# s1 d1) (J# s2 d2) (J# s3 d3) =
(# s', d' #) -> J# s' d'
powModInteger b e m = powModInteger (toBig b) (toBig e) (toBig m)
-- | @powModSecInteger b e m@ computes base @b@ raised to exponent @e@
-- modulo @m@. It is required that @e@ > 0 and @m@ is odd.
--
-- This is a \"secure\" variant of 'powModInteger' using the
-- @mpz_powm_sec()@ function which is designed to be resilient to side
-- channel attacks and is therefore intended for cryptographic
-- applications.
{-# NOINLINE powModSecInteger #-}
powModSecInteger :: Integer -> Integer -> Integer -> Integer
powModSecInteger (J# s1 d1) (J# s2 d2) (J# s3 d3) =
case powModSecInteger# s1 d1 s2 d2 s3 d3 of
(# s', d' #) -> J# s' d'
powModSecInteger b e m = powModSecInteger (toBig b) (toBig e) (toBig m)
-- | @recipModInteger x m@ computes the inverse of @x@ modulo @m@. If
-- the inverse exists, the return value @y@ will satisfy @0 < y <
-- abs(m)@, otherwise the result is 0.
......
......@@ -52,6 +52,7 @@ import "integer-gmp" __gmpz_ior;
import "integer-gmp" __gmpz_com;
import "integer-gmp" __gmpz_pow_ui;
import "integer-gmp" __gmpz_powm;
import "integer-gmp" __gmpz_powm_sec;
import "integer-gmp" __gmpz_invert;
import "integer-gmp" integer_cbits_decodeDouble;
......@@ -437,6 +438,7 @@ GMP_TAKE2_RET2(integer_cmm_quotRemIntegerzh, __gmpz_tdiv_qr)
GMP_TAKE2_RET2(integer_cmm_divModIntegerzh, __gmpz_fdiv_qr)
GMP_TAKE3_RET1(integer_cmm_powModIntegerzh, __gmpz_powm)
GMP_TAKE3_RET1(integer_cmm_powModSecIntegerzh, __gmpz_powm_sec)
GMP_TAKE2_RET1(integer_cmm_recipModIntegerzh, __gmpz_invert)
GMP_TAKE1_UL1_RET1(integer_cmm_powIntegerzh, __gmpz_pow_ui)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment