diff --git a/constantine.nimble b/constantine.nimble index 29774f8..8efa80a 100644 --- a/constantine.nimble +++ b/constantine.nimble @@ -26,19 +26,26 @@ proc test(path: string) = task test, "Run all tests": # -d:testingCurves is configured in a *.nim.cfg for convenience test "tests/test_primitives.nim" + test "tests/test_io_bigints.nim" test "tests/test_bigints.nim" test "tests/test_bigints_multimod.nim" - test "tests/test_bigints_vs_gmp.nim" + + test "tests/test_io_fields" test "tests/test_finite_fields.nim" - test "tests/test_finite_fields_vs_gmp.nim" test "tests/test_finite_fields_powinv.nim" + test "tests/test_bigints_vs_gmp.nim" + test "tests/test_finite_fields_vs_gmp.nim" + task test_no_gmp, "Run tests that don't require GMP": # -d:testingCurves is configured in a *.nim.cfg for convenience test "tests/test_primitives.nim" + test "tests/test_io_bigints.nim" test "tests/test_bigints.nim" test "tests/test_bigints_multimod.nim" + + test "tests/test_io_fields" test "tests/test_finite_fields.nim" test "tests/test_finite_fields_powinv.nim" diff --git a/constantine/arithmetic/bigints_raw.nim b/constantine/arithmetic/bigints_raw.nim index 90e9060..130313a 100644 --- a/constantine/arithmetic/bigints_raw.nim +++ b/constantine/arithmetic/bigints_raw.nim @@ -662,7 +662,9 @@ func montyPowPrologue( # forcing this inline actually reduces the code size result.window = scratchspace.len.getWindowLen() - result.bigIntSize = a.numLimbs() * sizeof(Word) + sizeof(BigIntView.bitLength) + result.bigIntSize = a.numLimbs() * sizeof(Word) + + offsetof(BigIntView, limbs) + + sizeof(BigIntView.bitLength) # Precompute window content, special case for window = 1 # (i.e scratchspace has only space for 2 temporaries) @@ -671,12 +673,11 @@ func montyPowPrologue( if result.window == 1: copyMem(pointer scratchspace[1], pointer a, result.bigIntSize) else: + scratchspace[1].setBitLength(bitSizeof(M)) copyMem(pointer scratchspace[2], pointer a, result.bigIntSize) for k in 2 ..< 1 shl result.window: scratchspace[k+1].montyMul(scratchspace[k], a, M, negInvModWord) - scratchspace[1].setBitLength(bitSizeof(M)) - # Set a to one copyMem(pointer a, pointer one, result.bigIntSize) diff --git a/constantine/primitives/extended_precision.nim b/constantine/primitives/extended_precision.nim index e7984df..297a4c5 100644 --- a/constantine/primitives/extended_precision.nim +++ b/constantine/primitives/extended_precision.nim @@ -123,8 +123,8 @@ when defined(gcc) or defined(clang) or defined(llvm_gcc): " + (unsigned __int128)", a2," * (unsigned __int128)", b2, " + (unsigned __int128)", c1, " + (unsigned __int128)", c2, ";"].} - {.emit:[hi, " = (NU64)", dblPrec," >> ", 63'u64, ";"].} - {.emit:[lo, " = (NU64)", dblPrec," & ", 1'u64 shl 63 - 1, ";"].} + {.emit:[hi, " = (NU64)(", dblPrec," >> ", 63'u64, ");"].} + {.emit:[lo, " = (NU64)", dblPrec," & ", (1'u64 shl 63 - 1), ";"].} else: {.error: "Compiler not implemented".} diff --git a/tests/test_finite_fields_powinv.nim b/tests/test_finite_fields_powinv.nim index cddf2d2..122e87b 100644 --- a/tests/test_finite_fields_powinv.nim +++ b/tests/test_finite_fields_powinv.nim @@ -20,6 +20,25 @@ proc main() = test "n² mod 101": let exponent = BigInt[64].fromUint(2'u64) + block: # 1*1 mod 101 + var n, expected: Fp[Fake101] + + n.fromUint(1'u32) + expected = n + + var r: Fp[Fake101] + r.prod(n, n) + + var r_bytes: array[8, byte] + r_bytes.exportRawUint(r, cpuEndian) + let rU64 = cast[uint64](r_bytes) + + check: + # Check equality in the Montgomery domain + bool(r == expected) + # Check equality when converting back to natural domain + 1'u64 == rU64 + block: # 1^2 mod 101 var n, expected: Fp[Fake101] diff --git a/tests/test_io_fields.nim b/tests/test_io_fields.nim index 5960a9b..1e06d7c 100644 --- a/tests/test_io_fields.nim +++ b/tests/test_io_fields.nim @@ -6,7 +6,7 @@ # * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0). # at your option. This file may not be copied, modified, or distributed except according to those terms. -import unittest, +import unittest, random, ../constantine/io/[io_bigints, io_fields], ../constantine/config/curves, ../constantine/config/common,