mirror of
https://github.com/logos-storage/constantine.git
synced 2026-01-02 13:13:07 +00:00
32-bit fixes (#288)
* fix the new div2n1n_vartime on 32-bit - regression from #286 * remove unnecessary defensive programming * reactivate 32-bit CI to check on #244 * 32-bit: centralize OS, ISA and env variable config * enable assemble on x86 32-bit
This commit is contained in:
parent
07f96ec259
commit
c3b76cd420
18
.github/workflows/ci.yml
vendored
18
.github/workflows/ci.yml
vendored
@ -9,21 +9,24 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
nim_version: [version-1-6] # [version-1-4, devel]
|
nim_version: [version-1-6] # [version-1-4, devel]
|
||||||
target:
|
target:
|
||||||
|
- os: linux
|
||||||
|
cpu: i386
|
||||||
|
TEST_LANG: c
|
||||||
|
BACKEND: NO_ASM
|
||||||
|
- os: linux
|
||||||
|
cpu: i386
|
||||||
|
TEST_LANG: c
|
||||||
|
BACKEND: ASM
|
||||||
|
|
||||||
- os: linux
|
- os: linux
|
||||||
cpu: amd64
|
cpu: amd64
|
||||||
TEST_LANG: c
|
TEST_LANG: c
|
||||||
BACKEND: NO_ASM
|
BACKEND: NO_ASM
|
||||||
|
|
||||||
# 32-bit CI failing with https://github.com/mratsim/constantine/issues/244
|
|
||||||
# "E: Unable to correct problems, you have held broken packages.""
|
|
||||||
# - os: linux
|
|
||||||
# cpu: i386
|
|
||||||
# TEST_LANG: c
|
|
||||||
# BACKEND: NO_ASM
|
|
||||||
- os: linux
|
- os: linux
|
||||||
cpu: amd64
|
cpu: amd64
|
||||||
TEST_LANG: c
|
TEST_LANG: c
|
||||||
BACKEND: ASM
|
BACKEND: ASM
|
||||||
|
|
||||||
- os: windows
|
- os: windows
|
||||||
cpu: amd64
|
cpu: amd64
|
||||||
TEST_LANG: c
|
TEST_LANG: c
|
||||||
@ -32,6 +35,7 @@ jobs:
|
|||||||
cpu: amd64
|
cpu: amd64
|
||||||
TEST_LANG: c
|
TEST_LANG: c
|
||||||
BACKEND: ASM
|
BACKEND: ASM
|
||||||
|
|
||||||
- os: macos
|
- os: macos
|
||||||
cpu: amd64
|
cpu: amd64
|
||||||
TEST_LANG: c
|
TEST_LANG: c
|
||||||
|
|||||||
@ -60,7 +60,7 @@ echo " release: ", defined(release)
|
|||||||
echo " danger: ", defined(danger)
|
echo " danger: ", defined(danger)
|
||||||
echo " inline assembly: ", UseASM_X86_64
|
echo " inline assembly: ", UseASM_X86_64
|
||||||
|
|
||||||
when (sizeof(int) == 4) or defined(CTT_32):
|
when CTT_32:
|
||||||
echo "⚠️ Warning: using Constantine with 32-bit limbs"
|
echo "⚠️ Warning: using Constantine with 32-bit limbs"
|
||||||
else:
|
else:
|
||||||
echo "Using Constantine with 64-bit limbs"
|
echo "Using Constantine with 64-bit limbs"
|
||||||
|
|||||||
@ -7,7 +7,8 @@ import
|
|||||||
|
|
||||||
proc report(op: string, elapsedNs: int64, elapsedCycles: int64, iters: int) =
|
proc report(op: string, elapsedNs: int64, elapsedCycles: int64, iters: int) =
|
||||||
let ns = elapsedNs div iters
|
let ns = elapsedNs div iters
|
||||||
let cycles = elapsedCycles div iters
|
when SupportsGetTicks:
|
||||||
|
let cycles = elapsedCycles div iters
|
||||||
let throughput = 1e9 / float64(ns)
|
let throughput = 1e9 / float64(ns)
|
||||||
when SupportsGetTicks:
|
when SupportsGetTicks:
|
||||||
echo &"{op:<70} {throughput:>15.3f} ops/s {ns:>16} ns/op {cycles:>12} CPU cycles (approx)"
|
echo &"{op:<70} {throughput:>15.3f} ops/s {ns:>16} ns/op {cycles:>12} CPU cycles (approx)"
|
||||||
@ -17,12 +18,15 @@ proc report(op: string, elapsedNs: int64, elapsedCycles: int64, iters: int) =
|
|||||||
template bench(fnCall: untyped, ticks, ns: var int64): untyped =
|
template bench(fnCall: untyped, ticks, ns: var int64): untyped =
|
||||||
block:
|
block:
|
||||||
let startTime = getMonotime()
|
let startTime = getMonotime()
|
||||||
let startClock = getTicks()
|
when SupportsGetTicks:
|
||||||
|
let startClock = getTicks()
|
||||||
fnCall
|
fnCall
|
||||||
let stopClock = getTicks()
|
when SupportsGetTicks:
|
||||||
|
let stopClock = getTicks()
|
||||||
let stopTime = getMonotime()
|
let stopTime = getMonotime()
|
||||||
|
|
||||||
ticks += stopClock - startClock
|
when SupportsGetTicks:
|
||||||
|
ticks += stopClock - startClock
|
||||||
ns += inNanoseconds(stopTime-startTime)
|
ns += inNanoseconds(stopTime-startTime)
|
||||||
|
|
||||||
func computeGasFee(inputs: openArray[byte]): tuple[eip128, eip2565: int] =
|
func computeGasFee(inputs: openArray[byte]): tuple[eip128, eip2565: int] =
|
||||||
@ -91,8 +95,8 @@ func computeGasFee(inputs: openArray[byte]): tuple[eip128, eip2565: int] =
|
|||||||
baseStop = baseStart+baseByteLen-1
|
baseStop = baseStart+baseByteLen-1
|
||||||
expStart = baseStop+1
|
expStart = baseStop+1
|
||||||
expStop = expStart+exponentByteLen-1
|
expStop = expStart+exponentByteLen-1
|
||||||
modStart = expStop+1
|
# modStart = expStop+1
|
||||||
modStop = modStart+modulusByteLen-1
|
# modStop = modStart+modulusByteLen-1
|
||||||
|
|
||||||
template exponent(): untyped =
|
template exponent(): untyped =
|
||||||
inputs.toOpenArray(expStart, expStop)
|
inputs.toOpenArray(expStart, expStop)
|
||||||
|
|||||||
@ -61,7 +61,7 @@ echo " release: ", defined(release)
|
|||||||
echo " danger: ", defined(danger)
|
echo " danger: ", defined(danger)
|
||||||
echo " inline assembly: ", UseASM_X86_64
|
echo " inline assembly: ", UseASM_X86_64
|
||||||
|
|
||||||
when (sizeof(int) == 4) or defined(CTT_32):
|
when CTT_32:
|
||||||
echo "⚠️ Warning: using Constantine with 32-bit limbs"
|
echo "⚠️ Warning: using Constantine with 32-bit limbs"
|
||||||
else:
|
else:
|
||||||
echo "Using Constantine with 64-bit limbs"
|
echo "Using Constantine with 64-bit limbs"
|
||||||
|
|||||||
@ -433,9 +433,6 @@ func eth_evm_modexp*(r: var openArray[byte], inputs: openArray[byte]): CttEVMSta
|
|||||||
if r.len != modulusByteLen:
|
if r.len != modulusByteLen:
|
||||||
return cttEVM_InvalidOutputSize
|
return cttEVM_InvalidOutputSize
|
||||||
|
|
||||||
if baseWordLen > modulusWordLen:
|
|
||||||
return cttEVM_InvalidInputSize
|
|
||||||
|
|
||||||
# Special cases
|
# Special cases
|
||||||
# ----------------------
|
# ----------------------
|
||||||
if paddedLengths.len + baseByteLen + exponentByteLen >= inputs.len:
|
if paddedLengths.len + baseByteLen + exponentByteLen >= inputs.len:
|
||||||
|
|||||||
@ -136,7 +136,7 @@ func sum2xMod*(r: var FpDbl, a, b: FpDbl) =
|
|||||||
|
|
||||||
# Conditional reduction by 2ⁿp
|
# Conditional reduction by 2ⁿp
|
||||||
staticFor i, 0, N:
|
staticFor i, 0, N:
|
||||||
SecretBool(overflowed).ccopy(r.limbs2x[i+N], t[i])
|
overflowed.ccopy(r.limbs2x[i+N], t[i])
|
||||||
|
|
||||||
func neg2xMod*(r: var FpDbl, a: FpDbl) =
|
func neg2xMod*(r: var FpDbl, a: FpDbl) =
|
||||||
## Double-precision modular substraction
|
## Double-precision modular substraction
|
||||||
|
|||||||
@ -17,28 +17,19 @@ import ./metering/tracer
|
|||||||
|
|
||||||
export primitives, tracer
|
export primitives, tracer
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
|
|
||||||
const CTT_ASM {.booldefine.} = true
|
|
||||||
const UseASM_X86_32* = CTT_ASM and X86 and GCC_Compatible
|
|
||||||
const UseASM_X86_64* = sizeof(pointer)*8 == 64 and UseASM_X86_32
|
|
||||||
|
|
||||||
# We use Nim effect system to track vartime subroutines
|
|
||||||
type VarTime* = object
|
|
||||||
|
|
||||||
# ############################################################
|
# ############################################################
|
||||||
#
|
#
|
||||||
# Secret Words
|
# Secret Words
|
||||||
#
|
#
|
||||||
# ############################################################
|
# ############################################################
|
||||||
|
|
||||||
when sizeof(int) == 8 and not defined(CTT_32):
|
when CTT_32:
|
||||||
type
|
type
|
||||||
BaseType* = uint64
|
BaseType* = uint32
|
||||||
## Physical BigInt for conversion in "normal integers"
|
## Physical BigInt for conversion in "normal integers"
|
||||||
else:
|
else:
|
||||||
type
|
type
|
||||||
BaseType* = uint32
|
BaseType* = uint64
|
||||||
## Physical BigInt for conversion in "normal integers"
|
## Physical BigInt for conversion in "normal integers"
|
||||||
|
|
||||||
type
|
type
|
||||||
@ -131,12 +122,12 @@ debug: # Don't allow printing secret words by default
|
|||||||
|
|
||||||
type SignedSecretWord* = distinct SecretWord
|
type SignedSecretWord* = distinct SecretWord
|
||||||
|
|
||||||
when sizeof(int) == 8 and not defined(CTT_32):
|
when CTT_32:
|
||||||
type
|
|
||||||
SignedBaseType* = int64
|
|
||||||
else:
|
|
||||||
type
|
type
|
||||||
SignedBaseType* = int32
|
SignedBaseType* = int32
|
||||||
|
else:
|
||||||
|
type
|
||||||
|
SignedBaseType* = int64
|
||||||
|
|
||||||
template fmap(x: SignedSecretWord, op: untyped, y: SignedSecretWord): SignedSecretWord =
|
template fmap(x: SignedSecretWord, op: untyped, y: SignedSecretWord): SignedSecretWord =
|
||||||
## Unwrap x and y from their distinct type
|
## Unwrap x and y from their distinct type
|
||||||
|
|||||||
31
constantine/platforms/config.nim
Normal file
31
constantine/platforms/config.nim
Normal file
@ -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.
|
||||||
|
|
||||||
|
# Compiler and CPU architecture configuration
|
||||||
|
# ------------------------------------------------------------
|
||||||
|
|
||||||
|
const GCC_Compatible* = defined(gcc) or defined(clang) or defined(llvm_gcc)
|
||||||
|
const X86* = defined(amd64) or defined(i386)
|
||||||
|
|
||||||
|
when sizeof(int) == 8 and GCC_Compatible:
|
||||||
|
type
|
||||||
|
uint128*{.importc: "unsigned __int128".} = object
|
||||||
|
int128*{.importc: "__int128".} = object
|
||||||
|
|
||||||
|
# Env variable configuration
|
||||||
|
# ------------------------------------------------------------
|
||||||
|
|
||||||
|
const CTT_ASM {.booldefine.} = true
|
||||||
|
const CTT_32* {.booldefine.} = bool(sizeof(pointer)*8 == 32)
|
||||||
|
const UseASM_X86_32* = CTT_ASM and X86 and GCC_Compatible
|
||||||
|
const UseASM_X86_64* = not(CTT_32) and UseASM_X86_32
|
||||||
|
|
||||||
|
when UseASM_X86_64:
|
||||||
|
static: doAssert bool(sizeof(pointer)*8 == 64), "Only 32-bit and 64-bit platforms are supported"
|
||||||
|
|
||||||
|
const UseAsmSyntaxIntel* {.booldefine.} = true
|
||||||
@ -33,10 +33,5 @@ type
|
|||||||
Carry* = Ct[uint8] # distinct range[0'u8 .. 1]
|
Carry* = Ct[uint8] # distinct range[0'u8 .. 1]
|
||||||
Borrow* = Ct[uint8] # distinct range[0'u8 .. 1]
|
Borrow* = Ct[uint8] # distinct range[0'u8 .. 1]
|
||||||
|
|
||||||
const GCC_Compatible* = defined(gcc) or defined(clang) or defined(llvm_gcc)
|
VarTime* = object
|
||||||
const X86* = defined(amd64) or defined(i386)
|
## For use with Nim effect system to track vartime subroutines
|
||||||
|
|
||||||
when sizeof(int) == 8 and GCC_Compatible:
|
|
||||||
type
|
|
||||||
uint128*{.importc: "unsigned __int128".} = object
|
|
||||||
int128*{.importc: "__int128".} = object
|
|
||||||
|
|||||||
@ -6,8 +6,9 @@
|
|||||||
# * 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 ./ct_types
|
import
|
||||||
import ../isa/macro_assembler_x86
|
./ct_types,
|
||||||
|
../config
|
||||||
|
|
||||||
# ############################################################
|
# ############################################################
|
||||||
#
|
#
|
||||||
|
|||||||
@ -6,7 +6,9 @@
|
|||||||
# * 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 ../constant_time/ct_types
|
import
|
||||||
|
../config,
|
||||||
|
../constant_time/ct_types
|
||||||
|
|
||||||
# ############################################################
|
# ############################################################
|
||||||
#
|
#
|
||||||
|
|||||||
@ -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.
|
||||||
|
|
||||||
import ../constant_time/ct_types
|
import ../config
|
||||||
|
|
||||||
when GCC_Compatible:
|
when GCC_Compatible:
|
||||||
func builtin_clz(n: uint32): cint {.importc: "__builtin_clz", nodecl.}
|
func builtin_clz(n: uint32): cint {.importc: "__builtin_clz", nodecl.}
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
# ############################################################
|
# ############################################################
|
||||||
|
|
||||||
import
|
import
|
||||||
|
../config,
|
||||||
./addcarry_subborrow,
|
./addcarry_subborrow,
|
||||||
../constant_time/ct_types,
|
../constant_time/ct_types,
|
||||||
../constant_time/ct_routines
|
../constant_time/ct_routines
|
||||||
|
|||||||
@ -6,7 +6,9 @@
|
|||||||
# * 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 ../constant_time/ct_types
|
import
|
||||||
|
../config,
|
||||||
|
../constant_time/ct_types
|
||||||
|
|
||||||
# ############################################################
|
# ############################################################
|
||||||
#
|
#
|
||||||
@ -86,7 +88,7 @@ func smul*(hi, lo: var Ct[uint64], a, b: Ct[uint64]) {.inline.} =
|
|||||||
##
|
##
|
||||||
## Inputs are intentionally unsigned
|
## Inputs are intentionally unsigned
|
||||||
## as we use their unchecked raw representation for cryptography
|
## as we use their unchecked raw representation for cryptography
|
||||||
##
|
##
|
||||||
## This is constant-time on most hardware
|
## This is constant-time on most hardware
|
||||||
## See: https://www.bearssl.org/ctmul.html
|
## See: https://www.bearssl.org/ctmul.html
|
||||||
block:
|
block:
|
||||||
|
|||||||
@ -15,8 +15,8 @@
|
|||||||
|
|
||||||
import ../abstractions
|
import ../abstractions
|
||||||
|
|
||||||
func div2n1n_nim_vartime[T: SomeUnsignedInt](q, r: var T, n_hi, n_lo, d: T) {.tags:[VarTime].}=
|
func div2n1n_nim_vartime[T: SomeUnsignedInt](q, r: var T, n_hi, n_lo, d: T) {.used, tags:[VarTime].}=
|
||||||
## Division uint128 by uint64
|
## Division uint128 by uint64 or uint64 by uint32
|
||||||
## Warning ⚠️ :
|
## Warning ⚠️ :
|
||||||
## - if n_hi == d, quotient does not fit in an uint64 and will throw SIGFPE
|
## - if n_hi == d, quotient does not fit in an uint64 and will throw SIGFPE
|
||||||
## - if n_hi > d result is undefined
|
## - if n_hi > d result is undefined
|
||||||
@ -59,7 +59,7 @@ func div2n1n_nim_vartime[T: SomeUnsignedInt](q, r: var T, n_hi, n_lo, d: T) {.ta
|
|||||||
q = (q1 shl halfSize) or q2
|
q = (q1 shl halfSize) or q2
|
||||||
r = r2
|
r = r2
|
||||||
|
|
||||||
when sizeof(int) == 8 and defined(vcc):
|
when not(CTT_32) and defined(vcc):
|
||||||
func udiv128_vartime(highDividend, lowDividend, divisor: uint64, remainder: var uint64): uint64 {.importc:"_udiv128", header: "<intrin.h>", nodecl, tags:[VarTime].}
|
func udiv128_vartime(highDividend, lowDividend, divisor: uint64, remainder: var uint64): uint64 {.importc:"_udiv128", header: "<intrin.h>", nodecl, tags:[VarTime].}
|
||||||
## Division 128 by 64, Microsoft only, 64-bit only,
|
## Division 128 by 64, Microsoft only, 64-bit only,
|
||||||
## returns quotient as return value remainder as var parameter
|
## returns quotient as return value remainder as var parameter
|
||||||
@ -74,7 +74,7 @@ when sizeof(int) == 8 and defined(vcc):
|
|||||||
## - if n_hi > d result is undefined
|
## - if n_hi > d result is undefined
|
||||||
q = udiv128_vartime(n_hi, n_lo, d, r)
|
q = udiv128_vartime(n_hi, n_lo, d, r)
|
||||||
|
|
||||||
elif sizeof(int) == 8 and GCC_Compatible:
|
elif not(CTT_32) and GCC_Compatible:
|
||||||
type
|
type
|
||||||
uint128{.importc: "unsigned __int128".} = object
|
uint128{.importc: "unsigned __int128".} = object
|
||||||
|
|
||||||
@ -108,15 +108,16 @@ func div2n1n_vartime*(q, r: var SecretWord, n_hi, n_lo, d: SecretWord) {.inline.
|
|||||||
## To avoid issues, n_hi, n_lo, d should be normalized.
|
## To avoid issues, n_hi, n_lo, d should be normalized.
|
||||||
## i.e. shifted (== multiplied by the same power of 2)
|
## i.e. shifted (== multiplied by the same power of 2)
|
||||||
## so that the most significant bit in d is set.
|
## so that the most significant bit in d is set.
|
||||||
when sizeof(int) == 4:
|
when CTT_32:
|
||||||
let dividend = (uint64(n_hi) shl 32) or uint64(n_lo)
|
let dividend = (uint64(n_hi) shl 32) or uint64(n_lo)
|
||||||
let divisor = uint64(d)
|
let divisor = uint64(d)
|
||||||
q = uint32(dividend div divisor)
|
q = SecretWord(dividend div divisor)
|
||||||
r = uint32(dividend mod divisor)
|
r = SecretWord(dividend mod divisor)
|
||||||
when nimvm:
|
|
||||||
div2n1n_nim_vartime(BaseType q, BaseType r, BaseType n_hi, BaseType n_lo, BaseType d)
|
|
||||||
else:
|
else:
|
||||||
when declared(div2n1n_128_vartime):
|
when nimvm:
|
||||||
div2n1n_128_vartime(BaseType q, BaseType r, BaseType n_hi, BaseType n_lo, BaseType d)
|
|
||||||
else:
|
|
||||||
div2n1n_nim_vartime(BaseType q, BaseType r, BaseType n_hi, BaseType n_lo, BaseType d)
|
div2n1n_nim_vartime(BaseType q, BaseType r, BaseType n_hi, BaseType n_lo, BaseType d)
|
||||||
|
else:
|
||||||
|
when declared(div2n1n_128_vartime):
|
||||||
|
div2n1n_128_vartime(BaseType q, BaseType r, BaseType n_hi, BaseType n_lo, BaseType d)
|
||||||
|
else:
|
||||||
|
div2n1n_nim_vartime(BaseType q, BaseType r, BaseType n_hi, BaseType n_lo, BaseType d)
|
||||||
|
|||||||
@ -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.
|
||||||
|
|
||||||
const UseAsmSyntaxIntel* {.booldefine.} = true
|
import ../config
|
||||||
|
|
||||||
when UseAsmSyntaxIntel:
|
when UseAsmSyntaxIntel:
|
||||||
# We need Intel syntax.
|
# We need Intel syntax.
|
||||||
|
|||||||
@ -6,7 +6,9 @@
|
|||||||
# * 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/[macros, strutils, sets, hashes, algorithm]
|
import
|
||||||
|
std/[macros, strutils, sets, hashes, algorithm],
|
||||||
|
../config
|
||||||
|
|
||||||
# A compile-time inline assembler
|
# A compile-time inline assembler
|
||||||
|
|
||||||
@ -39,15 +41,7 @@ type
|
|||||||
# Clobbered register
|
# Clobbered register
|
||||||
ClobberedReg
|
ClobberedReg
|
||||||
|
|
||||||
when sizeof(int) == 8 and not defined(CTT_32):
|
when CTT_32:
|
||||||
type
|
|
||||||
Register* = enum
|
|
||||||
rbx
|
|
||||||
rdx
|
|
||||||
r8
|
|
||||||
rax
|
|
||||||
xmm0
|
|
||||||
else:
|
|
||||||
type
|
type
|
||||||
Register* = enum
|
Register* = enum
|
||||||
rbx = "ebx"
|
rbx = "ebx"
|
||||||
@ -55,6 +49,14 @@ else:
|
|||||||
r8 = "r8d"
|
r8 = "r8d"
|
||||||
rax = "eax"
|
rax = "eax"
|
||||||
xmm0
|
xmm0
|
||||||
|
else:
|
||||||
|
type
|
||||||
|
Register* = enum
|
||||||
|
rbx
|
||||||
|
rdx
|
||||||
|
r8
|
||||||
|
rax
|
||||||
|
xmm0
|
||||||
|
|
||||||
type
|
type
|
||||||
Constraint* = enum
|
Constraint* = enum
|
||||||
|
|||||||
@ -6,7 +6,9 @@
|
|||||||
# * 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/[macros, strutils, sets, hashes, algorithm]
|
import
|
||||||
|
std/[macros, strutils, sets, hashes, algorithm],
|
||||||
|
../config
|
||||||
|
|
||||||
# A compile-time inline assembler
|
# A compile-time inline assembler
|
||||||
|
|
||||||
@ -39,15 +41,7 @@ type
|
|||||||
# Clobbered register
|
# Clobbered register
|
||||||
ClobberedReg
|
ClobberedReg
|
||||||
|
|
||||||
when sizeof(int) == 8 and not defined(CTT_32):
|
when CTT_32:
|
||||||
type
|
|
||||||
Register* = enum
|
|
||||||
rbx
|
|
||||||
rdx
|
|
||||||
r8
|
|
||||||
rax
|
|
||||||
xmm0
|
|
||||||
else:
|
|
||||||
type
|
type
|
||||||
Register* = enum
|
Register* = enum
|
||||||
rbx = "ebx"
|
rbx = "ebx"
|
||||||
@ -55,6 +49,14 @@ else:
|
|||||||
r8 = "r8d"
|
r8 = "r8d"
|
||||||
rax = "eax"
|
rax = "eax"
|
||||||
xmm0
|
xmm0
|
||||||
|
else:
|
||||||
|
type
|
||||||
|
Register* = enum
|
||||||
|
rbx
|
||||||
|
rdx
|
||||||
|
r8
|
||||||
|
rax
|
||||||
|
xmm0
|
||||||
|
|
||||||
type
|
type
|
||||||
Constraint* = enum
|
Constraint* = enum
|
||||||
@ -464,14 +466,17 @@ func getStrOffset(a: Assembler_x86, op: Operand): string =
|
|||||||
if op.desc.rm in {Mem, MemOffsettable}:
|
if op.desc.rm in {Mem, MemOffsettable}:
|
||||||
# Directly accessing memory
|
# Directly accessing memory
|
||||||
if defined(gcc):
|
if defined(gcc):
|
||||||
|
# https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#x86-Operand-Modifiers
|
||||||
|
# q: Print the DImode name of the register.
|
||||||
|
# k: Print the SImode name of the register.
|
||||||
if a.wordBitWidth == 64:
|
if a.wordBitWidth == 64:
|
||||||
if op.offset == 0:
|
if op.offset == 0:
|
||||||
return "%q" & op.desc.asmId
|
return "%q" & op.desc.asmId
|
||||||
return "%q" & op.desc.asmId & " + " & $(op.offset * a.wordSize)
|
return "%q" & op.desc.asmId & " + " & $(op.offset * a.wordSize)
|
||||||
else:
|
else:
|
||||||
if op.offset == 0:
|
if op.offset == 0:
|
||||||
return "%d" & op.desc.asmId
|
return "%k" & op.desc.asmId
|
||||||
return "%d" & op.desc.asmId & " + " & $(op.offset * a.wordSize)
|
return "%k" & op.desc.asmId & " + " & $(op.offset * a.wordSize)
|
||||||
elif defined(clang):
|
elif defined(clang):
|
||||||
if a.wordBitWidth == 64:
|
if a.wordBitWidth == 64:
|
||||||
if op.offset == 0:
|
if op.offset == 0:
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
# 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
|
import
|
||||||
|
./config,
|
||||||
constant_time/[
|
constant_time/[
|
||||||
ct_types,
|
ct_types,
|
||||||
ct_routines,
|
ct_routines,
|
||||||
@ -23,6 +24,7 @@ import
|
|||||||
./allocs
|
./allocs
|
||||||
|
|
||||||
export
|
export
|
||||||
|
config,
|
||||||
ct_types,
|
ct_types,
|
||||||
ct_routines,
|
ct_routines,
|
||||||
multiplexers,
|
multiplexers,
|
||||||
|
|||||||
@ -4,7 +4,8 @@ import
|
|||||||
../../constantine/math/[
|
../../constantine/math/[
|
||||||
arithmetic,
|
arithmetic,
|
||||||
io/io_bigints],
|
io/io_bigints],
|
||||||
../../constantine/math_arbitrary_precision/arithmetic/limbs_divmod_vartime
|
../../constantine/math_arbitrary_precision/arithmetic/limbs_divmod_vartime,
|
||||||
|
../../constantine/platforms/abstractions
|
||||||
|
|
||||||
let a = BigInt[64].fromUint(0xa0e5cb56a1c08396'u64)
|
let a = BigInt[64].fromUint(0xa0e5cb56a1c08396'u64)
|
||||||
let M = BigInt[64].fromUint(0xae57180eceb0206f'u64)
|
let M = BigInt[64].fromUint(0xae57180eceb0206f'u64)
|
||||||
@ -14,9 +15,9 @@ var r, r2: BigInt[64]
|
|||||||
r.reduce(a, M)
|
r.reduce(a, M)
|
||||||
doAssert r2.limbs.reduce_vartime(a.limbs, M.limbs)
|
doAssert r2.limbs.reduce_vartime(a.limbs, M.limbs)
|
||||||
|
|
||||||
let rU64 = 0xa0e5cb56a1c08396'u64 mod 0xae57180eceb0206f'u64
|
let rBase = cast[BaseType](0xa0e5cb56a1c08396'u64) mod cast[BaseType](0xae57180eceb0206f'u64)
|
||||||
# echo r.toHex()
|
# echo r.toHex()
|
||||||
|
|
||||||
doAssert rU64 == a.limbs[0].uint64
|
doAssert rBase == a.limbs[0].BaseType
|
||||||
doAssert bool(a == r)
|
doAssert bool(a == r)
|
||||||
echo "SUCCESS: t_bigints_mod.nim"
|
echo "SUCCESS: t_bigints_mod.nim"
|
||||||
@ -206,7 +206,7 @@ suite "EVM ModExp precompile (EIP-198)":
|
|||||||
0xa0]
|
0xa0]
|
||||||
var r = newSeq[byte](1)
|
var r = newSeq[byte](1)
|
||||||
let status = r.eth_evm_modexp(input)
|
let status = r.eth_evm_modexp(input)
|
||||||
doAssert status == cttEVM_Success
|
doAssert status == cttEVM_Success, "Failure status: " & $status
|
||||||
|
|
||||||
test "Audit #6 - DOS Vector 1":
|
test "Audit #6 - DOS Vector 1":
|
||||||
let input = [
|
let input = [
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user