Giter Site home page Giter Site logo

Comments (4)

mratsim avatar mratsim commented on September 28, 2024 1

Regarding optimizations, the representation must use uint64 on 64-bit arch and on x86 64-bit use extended precision multiplication 64x64->128 and 2-by-1 division.

from bigints.

mratsim avatar mratsim commented on September 28, 2024

See my comment to #78 (comment)

Offering functions with signatures proc add(r: var BigInt, a, b: BigInt) that allows algorithm implementers to reuse buffers.
Those function should properly deal with aliasing.

It's much easier for maintenance, optimization and future development to have a single high-level function that can handle aliasing, sign, a > b and b < a.
Then if needed you can specialize for the aliasing case. But it becomes very tricky if you want BigInt to work in the compile-time VM, it would be nice if we had overloads based on {.noalias.} that worked in the VM or some magic to compare if 2 parameters are actually pointing to the same memory.

This is what I do in Constantine:
At a low-level I have:

func add*(a: var Limbs, b: Limbs): Carry =
  ## Limbs addition
  ## Returns the carry
  when UseASM_X86_32:
    result = add_asm(a, a, b)
  else:
    result = Carry(0)
    for i in 0 ..< a.len:
      addC(result, a[i], a[i], b[i], result)

func add*(a: var Limbs, w: SecretWord): Carry =
  ## Limbs addition, add a number that fits in a word
  ## Returns the carry
  result = Carry(0)
  addC(result, a[0], a[0], w, result)
  for i in 1 ..< a.len:
    addC(result, a[i], a[i], Zero, result)

func sum*(r: var Limbs, a, b: Limbs): Carry =
  ## Sum `a` and `b` into `r`
  ## `r` is initialized/overwritten
  ##
  ## Returns the carry
  when UseASM_X86_32:
    result = add_asm(r, a, b)
  else:
    result = Carry(0)
    for i in 0 ..< a.len:
      addC(result, r[i], a[i], b[i], result)

https://github.com/mratsim/constantine/blob/50717d8/constantine/arithmetic/limbs.nim#L198-L226

And at a high-level I offer: https://github.com/mratsim/constantine/blob/50717d8/constantine/arithmetic/bigints.nim#L196-L246

func add*(a: var BigInt, b: BigInt): SecretBool =
  ## Constant-time in-place addition
  ## Returns the carry
  (SecretBool) add(a.limbs, b.limbs)

func add*(a: var BigInt, b: SecretWord): SecretBool =
  ## Constant-time in-place addition
  ## Returns the carry
  (SecretBool) add(a.limbs, b)

func `+=`*(a: var BigInt, b: BigInt) =
  ## Constant-time in-place addition
  ## Discards the carry
  discard add(a.limbs, b.limbs)

func `+=`*(a: var BigInt, b: SecretWord) =
  ## Constant-time in-place addition
  ## Discards the carry
  discard add(a.limbs, b)

func double*(a: var BigInt): SecretBool =
  ## Constant-time in-place doubling
  ## Returns the carry
  (SecretBool) add(a.limbs, a.limbs)

func sum*(r: var BigInt, a, b: BigInt): SecretBool =
  ## Sum `a` and `b` into `r`.
  ## `r` is initialized/overwritten
  ##
  ## Returns the carry
  (SecretBool) sum(r.limbs, a.limbs, b.limbs)

Note that sum can deal with aliasing.
That said Constantine has other limiting constraints, for example code must be constant-time so no branches that may depend on secret data so if/else. And on the other hand inputs are always positive and (almost always) same size, known at compile-time.

from bigints.

konsumlamm avatar konsumlamm commented on September 28, 2024

Hmm, one use case I see is optimizing a = b + c to addition(a, b, c), but I'd rather not expose the functions taking a buffer, so that would be limited to bigints functions. I think we should definitely optimize += etc.

from bigints.

mratsim avatar mratsim commented on September 28, 2024

If you want others to build more complex algorithm on top, having functions that do not allocate is very important for optimization.

People would be able to provide a pool of BigInt and recycle them in perf-critical code (this is done in Go for example).
People would be able to reuse a buffer for thousands of limbs for stuff like FFT, Prime algorithm and what not without stressing the allocator, especially in a multithreaded context.

from bigints.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.