mirror of
https://github.com/codex-storage/constantine.git
synced 2025-02-05 15:33:55 +00:00
fix fuzz 5 reloaded: modexp - endianness issue for exponent MSB (#266)
* fix fuzz 5 reloaded: endianness issue for exponent MSB * refactoring typo in test vs gmp
This commit is contained in:
parent
b645d68e1a
commit
1ad8499ae5
@ -361,7 +361,7 @@ func scalarMul_vartime*[scalBits; EC](
|
||||
|
||||
const L = scalBits.ceilDiv_vartime(M) + 1
|
||||
|
||||
let usedBits = scalar.limbs.getBits_vartime()
|
||||
let usedBits = scalar.limbs.getBits_LE_vartime()
|
||||
|
||||
when scalBits == EC.F.C.getCurveOrderBitwidth() and
|
||||
EC.F.C.hasEndomorphismAcceleration():
|
||||
|
@ -55,8 +55,8 @@ func powOddMod_vartime*(
|
||||
debug:
|
||||
doAssert bool(M.isOdd())
|
||||
|
||||
let aBits = a.getBits_vartime()
|
||||
let mBits = M.getBits_vartime()
|
||||
let aBits = a.getBits_LE_vartime()
|
||||
let mBits = M.getBits_LE_vartime()
|
||||
let L = wordsRequired(mBits)
|
||||
let m0ninv = M[0].negInvModWord()
|
||||
var rMont = allocStackArray(SecretWord, L)
|
||||
@ -105,17 +105,17 @@ func powMod_vartime*(
|
||||
|
||||
# Special cases: early returns
|
||||
# -------------------------------------------------------------------
|
||||
let mBits = M.getBits_vartime()
|
||||
let mBits = M.getBits_LE_vartime()
|
||||
if mBits < 2: # Check if modulus = 0 or 1
|
||||
r.setZero()
|
||||
return
|
||||
|
||||
let eBits = exponent.getBits_vartime()
|
||||
let eBits = exponent.getBits_BE_vartime()
|
||||
if eBits == 0: # Check if exponent == 0
|
||||
r.setOne() # a⁰ = 1 and 0⁰ = 1
|
||||
return
|
||||
|
||||
let aBits = a.getBits_vartime()
|
||||
let aBits = a.getBits_LE_vartime()
|
||||
if aBits < 2: # Check if a == 0 or a == 1
|
||||
r[0] = a[0]
|
||||
for i in 1 ..< r.len:
|
||||
|
@ -109,7 +109,7 @@ func powMod2k_vartime*(
|
||||
for i in 0 ..< r.len:
|
||||
r[i] = Zero
|
||||
|
||||
let msb = getMSB_vartime(exponent)
|
||||
let msb = getMSB_BE_vartime(exponent)
|
||||
|
||||
if msb == -1: # exponent is 0
|
||||
r[0] = One # x⁰ = 1, even for 0⁰
|
||||
|
@ -105,18 +105,40 @@ func ccopyWords*(
|
||||
# Bit operations
|
||||
# ------------------------------------------------------------
|
||||
|
||||
func getMSB_vartime*[T](a: openArray[T]): int =
|
||||
func getMSB_BE_vartime*(a: openArray[byte]): int =
|
||||
## Returns the position of the most significant bit
|
||||
## of `a`.
|
||||
## Returns -1 if a == 0
|
||||
##
|
||||
## Input MUST be ordered from most to least significant byte
|
||||
result = -1
|
||||
for i in countdown(a.len-1, 0):
|
||||
if bool(a[i] != T(0)):
|
||||
return int(log2_vartime(uint64 a[i])) + 8*sizeof(T)*i
|
||||
for i in 0 ..< a.len:
|
||||
if bool a[i] != 0:
|
||||
return int(log2_vartime(uint32 a[i])) + 8*sizeof(byte)*(a.len-1-i)
|
||||
|
||||
func getBits_vartime*[T](a: openArray[T]): int {.inline.} =
|
||||
func getBits_BE_vartime*(a: openArray[byte]): int {.inline.} =
|
||||
## Returns the number of bits used by `a`
|
||||
## Returns 0 for 0
|
||||
1 + getMSB_vartime(a)
|
||||
##
|
||||
## Input MUST be ordered from least to most significant byte
|
||||
1 + getMSB_BE_vartime(a)
|
||||
|
||||
func getMSB_LE_vartime(a: openArray[SecretWord]): int =
|
||||
## Returns the position of the most significant bit
|
||||
## of `a`.
|
||||
## Returns -1 if a == 0
|
||||
##
|
||||
## Input MUST be ordered from least to most significant word
|
||||
result = -1
|
||||
for i in countdown(a.len-1, 0):
|
||||
if bool a[i] != Zero:
|
||||
return int(log2_vartime(uint64 a[i])) + 8*sizeof(SecretWord)*i
|
||||
|
||||
func getBits_LE_vartime*(a: openArray[SecretWord]): int {.inline.} =
|
||||
## Returns the number of bits used by `a`
|
||||
## Returns 0 for 0
|
||||
##
|
||||
## Input MUST be ordered from least to most significant word
|
||||
1 + getMSB_LE_vartime(a)
|
||||
|
||||
{.pop.} # raises no exceptions
|
||||
|
@ -97,9 +97,9 @@ proc test(rng: var RngState) =
|
||||
mpz_clear(rr)
|
||||
|
||||
let
|
||||
aBits = a.getBits_vartime()
|
||||
eBits = e.getBits_vartime()
|
||||
mBits = M.getBits_vartime()
|
||||
aBits = a.getBits_LE_vartime()
|
||||
eBits = e.getBits_BE_vartime()
|
||||
mBits = M.getBits_LE_vartime()
|
||||
|
||||
rCtt.powMod_vartime(a, e, M, window = 4)
|
||||
|
||||
|
@ -42,6 +42,37 @@ suite "EVM ModExp precompile (EIP-198)":
|
||||
doAssert status == cttEVM_Success
|
||||
doAssert r[0] == 0, ". Result was " & $r[0]
|
||||
|
||||
test "Audit #5-2 - Fuzz failure with even modulus strikes back":
|
||||
let input = [
|
||||
|
||||
# Length of base (1)
|
||||
uint8 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
|
||||
# Length of exponent (5)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
|
||||
|
||||
# Length of modulus (1)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
|
||||
# Base
|
||||
0x3a,
|
||||
|
||||
# Exponent
|
||||
0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
# Modulus
|
||||
0x08
|
||||
]
|
||||
|
||||
var r = newSeq[byte](1)
|
||||
let status = r.eth_evm_modexp(input)
|
||||
doAssert status == cttEVM_Success
|
||||
doAssert r[0] == 0, ". Result was " & $r[0]
|
||||
|
||||
test "Audit #8 - off-by-1 buffer overflow - ptr + length exclusive vs openArray(lo, hi) inclusive":
|
||||
let input = [
|
||||
# Length of base (24)
|
||||
|
Loading…
x
Reference in New Issue
Block a user