Remove dependency on number theory (not on Nimble) & prepare for tests

This commit is contained in:
mratsim 2018-02-19 15:17:41 +01:00
parent b62d9e0883
commit d830f6993f
3 changed files with 90 additions and 3 deletions

View File

@ -7,4 +7,17 @@ srcDir = "src"
### Dependencies
requires "nim >= 0.17.2", "number_theory"
requires "nim >= 0.17.2", "number_theory", "keccak_tiny >= 0.1.0"
proc test(name: string, lang: string = "cpp") =
if not dirExists "build":
mkDir "build"
if not dirExists "nimcache":
mkDir "nimcache"
--run
--nimcache: "nimcache"
switch("out", ("./build/" & name))
setCommand lang, "tests/" & name & ".nim"
task test, "Run all tests":
test "all_tests"

View File

@ -2,10 +2,9 @@
# Distributed under the Apache v2 License (license terms are at http://www.apache.org/licenses/LICENSE-2.0).
import math, sequtils,
number_theory, # Not on nimble yet: https://github.com/numforge/number-theory
keccak_tiny
import ./private/[primes, casting, functional]
import ./private/[primes, casting, functional, intmath]
export toHex, hexToSeqBytesBE
# TODO: Switching from default int to uint64

75
src/private/intmath.nim Normal file
View File

@ -0,0 +1,75 @@
# From https://github.com/numforge/number-theory/
# MIT Licence
# Copyright (c) 2016 Mamy Ratsimbazafy
proc isOdd*[T: SomeInteger](i: T): bool {.inline, noSideEffect.} =
(i and 1.T) != 0
# ############
type
ldiv_t {.bycopy, importc: "ldiv_t", header:"<stdlib.h>".} = object
quot: clong ## quotient
rem: clong ## remainder
lldiv_t {.bycopy, importc: "lldiv_t", header:"<stdlib.h>".} = object
quot: clonglong
rem: clonglong
proc ldiv(a, b: clong): ldiv_t {.importc: "ldiv", header: "<stdlib.h>".}
proc lldiv(a, b: clonglong): lldiv_t {.importc: "lldiv", header: "<stdlib.h>".}
proc divmod*(a, b: int32): tuple[quot, rem: clong] {.inline.}=
## Compute quotient and reminder of integer division in a single intrinsics operation
# TODO: changing clong to int32 poses an issue for some reason
cast[type result](ldiv(a,b))
proc divmod*(a, b: int64): tuple[quot, rem: int64] {.inline.}=
## Compute quotient and reminder of integer division in a single intrinsicsoperation
cast[type result](lldiv(a,b))
proc divmod*[T: SomeUnsignedInt](a, b: T): tuple[quot, rem: T] {.inline.}=
# There is no single instruction for unsigned ints
# Hopefully the compiler does its work properly
(a div b, a mod b)
# ############
proc addmod*[T: SomeInteger](a, b, m: T): T =
## Modular addition
let a_m = if a < m: a
else: a mod m
if b == 0.T:
return a_m
let b_m = if b < m: b
else: b mod m
# We don't do a + b to avoid overflows
# But we know that m at least is inferior to biggest T
let b_from_m = m - b_m
if a_m >= b_from_m:
return a_m - b_from_m
return m - b_from_m + a_m
proc doublemod[T: SomeInteger](a, m: T): T {.inline.}=
## double a modulo m. assume a < m
result = a
if a >= m - a:
result -= m
result += a
proc mulmod*[T: SomeInteger](a, b, m: T): T =
## Modular multiplication
var a_m = a mod m
var b_m = b mod m
if b_m > a_m:
swap(a_m, b_m)
while b_m > 0.T:
if b_m.isOdd:
result = addmod(result, a_m, m)
a_m = doublemod(a_m, m)
b_m = b_m shr 1