2020-02-08 17:50:01 +00:00
|
|
|
# Constantine
|
|
|
|
# Copyright (c) 2018-2019 Status Research & Development GmbH
|
|
|
|
# Copyright (c) 2020-Present Mamy André-Ratsimbazafy
|
|
|
|
# Licensed and distributed under either of
|
|
|
|
# * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT).
|
|
|
|
# * 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, random,
|
2020-02-09 15:22:55 +00:00
|
|
|
../constantine/[io, bigints, primitives]
|
2020-02-08 17:50:01 +00:00
|
|
|
|
|
|
|
suite "isZero":
|
|
|
|
test "isZero for zero":
|
|
|
|
var x: BigInt[128]
|
|
|
|
check: x.isZero().bool
|
|
|
|
test "isZero for non-zero":
|
|
|
|
block:
|
|
|
|
var x = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
|
|
|
check: not x.isZero().bool
|
|
|
|
block:
|
|
|
|
var x = fromHex(BigInt[128], "0x00000000_00000001_00000000_00000000")
|
|
|
|
check: not x.isZero().bool
|
|
|
|
block:
|
|
|
|
var x = fromHex(BigInt[128], "0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF")
|
|
|
|
check: not x.isZero().bool
|
|
|
|
|
|
|
|
suite "Arithmetic operations - Addition":
|
|
|
|
test "Adding 2 zeros":
|
|
|
|
var a = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000000")
|
|
|
|
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000000")
|
|
|
|
let carry = a.add(b, ctrue(Word))
|
|
|
|
check: a.isZero().bool
|
|
|
|
|
|
|
|
test "Adding 1 zero - real addition":
|
|
|
|
block:
|
|
|
|
var a = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000000")
|
|
|
|
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
|
|
|
let carry = a.add(b, ctrue(Word))
|
|
|
|
|
|
|
|
let c = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
|
|
|
check:
|
|
|
|
bool(a == c)
|
|
|
|
block:
|
|
|
|
var a = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
|
|
|
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000000")
|
|
|
|
let carry = a.add(b, ctrue(Word))
|
|
|
|
|
|
|
|
let c = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
|
|
|
check:
|
|
|
|
bool(a == c)
|
|
|
|
|
|
|
|
test "Adding 1 zero - fake addition":
|
|
|
|
block:
|
|
|
|
var a = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000000")
|
|
|
|
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
|
|
|
let carry = a.add(b, cfalse(Word))
|
|
|
|
|
|
|
|
let c = a
|
|
|
|
check:
|
|
|
|
bool(a == c)
|
|
|
|
block:
|
|
|
|
var a = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
|
|
|
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000000")
|
|
|
|
let carry = a.add(b, cfalse(Word))
|
|
|
|
|
|
|
|
let c = a
|
|
|
|
check:
|
|
|
|
bool(a == c)
|
|
|
|
|
|
|
|
test "Adding non-zeros - real addition":
|
|
|
|
block:
|
|
|
|
var a = fromHex(BigInt[128], "0x00000000_00000001_00000000_00000000")
|
|
|
|
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
|
|
|
let carry = a.add(b, ctrue(Word))
|
|
|
|
|
|
|
|
let c = fromHex(BigInt[128], "0x00000000_00000001_00000000_00000001")
|
|
|
|
check:
|
|
|
|
bool(a == c)
|
|
|
|
block:
|
|
|
|
var a = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
|
|
|
let b = fromHex(BigInt[128], "0x00000000_00000001_00000000_00000000")
|
|
|
|
let carry = a.add(b, ctrue(Word))
|
|
|
|
|
|
|
|
let c = fromHex(BigInt[128], "0x00000000_00000001_00000000_00000001")
|
|
|
|
check:
|
|
|
|
bool(a == c)
|
|
|
|
|
|
|
|
test "Adding non-zeros - fake addition":
|
|
|
|
block:
|
|
|
|
var a = fromHex(BigInt[128], "0x00000000_00000001_00000000_00000000")
|
|
|
|
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
|
|
|
let carry = a.add(b, cfalse(Word))
|
|
|
|
|
|
|
|
let c = a
|
|
|
|
check:
|
|
|
|
bool(a == c)
|
|
|
|
block:
|
|
|
|
var a = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
|
|
|
let b = fromHex(BigInt[128], "0x00000000_00000001_00000000_00000000")
|
|
|
|
let carry = a.add(b, cfalse(Word))
|
|
|
|
|
|
|
|
let c = a
|
|
|
|
check:
|
|
|
|
bool(a == c)
|
2020-02-08 18:09:20 +00:00
|
|
|
|
|
|
|
test "Addition limbs carry":
|
|
|
|
block:
|
|
|
|
var a = fromHex(BigInt[128], "0x00000000_FFFFFFFF_FFFFFFFF_FFFFFFFE")
|
|
|
|
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
|
|
|
let carry = a.add(b, ctrue(Word))
|
|
|
|
|
|
|
|
let c = fromHex(BigInt[128], "0x00000000_FFFFFFFF_FFFFFFFF_FFFFFFFF")
|
|
|
|
check:
|
|
|
|
bool(a == c)
|
|
|
|
not bool(carry)
|
|
|
|
|
|
|
|
block:
|
|
|
|
var a = fromHex(BigInt[128], "0x00000000_FFFFFFFF_FFFFFFFF_FFFFFFFF")
|
|
|
|
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
|
|
|
let carry = a.add(b, ctrue(Word))
|
|
|
|
|
|
|
|
let c = fromHex(BigInt[128], "0x00000001_00000000_00000000_00000000")
|
|
|
|
check:
|
|
|
|
bool(a == c)
|
|
|
|
not bool(carry)
|
|
|
|
|
|
|
|
block:
|
|
|
|
var a = fromHex(BigInt[128], "0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF")
|
|
|
|
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
|
|
|
let carry = a.add(b, ctrue(Word))
|
|
|
|
|
|
|
|
# BigInt[128] takes 3 Words as a BigInt Word is 63-bit
|
|
|
|
var ab: array[3*sizeof(Word), byte]
|
|
|
|
ab.dumpRawUint(a, littleEndian)
|
|
|
|
|
|
|
|
# Given that it uses 3 words, we actually can store 2^128 in BigInt[128]
|
|
|
|
var c: array[3*sizeof(Word), byte]
|
|
|
|
c[16] = 1
|
|
|
|
check:
|
|
|
|
c == ab
|
|
|
|
not bool(carry) # carry can only happen within limbs
|