Skip to content

divRem_vartime doesn't seem to work #538

@bkomuves

Description

@bkomuves

In constantine/math_arbitrary_precision/arithmetic/limbs_divmod_vartime there is a divRem_vartime function, which I assume is supposed to implement arbitrary precision integer division with remainder.

(I couldn't find any other function implementing this operation)

However, this appears to be completely broken. For example with inputs a = 2^64 + 3 and b = 1234567 I get the result q = 0 and r = 3

Example code:

import pkg/constantine/platforms/abstractions
import pkg/constantine/math/arithmetic/bigints
import pkg/constantine/math/io/io_bigints
import pkg/constantine/math_arbitrary_precision/arithmetic/limbs_divmod_vartime

proc printSecretArray(xs: array[4, SecretWord]) = 
  echo " - limbs[0] = " & $uint64(xs[0])
  echo " - limbs[1] = " & $uint64(xs[1])
  echo " - limbs[2] = " & $uint64(xs[2])
  echo " - limbs[3] = " & $uint64(xs[3])

proc main() =

  var x : BigInt[256]
  # let _ = x.fromDecimal("18446744073709551613")     # 2^64 - 3   // this works
  let _ = x.fromDecimal("18446744073709551619")       # 2^64 + 3   // this doesn't

  var y : BigInt[256]
  let _ = y.fromDecimal("1234567")

  let a: array[4, SecretWord] = x.limbs
  let b: array[4, SecretWord] = y.limbs
  var q: array[4, SecretWord]
  var r: array[4, SecretWord]
  
  let res = divRem_vartime(q,r,a,b)
  echo "function returns: " & $res

  echo "quotient limbs:"
  printSecretArray(q)
  echo "remainder limbs:"
  printSecretArray(r)

  let qbig: BigInt[256] = BigInt[256](limbs: q)  
  let rbig: BigInt[256] = BigInt[256](limbs: r)

  echo "x = " & toDecimal(x)
  echo "y = " & toDecimal(y)
  echo "q = " & toDecimal(qbig)
  echo "r = " & toDecimal(rbig)

  var mverybig: BigInt[512] 
  prod[512,256,256](mverybig,qbig,y)       # q*y

  var mbig: BigInt[256]
  copyTruncatedFrom[256,512](mbig,mverybig)

  var reconstr_x: BigInt[256] = rbig
  reconstr_x += mbig                       # q*y + r

  echo "q * y           = " & toDecimal(mbig)
  echo "reconstructed x = " & toDecimal(reconstr_x)

  echo "OK = " & $(bool(x == reconstr_x))

when isMainModule:
  main()

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions