mirror of
https://github.com/logos-storage/constantine.git
synced 2026-01-02 13:13:07 +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
|
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
|
when scalBits == EC.F.C.getCurveOrderBitwidth() and
|
||||||
EC.F.C.hasEndomorphismAcceleration():
|
EC.F.C.hasEndomorphismAcceleration():
|
||||||
|
|||||||
@ -55,8 +55,8 @@ func powOddMod_vartime*(
|
|||||||
debug:
|
debug:
|
||||||
doAssert bool(M.isOdd())
|
doAssert bool(M.isOdd())
|
||||||
|
|
||||||
let aBits = a.getBits_vartime()
|
let aBits = a.getBits_LE_vartime()
|
||||||
let mBits = M.getBits_vartime()
|
let mBits = M.getBits_LE_vartime()
|
||||||
let L = wordsRequired(mBits)
|
let L = wordsRequired(mBits)
|
||||||
let m0ninv = M[0].negInvModWord()
|
let m0ninv = M[0].negInvModWord()
|
||||||
var rMont = allocStackArray(SecretWord, L)
|
var rMont = allocStackArray(SecretWord, L)
|
||||||
@ -105,17 +105,17 @@ func powMod_vartime*(
|
|||||||
|
|
||||||
# Special cases: early returns
|
# Special cases: early returns
|
||||||
# -------------------------------------------------------------------
|
# -------------------------------------------------------------------
|
||||||
let mBits = M.getBits_vartime()
|
let mBits = M.getBits_LE_vartime()
|
||||||
if mBits < 2: # Check if modulus = 0 or 1
|
if mBits < 2: # Check if modulus = 0 or 1
|
||||||
r.setZero()
|
r.setZero()
|
||||||
return
|
return
|
||||||
|
|
||||||
let eBits = exponent.getBits_vartime()
|
let eBits = exponent.getBits_BE_vartime()
|
||||||
if eBits == 0: # Check if exponent == 0
|
if eBits == 0: # Check if exponent == 0
|
||||||
r.setOne() # a⁰ = 1 and 0⁰ = 1
|
r.setOne() # a⁰ = 1 and 0⁰ = 1
|
||||||
return
|
return
|
||||||
|
|
||||||
let aBits = a.getBits_vartime()
|
let aBits = a.getBits_LE_vartime()
|
||||||
if aBits < 2: # Check if a == 0 or a == 1
|
if aBits < 2: # Check if a == 0 or a == 1
|
||||||
r[0] = a[0]
|
r[0] = a[0]
|
||||||
for i in 1 ..< r.len:
|
for i in 1 ..< r.len:
|
||||||
|
|||||||
@ -109,7 +109,7 @@ func powMod2k_vartime*(
|
|||||||
for i in 0 ..< r.len:
|
for i in 0 ..< r.len:
|
||||||
r[i] = Zero
|
r[i] = Zero
|
||||||
|
|
||||||
let msb = getMSB_vartime(exponent)
|
let msb = getMSB_BE_vartime(exponent)
|
||||||
|
|
||||||
if msb == -1: # exponent is 0
|
if msb == -1: # exponent is 0
|
||||||
r[0] = One # x⁰ = 1, even for 0⁰
|
r[0] = One # x⁰ = 1, even for 0⁰
|
||||||
|
|||||||
@ -105,18 +105,40 @@ func ccopyWords*(
|
|||||||
# Bit operations
|
# 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
|
## Returns the position of the most significant bit
|
||||||
## of `a`.
|
## of `a`.
|
||||||
## Returns -1 if a == 0
|
## Returns -1 if a == 0
|
||||||
|
##
|
||||||
|
## Input MUST be ordered from most to least significant byte
|
||||||
result = -1
|
result = -1
|
||||||
for i in countdown(a.len-1, 0):
|
for i in 0 ..< a.len:
|
||||||
if bool(a[i] != T(0)):
|
if bool a[i] != 0:
|
||||||
return int(log2_vartime(uint64 a[i])) + 8*sizeof(T)*i
|
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 the number of bits used by `a`
|
||||||
## Returns 0 for 0
|
## 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
|
{.pop.} # raises no exceptions
|
||||||
|
|||||||
@ -97,9 +97,9 @@ proc test(rng: var RngState) =
|
|||||||
mpz_clear(rr)
|
mpz_clear(rr)
|
||||||
|
|
||||||
let
|
let
|
||||||
aBits = a.getBits_vartime()
|
aBits = a.getBits_LE_vartime()
|
||||||
eBits = e.getBits_vartime()
|
eBits = e.getBits_BE_vartime()
|
||||||
mBits = M.getBits_vartime()
|
mBits = M.getBits_LE_vartime()
|
||||||
|
|
||||||
rCtt.powMod_vartime(a, e, M, window = 4)
|
rCtt.powMod_vartime(a, e, M, window = 4)
|
||||||
|
|
||||||
|
|||||||
@ -42,6 +42,37 @@ suite "EVM ModExp precompile (EIP-198)":
|
|||||||
doAssert status == cttEVM_Success
|
doAssert status == cttEVM_Success
|
||||||
doAssert r[0] == 0, ". Result was " & $r[0]
|
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":
|
test "Audit #8 - off-by-1 buffer overflow - ptr + length exclusive vs openArray(lo, hi) inclusive":
|
||||||
let input = [
|
let input = [
|
||||||
# Length of base (24)
|
# Length of base (24)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user