Github Action CI (without GMP) (#29)
* Github Action CI (without GMP) * Deactivate MacOS, spurious failures: https://github.com/actions/virtual-environments/issues/841 * force install with nimble * Add badge * Don"t include Nim 1.2.x https://github.com/mratsim/constantine/pull/20#issuecomment-646327952 * Action branch mistake * Add back OSX? https://github.com/actions/virtual-environments/issues/841, https://github.com/actions/virtual-environments/issues/969 * fix MacOS target * comment out RDTSC on i386 * Add initialization canaries * Add more verbose output to debug windows failures * spurious windows i386 test * For now only activate Linux and mac * missed include
This commit is contained in:
parent
b509eeaeb6
commit
a2a2495351
|
@ -0,0 +1,199 @@
|
||||||
|
name: Constantine CI
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
max-parallel: 20
|
||||||
|
matrix:
|
||||||
|
branch: [devel] # [version-1-2, devel] - # 1.2 doesn't compile https://github.com/mratsim/constantine/pull/20#issuecomment-646327952
|
||||||
|
target:
|
||||||
|
- os: linux
|
||||||
|
cpu: amd64
|
||||||
|
TEST_LANG: c
|
||||||
|
- os: linux
|
||||||
|
cpu: amd64
|
||||||
|
TEST_LANG: cpp
|
||||||
|
- os: linux
|
||||||
|
cpu: i386
|
||||||
|
TEST_LANG: c
|
||||||
|
- os: linux
|
||||||
|
cpu: i386
|
||||||
|
TEST_LANG: cpp
|
||||||
|
- os: macos
|
||||||
|
cpu: amd64
|
||||||
|
TEST_LANG: c
|
||||||
|
- os: macos
|
||||||
|
cpu: amd64
|
||||||
|
TEST_LANG: cpp
|
||||||
|
# TODO:
|
||||||
|
# 1. Modulo/reduce bug on 32-bit
|
||||||
|
# 2. ModInverse bug on all windows
|
||||||
|
# - os: windows
|
||||||
|
# cpu: amd64
|
||||||
|
# TEST_LANG: c
|
||||||
|
# - os: windows
|
||||||
|
# cpu: amd64
|
||||||
|
# TEST_LANG: cpp
|
||||||
|
# - os: windows
|
||||||
|
# cpu: i386
|
||||||
|
# TEST_LANG: c
|
||||||
|
# - os: windows
|
||||||
|
# cpu: i386
|
||||||
|
# TEST_LANG: cpp
|
||||||
|
include:
|
||||||
|
- target:
|
||||||
|
os: linux
|
||||||
|
builder: ubuntu-18.04
|
||||||
|
- target:
|
||||||
|
os: macos
|
||||||
|
builder: macos-10.15
|
||||||
|
# - target:
|
||||||
|
# os: windows
|
||||||
|
# builder: windows-2019
|
||||||
|
name: '${{ matrix.target.os }}-${{ matrix.target.cpu }}-${{ matrix.target.TEST_LANG }} (${{ matrix.branch }})'
|
||||||
|
runs-on: ${{ matrix.builder }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout constantine
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
path: constantine
|
||||||
|
|
||||||
|
# - name: Install dependencies (Linux amd64)
|
||||||
|
# if: runner.os == 'Linux' && matrix.target.cpu == 'amd64'
|
||||||
|
# run: |
|
||||||
|
# sudo DEBIAN_FRONTEND='noninteractive' apt-fast install \
|
||||||
|
# --no-install-recommends -yq <packages here>
|
||||||
|
|
||||||
|
- name: Install dependencies (Linux i386)
|
||||||
|
if: runner.os == 'Linux' && matrix.target.cpu == 'i386'
|
||||||
|
run: |
|
||||||
|
sudo dpkg --add-architecture i386
|
||||||
|
sudo apt-fast update -qq
|
||||||
|
sudo DEBIAN_FRONTEND='noninteractive' apt-fast install \
|
||||||
|
--no-install-recommends -yq gcc-multilib g++-multilib \
|
||||||
|
libssl-dev:i386
|
||||||
|
mkdir -p external/bin
|
||||||
|
cat << EOF > external/bin/gcc
|
||||||
|
#!/bin/bash
|
||||||
|
exec $(which gcc) -m32 "\$@"
|
||||||
|
EOF
|
||||||
|
cat << EOF > external/bin/g++
|
||||||
|
#!/bin/bash
|
||||||
|
exec $(which g++) -m32 "\$@"
|
||||||
|
EOF
|
||||||
|
chmod 755 external/bin/gcc external/bin/g++
|
||||||
|
echo '::add-path::${{ github.workspace }}/external/bin'
|
||||||
|
# - name: Install dependencies (macOS)
|
||||||
|
# if: runner.os == 'macOS'
|
||||||
|
# run: brew install <packages here>
|
||||||
|
|
||||||
|
- name: Install dependencies (Windows)
|
||||||
|
if: runner.os == 'Windows'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
mkdir external
|
||||||
|
if [[ '${{ matrix.target.cpu }}' == 'amd64' ]]; then
|
||||||
|
arch=64
|
||||||
|
else
|
||||||
|
arch=32
|
||||||
|
fi
|
||||||
|
curl -L "https://nim-lang.org/download/mingw$arch-6.3.0.7z" -o "external/mingw$arch.7z"
|
||||||
|
curl -L "https://nim-lang.org/download/windeps.zip" -o external/windeps.zip
|
||||||
|
7z x "external/mingw$arch.7z" -oexternal/
|
||||||
|
7z x external/windeps.zip -oexternal/dlls
|
||||||
|
echo '::add-path::${{ github.workspace }}'"/external/mingw$arch/bin"
|
||||||
|
echo '::add-path::${{ github.workspace }}'"/external/dlls"
|
||||||
|
- name: Setup environment
|
||||||
|
shell: bash
|
||||||
|
run: echo '::add-path::${{ github.workspace }}/nim/bin'
|
||||||
|
|
||||||
|
- name: Get latest Nim commit hash
|
||||||
|
id: versions
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
getHash() {
|
||||||
|
git ls-remote "https://github.com/$1" "${2:-HEAD}" | cut -f 1
|
||||||
|
}
|
||||||
|
nimHash=$(getHash nim-lang/Nim '${{ matrix.branch }}')
|
||||||
|
csourcesHash=$(getHash nim-lang/csources)
|
||||||
|
echo "::set-output name=nim::$nimHash"
|
||||||
|
echo "::set-output name=csources::$csourcesHash"
|
||||||
|
- name: Restore prebuilt Nim from cache
|
||||||
|
id: nim-cache
|
||||||
|
uses: actions/cache@v1
|
||||||
|
with:
|
||||||
|
path: nim
|
||||||
|
key: 'nim-${{ matrix.target.os }}-${{ matrix.target.cpu }}-${{ steps.versions.outputs.nim }}'
|
||||||
|
|
||||||
|
- name: Restore prebuilt csources from cache
|
||||||
|
if: steps.nim-cache.outputs.cache-hit != 'true'
|
||||||
|
id: csources-cache
|
||||||
|
uses: actions/cache@v1
|
||||||
|
with:
|
||||||
|
path: csources/bin
|
||||||
|
key: 'csources-${{ matrix.target.os }}-${{ matrix.target.cpu }}-${{ steps.versions.outputs.csources }}'
|
||||||
|
|
||||||
|
- name: Checkout Nim csources
|
||||||
|
if: >
|
||||||
|
steps.csources-cache.outputs.cache-hit != 'true' &&
|
||||||
|
steps.nim-cache.outputs.cache-hit != 'true'
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
repository: nim-lang/csources
|
||||||
|
path: csources
|
||||||
|
ref: ${{ steps.versions.outputs.csources }}
|
||||||
|
|
||||||
|
- name: Checkout Nim
|
||||||
|
if: steps.nim-cache.outputs.cache-hit != 'true'
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
repository: nim-lang/Nim
|
||||||
|
path: nim
|
||||||
|
ref: ${{ steps.versions.outputs.nim }}
|
||||||
|
|
||||||
|
- name: Build Nim and associated tools
|
||||||
|
if: steps.nim-cache.outputs.cache-hit != 'true'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
ncpu=
|
||||||
|
ext=
|
||||||
|
case '${{ runner.os }}' in
|
||||||
|
'Linux')
|
||||||
|
ncpu=$(nproc)
|
||||||
|
;;
|
||||||
|
'macOS')
|
||||||
|
ncpu=$(sysctl -n hw.ncpu)
|
||||||
|
;;
|
||||||
|
'Windows')
|
||||||
|
ncpu=$NUMBER_OF_PROCESSORS
|
||||||
|
ext=.exe
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
[[ -z "$ncpu" || $ncpu -le 0 ]] && ncpu=1
|
||||||
|
if [[ ! -e csources/bin/nim$ext ]]; then
|
||||||
|
make -C csources -j $ncpu CC=gcc ucpu='${{ matrix.target.cpu }}'
|
||||||
|
else
|
||||||
|
echo 'Using prebuilt csources'
|
||||||
|
fi
|
||||||
|
cp -v csources/bin/nim$ext nim/bin
|
||||||
|
cd nim
|
||||||
|
nim c koch
|
||||||
|
./koch boot -d:release
|
||||||
|
./koch tools -d:release
|
||||||
|
# clean up to save cache space
|
||||||
|
rm koch
|
||||||
|
rm -rf nimcache
|
||||||
|
rm -rf dist
|
||||||
|
rm -rf .git
|
||||||
|
- name: Install test dependencies
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
nimble refresh
|
||||||
|
nimble install -y gmp stew
|
||||||
|
- name: Run constantine tests (without GMP)
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
cd constantine
|
||||||
|
nimble test_no_gmp
|
|
@ -3,7 +3,8 @@
|
||||||
[![License: Apache](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
|
[![License: Apache](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
|
||||||
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
|
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
|
||||||
![Stability: experimental](https://img.shields.io/badge/stability-experimental-orange.svg)\
|
![Stability: experimental](https://img.shields.io/badge/stability-experimental-orange.svg)\
|
||||||
[![Build Status: Travis](https://img.shields.io/travis/com/mratsim/constantine/master?label=Travis%20%28Linux%20x86_64%2FARM64,%20MacOS%20x86_64%29)](https://travis-ci.com/mratsim/constantine)
|
![Github Actions CI](https://github.com/mratsim/constantine/workflows/Constantine%20CI/badge.svg)\
|
||||||
|
[![Build Status: Travis](https://img.shields.io/travis/com/mratsim/constantine/master?label=Travis%20%28Linux%20x86_64%2FARM64,%20MacOS%20x86_64%29)](https://travis-ci.com/mratsim/constantine)\
|
||||||
[![Build Status: Azure](https://img.shields.io/azure-devops/build/numforge/07a2a7a5-995a-45d3-acd5-f5456fe7b04d/4?label=Azure%20%28Linux%2064-bit%2C%20Windows%2032%2F64-bit%2C%20MacOS%2064-bit%29)](https://dev.azure.com/numforge/Constantine/_build?definitionId=4&branchName=master)
|
[![Build Status: Azure](https://img.shields.io/azure-devops/build/numforge/07a2a7a5-995a-45d3-acd5-f5456fe7b04d/4?label=Azure%20%28Linux%2064-bit%2C%20Windows%2032%2F64-bit%2C%20MacOS%2064-bit%29)](https://dev.azure.com/numforge/Constantine/_build?definitionId=4&branchName=master)
|
||||||
|
|
||||||
This library provides constant-time implementation of elliptic curve cryptography.
|
This library provides constant-time implementation of elliptic curve cryptography.
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0).
|
# * 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.
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||||
|
|
||||||
when defined(i386) or defined(amd64):
|
when defined(amd64): # TODO defined(i386) but it seems lie RDTSC call is misconfigured
|
||||||
import platforms/x86
|
import platforms/x86
|
||||||
export getTicks, cpuName
|
export getTicks, cpuName
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,12 @@ const testDesc: seq[tuple[path: string, useGMP: bool]] = @[
|
||||||
("tests/t_ec_sage_bls12_381.nim", false)
|
("tests/t_ec_sage_bls12_381.nim", false)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# For temporary (hopefully) investigation that can only be reproduced in CI
|
||||||
|
const useDebug = [
|
||||||
|
"tests/t_bigints.nim"
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
# Helper functions
|
# Helper functions
|
||||||
# ----------------------------------------------------------------
|
# ----------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -109,10 +115,16 @@ task test, "Run all tests":
|
||||||
# -d:testingCurves is configured in a *.nim.cfg for convenience
|
# -d:testingCurves is configured in a *.nim.cfg for convenience
|
||||||
|
|
||||||
for td in testDesc:
|
for td in testDesc:
|
||||||
|
if td.path in useDebug:
|
||||||
|
test "-d:debugConstantine", td.path
|
||||||
|
else:
|
||||||
test "", td.path
|
test "", td.path
|
||||||
|
|
||||||
if sizeof(int) == 8: # 32-bit tests on 64-bit arch
|
if sizeof(int) == 8: # 32-bit tests on 64-bit arch
|
||||||
for td in testDesc:
|
for td in testDesc:
|
||||||
|
if td.path in useDebug:
|
||||||
|
test "-d:Constantine32 -d:debugConstantine", td.path
|
||||||
|
else:
|
||||||
test "-d:Constantine32", td.path
|
test "-d:Constantine32", td.path
|
||||||
|
|
||||||
# Benchmarks compile and run
|
# Benchmarks compile and run
|
||||||
|
@ -130,13 +142,20 @@ task test_no_gmp, "Run tests that don't require GMP":
|
||||||
# -d:testingCurves is configured in a *.nim.cfg for convenience
|
# -d:testingCurves is configured in a *.nim.cfg for convenience
|
||||||
for td in testDesc:
|
for td in testDesc:
|
||||||
if not td.useGMP:
|
if not td.useGMP:
|
||||||
|
if td.path in useDebug:
|
||||||
|
test "-d:debugConstantine", td.path
|
||||||
|
else:
|
||||||
test "", td.path
|
test "", td.path
|
||||||
|
|
||||||
if sizeof(int) == 8: # 32-bit tests on 64-bit arch
|
if sizeof(int) == 8: # 32-bit tests on 64-bit arch
|
||||||
for td in testDesc:
|
for td in testDesc:
|
||||||
if not td.useGMP:
|
if not td.useGMP:
|
||||||
|
if td.path in useDebug:
|
||||||
|
test "-d:Constantine32 -d:debugConstantine", td.path
|
||||||
|
else:
|
||||||
test "-d:Constantine32", td.path
|
test "-d:Constantine32", td.path
|
||||||
|
|
||||||
|
|
||||||
# Benchmarks compile and run
|
# Benchmarks compile and run
|
||||||
# ignore Windows 32-bit for the moment
|
# ignore Windows 32-bit for the moment
|
||||||
# Ensure benchmarks stay relevant. Ignore Windows 32-bit at the moment
|
# Ensure benchmarks stay relevant. Ignore Windows 32-bit at the moment
|
||||||
|
@ -154,6 +173,9 @@ task test_parallel, "Run all tests in parallel (via GNU parallel)":
|
||||||
exec "> " & buildParallel
|
exec "> " & buildParallel
|
||||||
|
|
||||||
for td in testDesc:
|
for td in testDesc:
|
||||||
|
if td.path in useDebug:
|
||||||
|
test "-d:debugConstantine", td.path, cmdFile
|
||||||
|
else:
|
||||||
test "", td.path, cmdFile
|
test "", td.path, cmdFile
|
||||||
|
|
||||||
# cmdFile.close()
|
# cmdFile.close()
|
||||||
|
@ -163,6 +185,9 @@ task test_parallel, "Run all tests in parallel (via GNU parallel)":
|
||||||
exec "> " & buildParallel
|
exec "> " & buildParallel
|
||||||
if sizeof(int) == 8: # 32-bit tests on 64-bit arch
|
if sizeof(int) == 8: # 32-bit tests on 64-bit arch
|
||||||
for td in testDesc:
|
for td in testDesc:
|
||||||
|
if td.path in useDebug:
|
||||||
|
test "-d:Constantine32 -d:debugConstantine", td.path, cmdFile
|
||||||
|
else:
|
||||||
test "-d:Constantine32", td.path, cmdFile
|
test "-d:Constantine32", td.path, cmdFile
|
||||||
# cmdFile.close()
|
# cmdFile.close()
|
||||||
# Execute everything in parallel with GNU parallel
|
# Execute everything in parallel with GNU parallel
|
||||||
|
|
|
@ -143,7 +143,7 @@ func steinsGCD*(v: var Limbs, a: Limbs, F, M: Limbs, bits: int, mp1div2: Limbs)
|
||||||
# GCD exist (always true if a and M are relatively prime)
|
# GCD exist (always true if a and M are relatively prime)
|
||||||
doAssert bool b.isOne() or
|
doAssert bool b.isOne() or
|
||||||
# or not (on prime fields iff input was zero) and no GCD fallback output is zero
|
# or not (on prime fields iff input was zero) and no GCD fallback output is zero
|
||||||
(a.isZero() and v.isZero())
|
v.isZero()
|
||||||
|
|
||||||
# ############################################################
|
# ############################################################
|
||||||
#
|
#
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
# 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
|
||||||
|
../../constantine/arithmetic/bigints,
|
||||||
|
../../constantine/config/[common, curves],
|
||||||
|
../../constantine/elliptic/[ec_weierstrass_affine, ec_weierstrass_projective]
|
||||||
|
|
||||||
|
# Canaries
|
||||||
|
# --------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# This file initializes a type with canary
|
||||||
|
# to detect initialization bugs that are silent
|
||||||
|
# when initialized from zero.
|
||||||
|
|
||||||
|
when sizeof(SecretWord) == 8:
|
||||||
|
const Canary = SecretWord(0xAAFACADEAAFACADE'u64)
|
||||||
|
else:
|
||||||
|
const Canary = SecretWord(0xAAFACADE'u32)
|
||||||
|
|
||||||
|
func canary*(T: typedesc): T =
|
||||||
|
when T is BigInt:
|
||||||
|
for i in 0 ..< result.limbs.len:
|
||||||
|
result.limbs[0] = Canary
|
||||||
|
else:
|
||||||
|
{.error: "Not implemented".}
|
|
@ -6,11 +6,16 @@
|
||||||
# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0).
|
# * 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.
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||||
|
|
||||||
import std/unittest,
|
import
|
||||||
|
# Standard library
|
||||||
|
std/unittest,
|
||||||
|
# Internal
|
||||||
../constantine/io/io_bigints,
|
../constantine/io/io_bigints,
|
||||||
../constantine/arithmetic,
|
../constantine/arithmetic,
|
||||||
../constantine/config/common,
|
../constantine/config/[common, type_bigint],
|
||||||
../constantine/primitives
|
../constantine/primitives,
|
||||||
|
# Test utilities,
|
||||||
|
support/canaries
|
||||||
|
|
||||||
echo "\n------------------------------------------------------\n"
|
echo "\n------------------------------------------------------\n"
|
||||||
|
|
||||||
|
@ -143,7 +148,7 @@ proc mainArith() =
|
||||||
suite "Multi-precision multiplication" & " [" & $WordBitwidth & "-bit mode]":
|
suite "Multi-precision multiplication" & " [" & $WordBitwidth & "-bit mode]":
|
||||||
test "Same size operand into double size result":
|
test "Same size operand into double size result":
|
||||||
block:
|
block:
|
||||||
var r: BigInt[256]
|
var r = canary(BigInt[256])
|
||||||
let a = BigInt[128].fromHex"0x12345678_FF11FFAA_00321321_CAFECAFE"
|
let a = BigInt[128].fromHex"0x12345678_FF11FFAA_00321321_CAFECAFE"
|
||||||
let b = BigInt[128].fromHex"0xDEADBEEF_DEADBEEF_DEADBEEF_DEADBEEF"
|
let b = BigInt[128].fromHex"0xDEADBEEF_DEADBEEF_DEADBEEF_DEADBEEF"
|
||||||
|
|
||||||
|
@ -156,7 +161,7 @@ proc mainArith() =
|
||||||
|
|
||||||
test "Different size into large result":
|
test "Different size into large result":
|
||||||
block:
|
block:
|
||||||
var r: BigInt[200]
|
var r = canary(BigInt[200])
|
||||||
let a = BigInt[29].fromHex"0x12345678"
|
let a = BigInt[29].fromHex"0x12345678"
|
||||||
let b = BigInt[128].fromHex"0xDEADBEEF_DEADBEEF_DEADBEEF_DEADBEEF"
|
let b = BigInt[128].fromHex"0xDEADBEEF_DEADBEEF_DEADBEEF_DEADBEEF"
|
||||||
|
|
||||||
|
@ -183,7 +188,7 @@ proc mainArith() =
|
||||||
suite "Multi-precision multiplication keeping only high words" & " [" & $WordBitwidth & "-bit mode]":
|
suite "Multi-precision multiplication keeping only high words" & " [" & $WordBitwidth & "-bit mode]":
|
||||||
test "Same size operand into double size result - discard first word":
|
test "Same size operand into double size result - discard first word":
|
||||||
block:
|
block:
|
||||||
var r: BigInt[256]
|
var r = canary(BigInt[256])
|
||||||
let a = BigInt[128].fromHex"0x12345678_FF11FFAA_00321321_CAFECAFE"
|
let a = BigInt[128].fromHex"0x12345678_FF11FFAA_00321321_CAFECAFE"
|
||||||
let b = BigInt[128].fromHex"0xDEADBEEF_DEADBEEF_DEADBEEF_DEADBEEF"
|
let b = BigInt[128].fromHex"0xDEADBEEF_DEADBEEF_DEADBEEF_DEADBEEF"
|
||||||
|
|
||||||
|
@ -199,7 +204,7 @@ proc mainArith() =
|
||||||
|
|
||||||
test "Same size operand into double size result - discard first 3 words":
|
test "Same size operand into double size result - discard first 3 words":
|
||||||
block:
|
block:
|
||||||
var r: BigInt[256]
|
var r = canary(BigInt[256])
|
||||||
let a = BigInt[128].fromHex"0x12345678_FF11FFAA_00321321_CAFECAFE"
|
let a = BigInt[128].fromHex"0x12345678_FF11FFAA_00321321_CAFECAFE"
|
||||||
let b = BigInt[128].fromHex"0xDEADBEEF_DEADBEEF_DEADBEEF_DEADBEEF"
|
let b = BigInt[128].fromHex"0xDEADBEEF_DEADBEEF_DEADBEEF_DEADBEEF"
|
||||||
|
|
||||||
|
@ -215,7 +220,7 @@ proc mainArith() =
|
||||||
|
|
||||||
test "All lower words trigger a carry":
|
test "All lower words trigger a carry":
|
||||||
block:
|
block:
|
||||||
var r: BigInt[256]
|
var r = canary(BigInt[256])
|
||||||
let a = BigInt[256].fromHex"0xFFFFF000_FFFFF111_FFFFFFFA_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF"
|
let a = BigInt[256].fromHex"0xFFFFF000_FFFFF111_FFFFFFFA_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF"
|
||||||
let b = BigInt[256].fromHex"0xFFFFFFFF_FFFFF222_FFFFFFFB_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF"
|
let b = BigInt[256].fromHex"0xFFFFFFFF_FFFFF222_FFFFFFFB_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF"
|
||||||
|
|
||||||
|
@ -235,7 +240,7 @@ proc mainArith() =
|
||||||
|
|
||||||
test "Different size into large result":
|
test "Different size into large result":
|
||||||
block:
|
block:
|
||||||
var r: BigInt[200]
|
var r = canary(BigInt[200])
|
||||||
let a = BigInt[29].fromHex"0x12345678"
|
let a = BigInt[29].fromHex"0x12345678"
|
||||||
let b = BigInt[128].fromHex"0xDEADBEEF_DEADBEEF_DEADBEEF_DEADBEEF"
|
let b = BigInt[128].fromHex"0xDEADBEEF_DEADBEEF_DEADBEEF_DEADBEEF"
|
||||||
|
|
||||||
|
@ -273,46 +278,56 @@ proc mainArith() =
|
||||||
let a = BigInt[7].fromUint(100'u32)
|
let a = BigInt[7].fromUint(100'u32)
|
||||||
let m = BigInt[4].fromUint(13'u8)
|
let m = BigInt[4].fromUint(13'u8)
|
||||||
|
|
||||||
var r: BigInt[4]
|
var r = canary(BigInt[4])
|
||||||
r.reduce(a, m)
|
r.reduce(a, m)
|
||||||
check:
|
let expected = BigInt[4].fromUint(100'u8 mod 13)
|
||||||
bool(r == BigInt[4].fromUint(100'u8 mod 13))
|
doAssert bool(r == expected),
|
||||||
|
"\n r (low-level repr): " & $r &
|
||||||
|
"\n expected (ll repr): " & $expected
|
||||||
|
|
||||||
block: #
|
block: #
|
||||||
let a = BigInt[32].fromUint(100'u32)
|
let a = BigInt[32].fromUint(100'u32)
|
||||||
let m = BigInt[4].fromUint(13'u8)
|
let m = BigInt[4].fromUint(13'u8)
|
||||||
|
|
||||||
var r: BigInt[4]
|
var r = canary(BigInt[4])
|
||||||
r.reduce(a, m)
|
r.reduce(a, m)
|
||||||
check:
|
let expected = BigInt[4].fromUint(100'u8 mod 13)
|
||||||
bool(r == BigInt[4].fromUint(100'u8 mod 13))
|
doAssert bool(r == expected),
|
||||||
|
"\n r (low-level repr): " & $r &
|
||||||
|
"\n expected (ll repr): " & $expected
|
||||||
|
|
||||||
block: #
|
block: #
|
||||||
let a = BigInt[64].fromUint(100'u32)
|
let a = BigInt[64].fromUint(100'u32)
|
||||||
let m = BigInt[4].fromUint(13'u8)
|
let m = BigInt[4].fromUint(13'u8)
|
||||||
|
|
||||||
var r: BigInt[4]
|
var r = canary(BigInt[4])
|
||||||
r.reduce(a, m)
|
r.reduce(a, m)
|
||||||
check:
|
let expected = BigInt[4].fromUint(100'u8 mod 13)
|
||||||
bool(r == BigInt[4].fromUint(100'u8 mod 13))
|
doAssert bool(r == expected),
|
||||||
|
"\n r (low-level repr): " & $r &
|
||||||
|
"\n expected (ll repr): " & $expected
|
||||||
|
|
||||||
test "2^64 mod 3":
|
test "2^64 mod 3":
|
||||||
let a = BigInt[65].fromHex("0x1_00000000_00000000")
|
let a = BigInt[65].fromHex("0x1_00000000_00000000")
|
||||||
let m = BigInt[8].fromUint(3'u8)
|
let m = BigInt[8].fromUint(3'u8)
|
||||||
|
|
||||||
var r: BigInt[8]
|
var r = canary(BigInt[8])
|
||||||
r.reduce(a, m)
|
r.reduce(a, m)
|
||||||
check:
|
let expected = BigInt[8].fromUint(1'u8)
|
||||||
bool(r == BigInt[8].fromUint(1'u8))
|
doAssert bool(r == expected),
|
||||||
|
"\n r (low-level repr): " & $r &
|
||||||
|
"\n expected (ll repr): " & $expected
|
||||||
|
|
||||||
test "1234567891234567890 mod 10":
|
test "1234567891234567890 mod 10":
|
||||||
let a = BigInt[64].fromUint(1234567891234567890'u64)
|
let a = BigInt[64].fromUint(1234567891234567890'u64)
|
||||||
let m = BigInt[8].fromUint(10'u8)
|
let m = BigInt[8].fromUint(10'u8)
|
||||||
|
|
||||||
var r: BigInt[8]
|
var r = canary(BigInt[8])
|
||||||
r.reduce(a, m)
|
r.reduce(a, m)
|
||||||
check:
|
let expected = BigInt[8].fromUint(0'u8)
|
||||||
bool(r == BigInt[8].fromUint(0'u8))
|
doAssert bool(r == expected),
|
||||||
|
"\n r (low-level repr): " & $r &
|
||||||
|
"\n expected (ll repr): " & $expected
|
||||||
|
|
||||||
suite "Modular operations - small modulus - Stint specific failures highlighted by property-based testing" & " [" & $WordBitwidth & "-bit mode]":
|
suite "Modular operations - small modulus - Stint specific failures highlighted by property-based testing" & " [" & $WordBitwidth & "-bit mode]":
|
||||||
# Vectors taken from Stint - https://github.com/status-im/nim-stint
|
# Vectors taken from Stint - https://github.com/status-im/nim-stint
|
||||||
|
@ -323,11 +338,13 @@ proc mainArith() =
|
||||||
let a = BigInt[56].fromUint(u)
|
let a = BigInt[56].fromUint(u)
|
||||||
let m = BigInt[48].fromUint(v)
|
let m = BigInt[48].fromUint(v)
|
||||||
|
|
||||||
var r: BigInt[48]
|
var r = canary(BigInt[48])
|
||||||
r.reduce(a, m)
|
r.reduce(a, m)
|
||||||
|
|
||||||
check:
|
let expected = BigInt[48].fromUint(u mod v)
|
||||||
bool(r == BigInt[48].fromUint(u mod v))
|
doAssert bool(r == expected),
|
||||||
|
"\n r (low-level repr): " & $r &
|
||||||
|
"\n expected (ll repr): " & $expected
|
||||||
|
|
||||||
test "Modulo: 15080397990160655 mod 600432699691":
|
test "Modulo: 15080397990160655 mod 600432699691":
|
||||||
let u = 15080397990160655'u64
|
let u = 15080397990160655'u64
|
||||||
|
@ -336,11 +353,13 @@ proc mainArith() =
|
||||||
let a = BigInt[54].fromUint(u)
|
let a = BigInt[54].fromUint(u)
|
||||||
let m = BigInt[40].fromUint(v)
|
let m = BigInt[40].fromUint(v)
|
||||||
|
|
||||||
var r: BigInt[40]
|
var r = canary(BigInt[40])
|
||||||
r.reduce(a, m)
|
r.reduce(a, m)
|
||||||
|
|
||||||
check:
|
let expected = BigInt[40].fromUint(u mod v)
|
||||||
bool(r == BigInt[40].fromUint(u mod v))
|
doAssert bool(r == expected),
|
||||||
|
"\n r (low-level repr): " & $r &
|
||||||
|
"\n expected (ll repr): " & $expected
|
||||||
|
|
||||||
proc mainNeg() =
|
proc mainNeg() =
|
||||||
suite "Conditional negation" & " [" & $WordBitwidth & "-bit mode]":
|
suite "Conditional negation" & " [" & $WordBitwidth & "-bit mode]":
|
||||||
|
@ -501,7 +520,7 @@ proc mainModularInverse() =
|
||||||
mp1div2.shiftRight(1)
|
mp1div2.shiftRight(1)
|
||||||
|
|
||||||
let expected = BigInt[16].fromUint(1969'u16)
|
let expected = BigInt[16].fromUint(1969'u16)
|
||||||
var r {.noInit.}: BigInt[16]
|
var r = canary(BigInt[16])
|
||||||
|
|
||||||
r.invmod(a, M, mp1div2)
|
r.invmod(a, M, mp1div2)
|
||||||
|
|
||||||
|
@ -516,7 +535,7 @@ proc mainModularInverse() =
|
||||||
mp1div2.shiftRight(1)
|
mp1div2.shiftRight(1)
|
||||||
|
|
||||||
let expected = BigInt[381].fromUint(1969'u16)
|
let expected = BigInt[381].fromUint(1969'u16)
|
||||||
var r {.noInit.}: BigInt[381]
|
var r = canary(BigInt[381])
|
||||||
|
|
||||||
r.invmod(a, M, mp1div2)
|
r.invmod(a, M, mp1div2)
|
||||||
|
|
||||||
|
@ -532,7 +551,7 @@ proc mainModularInverse() =
|
||||||
mp1div2.shiftRight(1)
|
mp1div2.shiftRight(1)
|
||||||
|
|
||||||
let expected = BigInt[16].fromUint(106'u16)
|
let expected = BigInt[16].fromUint(106'u16)
|
||||||
var r {.noInit.}: BigInt[16]
|
var r = canary(BigInt[16])
|
||||||
|
|
||||||
r.invmod(a, M, mp1div2)
|
r.invmod(a, M, mp1div2)
|
||||||
|
|
||||||
|
@ -547,7 +566,7 @@ proc mainModularInverse() =
|
||||||
mp1div2.shiftRight(1)
|
mp1div2.shiftRight(1)
|
||||||
|
|
||||||
let expected = BigInt[381].fromUint(106'u16)
|
let expected = BigInt[381].fromUint(106'u16)
|
||||||
var r {.noInit.}: BigInt[381]
|
var r = canary(BigInt[381])
|
||||||
|
|
||||||
r.invmod(a, M, mp1div2)
|
r.invmod(a, M, mp1div2)
|
||||||
|
|
||||||
|
@ -563,7 +582,7 @@ proc mainModularInverse() =
|
||||||
|
|
||||||
let expected = BigInt[381].fromHex("0x0636759a0f3034fa47174b2c0334902f11e9915b7bd89c6a2b3082b109abbc9837da17201f6d8286fe6203caa1b9d4c8")
|
let expected = BigInt[381].fromHex("0x0636759a0f3034fa47174b2c0334902f11e9915b7bd89c6a2b3082b109abbc9837da17201f6d8286fe6203caa1b9d4c8")
|
||||||
|
|
||||||
var r {.noInit.}: BigInt[381]
|
var r = canary(BigInt[381])
|
||||||
r.invmod(a, M, mp1div2)
|
r.invmod(a, M, mp1div2)
|
||||||
|
|
||||||
check: bool(r == expected)
|
check: bool(r == expected)
|
||||||
|
@ -578,7 +597,7 @@ proc mainModularInverse() =
|
||||||
discard mp1div2.add(SecretWord 1)
|
discard mp1div2.add(SecretWord 1)
|
||||||
|
|
||||||
let expected = BigInt[16].fromUint(0'u16)
|
let expected = BigInt[16].fromUint(0'u16)
|
||||||
var r {.noInit.}: BigInt[16]
|
var r = canary(BigInt[16])
|
||||||
|
|
||||||
r.invmod(a, M, mp1div2)
|
r.invmod(a, M, mp1div2)
|
||||||
|
|
||||||
|
@ -593,7 +612,7 @@ proc mainModularInverse() =
|
||||||
discard mp1div2.add(SecretWord 1)
|
discard mp1div2.add(SecretWord 1)
|
||||||
|
|
||||||
let expected = BigInt[381].fromUint(0'u16)
|
let expected = BigInt[381].fromUint(0'u16)
|
||||||
var r {.noInit.}: BigInt[381]
|
var r = canary(BigInt[381])
|
||||||
|
|
||||||
r.invmod(a, M, mp1div2)
|
r.invmod(a, M, mp1div2)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue