Skip to content

Commit

Permalink
fix(arith): bug in vartime inversion when using fused inverse+multipl…
Browse files Browse the repository at this point in the history
…y by factor - found by Guido Vranken
  • Loading branch information
mratsim committed Jul 16, 2024
1 parent cbce226 commit b99ee13
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 2 deletions.
4 changes: 2 additions & 2 deletions constantine/math/arithmetic/limbs_exgcd.nim
Original file line number Diff line number Diff line change
Expand Up @@ -854,7 +854,7 @@ func invmod_vartime*(
r.setZero()
return
if a.isOne().bool:
r.setOne()
r = F
return

const Excess = 2
Expand Down Expand Up @@ -888,7 +888,7 @@ func invmod_vartime*(
r.setZero()
return
if a.isOne().bool:
r.setOne()
r = F
return

const Excess = 2
Expand Down
17 changes: 17 additions & 0 deletions tests/math_bigints/t_bigints.nim
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import
# Standard library
std/unittest,
# Internal
constantine/named/algebras,
constantine/math/io/io_bigints,
constantine/math/arithmetic,
constantine/platforms/abstractions,
Expand Down Expand Up @@ -658,6 +659,22 @@ proc mainModularInverse() =
bool(r == expected)
bool(r2 == expected)

test "#433 - CryptoFuzz / Oss-Fuzz bug with unit inversion":
block:
let a = BigInt[255].fromUint(1'u)
let M = BLS12_381.scalarFieldModulus()
let F = Fr[BLS12_381].getR2modP()

var r = canary(BigInt[255])
var r2 = canary(BigInt[255])

r.invmod(a, F, M)
r2.invmod_vartime(a, F, M)

check:
bool(r == F)
bool(r2 == F)

mainArith()
mainMul()
mainMulHigh()
Expand Down
10 changes: 10 additions & 0 deletions tests/math_fields/t_finite_fields_powinv.nim
Original file line number Diff line number Diff line change
Expand Up @@ -465,4 +465,14 @@ proc main_anti_regression =

check: bool(a == expected)

suite "Bug highlighted by 24/7 fuzzing (Guido Vranken's CryptoFuzz / Google-OssFuzz)" & " [" & $WordBitWidth & "-bit words]":
test "#433 - Short-circuit when Montgomery a' = aR (mod p) == 1":
let a = BigInt[255].fromDecimal("12549076656233958353659347336803947287922716146853412054870763148006372261952")
let expected = BigInt[255].fromDecimal("10920338887063814464675503992315976177888879664585288394250266608035967270910")
var aa = Fr[BLS12_381].fromBig(a)

doAssert bool(aa.mres.isOne())
aa.inv_vartime()
check: bool(aa.toBig() == expected)

main_anti_regression()

0 comments on commit b99ee13

Please sign in to comment.