Fix extended prec multiplication carry. Passing modulo tests against medium BigInt (192~256 bits)

This commit is contained in:
Mamy André-Ratsimbazafy 2020-02-10 22:19:47 +01:00
parent 73b71a184c
commit 8d160189d1
No known key found for this signature in database
GPG Key ID: 7B88AD1FE79492E1
5 changed files with 15 additions and 17 deletions

View File

@ -19,4 +19,5 @@ task test, "Run all tests":
test "", "tests/test_primitives.nim"
test "", "tests/test_io.nim"
test "", "tests/test_bigints.nim"
test "", "tests/test_bigints_multimod.nim"
test " -d:testingCurves", "tests/test_field_fp.nim"

View File

@ -57,6 +57,8 @@ from sugar import distinctBase
type Word* = Ct[uint32]
## Logical BigInt word
## A logical BigInt word is of size physical MachineWord-1
type DoubleWord = Ct[uint64]
type BaseType* = uint32
## Physical BigInt for conversion in "normal integers"
@ -357,17 +359,15 @@ func shlAddMod(a: BigIntViewMut, c: Word, M: BigIntViewConst) =
var qp_lo: Word
block: # q*p
var qp_hi: Word
unsafeExtendedPrecMul(qp_hi, qp_lo, q, M[i]) # q * p
qp_lo += carry # Add carry from previous limb
carry = qp_hi shl 1 + qp_lo.isMsbSet.Word # New carry
qp_lo = qp_lo and MaxWord # Normalize to u63
# q * p + carry (doubleword) carry from previous limb
let qp = unsafeExtPrecMul(q, M[i]) + carry.DoubleWord
carry = Word(qp shr WordBitSize) # New carry: high digit besides LSB
qp_lo = qp.Word and MaxWord # Normalize to u63
block: # a*2^63 - q*p
a[i] -= qp_lo
carry += Word(a[i].isMsbSet) # Adjust if borrow
a[i] = a[i] and MaxWord # Normalize to u63
carry += Word(a[i].isMsbSet) # Adjust if borrow
a[i] = a[i] and MaxWord # Normalize to u63
over_p = mux(
a[i] == M[i], over_p,

View File

@ -38,7 +38,7 @@ func asm_x86_64_extMul(hi, lo: var uint64, a, b: uint64) {.inline.}=
:
"""
func unsafeExtendedPrecMul*(hi, lo: var Ct[uint64], a, b: Ct[uint64]) {.inline.}=
func unsafeExtPrecMul*(hi, lo: var Ct[uint64], a, b: Ct[uint64]) {.inline.}=
## Extended precision multiplication uint64 * uint64 --> uint128
##
## TODO, at the moment only x86_64 architecture are supported
@ -57,13 +57,9 @@ func unsafeExtendedPrecMul*(hi, lo: var Ct[uint64], a, b: Ct[uint64]) {.inline.}
else:
asm_x86_64_extMul(T(hi), T(lo), T(a), T(b))
import strutils
func unsafeExtendedPrecMul*(hi, lo: var Ct[uint32], a, b: Ct[uint32]) {.inline.}=
## Extended precision multiplication uint32 * uint32 --> uint32
let extMul = uint64(a) * uint64(b)
hi = (Ct[uint32])(extMul shr 32)
lo = (Ct[uint32])(extMul and ((1'u64 shl 32) - 1))
template unsafeExtPrecMul*(a, b: Ct[uint32]): Ct[uint64] =
## Extended precision multiplication uint32 * uint32 --> uint64
Ct[uint64](uint64(a) * uint64(b))
func asm_x86_64_div2n1n(q, r: var uint64, n_hi, n_lo, d: uint64) {.inline.}=
## Division uint128 by uint64

View File

@ -10,7 +10,7 @@ import
# Standard library
unittest, random, strutils,
# Third-party
../constantine/[io, bigints, primitives]
../constantine/[io, bigints_raw, bigints_public, primitives]
suite "Bigints - Multiprecision modulo":
test "bitsize 237 mod bitsize 192":

View File

@ -0,0 +1 @@
-d:debugConstantine