Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,23 @@ jobs:
nim_version: [version-1-6] # [version-1-4, devel]
target:
- os: linux
cpu: amd64
cpu: i386
TEST_LANG: c
BACKEND: NO_ASM
- os: linux
cpu: i386
TEST_LANG: c
BACKEND: 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
cpu: amd64
TEST_LANG: c
BACKEND: NO_ASM
- os: linux
cpu: amd64
TEST_LANG: c
BACKEND: ASM

- os: windows
cpu: amd64
TEST_LANG: c
Expand All @@ -32,6 +35,7 @@ jobs:
cpu: amd64
TEST_LANG: c
BACKEND: ASM

- os: macos
cpu: amd64
TEST_LANG: c
Expand Down
2 changes: 1 addition & 1 deletion benchmarks/bench_blueprint.nim
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ echo " release: ", defined(release)
echo " danger: ", defined(danger)
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"
else:
echo "Using Constantine with 64-bit limbs"
Expand Down
16 changes: 10 additions & 6 deletions benchmarks/bench_evm_modexp_dos.nim
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import

proc report(op: string, elapsedNs: int64, elapsedCycles: int64, iters: int) =
let ns = elapsedNs div iters
let cycles = elapsedCycles div iters
when SupportsGetTicks:
let cycles = elapsedCycles div iters
let throughput = 1e9 / float64(ns)
when SupportsGetTicks:
echo &"{op:<70} {throughput:>15.3f} ops/s {ns:>16} ns/op {cycles:>12} CPU cycles (approx)"
Expand All @@ -17,12 +18,15 @@ proc report(op: string, elapsedNs: int64, elapsedCycles: int64, iters: int) =
template bench(fnCall: untyped, ticks, ns: var int64): untyped =
block:
let startTime = getMonotime()
let startClock = getTicks()
when SupportsGetTicks:
let startClock = getTicks()
fnCall
let stopClock = getTicks()
when SupportsGetTicks:
let stopClock = getTicks()
let stopTime = getMonotime()

ticks += stopClock - startClock
when SupportsGetTicks:
ticks += stopClock - startClock
ns += inNanoseconds(stopTime-startTime)

func computeGasFee(inputs: openArray[byte]): tuple[eip128, eip2565: int] =
Expand Down Expand Up @@ -91,8 +95,8 @@ func computeGasFee(inputs: openArray[byte]): tuple[eip128, eip2565: int] =
baseStop = baseStart+baseByteLen-1
expStart = baseStop+1
expStop = expStart+exponentByteLen-1
modStart = expStop+1
modStop = modStart+modulusByteLen-1
# modStart = expStop+1
# modStop = modStart+modulusByteLen-1

template exponent(): untyped =
inputs.toOpenArray(expStart, expStop)
Expand Down
2 changes: 1 addition & 1 deletion benchmarks/bench_fp_double_precision.nim
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ echo " release: ", defined(release)
echo " danger: ", defined(danger)
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"
else:
echo "Using Constantine with 64-bit limbs"
Expand Down
3 changes: 0 additions & 3 deletions constantine/ethereum_evm_precompiles.nim
Original file line number Diff line number Diff line change
Expand Up @@ -433,9 +433,6 @@ func eth_evm_modexp*(r: var openArray[byte], inputs: openArray[byte]): CttEVMSta
if r.len != modulusByteLen:
return cttEVM_InvalidOutputSize

if baseWordLen > modulusWordLen:
return cttEVM_InvalidInputSize

# Special cases
# ----------------------
if paddedLengths.len + baseByteLen + exponentByteLen >= inputs.len:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ func sum2xMod*(r: var FpDbl, a, b: FpDbl) =

# Conditional reduction by 2ⁿp
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) =
## Double-precision modular substraction
Expand Down
21 changes: 6 additions & 15 deletions constantine/platforms/abstractions.nim
Original file line number Diff line number Diff line change
Expand Up @@ -17,28 +17,19 @@ import ../../metering/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
#
# ############################################################

when sizeof(int) == 8 and not defined(CTT_32):
when CTT_32:
type
BaseType* = uint64
BaseType* = uint32
## Physical BigInt for conversion in "normal integers"
else:
type
BaseType* = uint32
BaseType* = uint64
## Physical BigInt for conversion in "normal integers"

type
Expand Down Expand Up @@ -131,12 +122,12 @@ debug: # Don't allow printing secret words by default

type SignedSecretWord* = distinct SecretWord

when sizeof(int) == 8 and not defined(CTT_32):
when CTT_32:
type
SignedBaseType* = int64
SignedBaseType* = int32
else:
type
SignedBaseType* = int32
SignedBaseType* = int64

template fmap(x: SignedSecretWord, op: untyped, y: SignedSecretWord): SignedSecretWord =
## Unwrap x and y from their distinct type
Expand Down
31 changes: 31 additions & 0 deletions constantine/platforms/config.nim
Original file line number Diff line number Diff line change
@@ -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
9 changes: 2 additions & 7 deletions constantine/platforms/constant_time/ct_types.nim
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,5 @@ type
Carry* = 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)
const X86* = defined(amd64) or defined(i386)

when sizeof(int) == 8 and GCC_Compatible:
type
uint128*{.importc: "unsigned __int128".} = object
int128*{.importc: "__int128".} = object
VarTime* = object
## For use with Nim effect system to track vartime subroutines
5 changes: 3 additions & 2 deletions constantine/platforms/constant_time/multiplexers.nim
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
# * 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 ./ct_types
import ../isa/macro_assembler_x86
import
./ct_types,
../config

# ############################################################
#
Expand Down
4 changes: 3 additions & 1 deletion constantine/platforms/intrinsics/addcarry_subborrow.nim
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
# * 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 ../constant_time/ct_types
import
../config,
../constant_time/ct_types

# ############################################################
#
Expand Down
2 changes: 1 addition & 1 deletion constantine/platforms/intrinsics/bitops.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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 ../constant_time/ct_types
import ../config

when GCC_Compatible:
func builtin_clz(n: uint32): cint {.importc: "__builtin_clz", nodecl.}
Expand Down
1 change: 1 addition & 0 deletions constantine/platforms/intrinsics/extended_precision.nim
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# ############################################################

import
../config,
./addcarry_subborrow,
../constant_time/ct_types,
../constant_time/ct_routines
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
# * 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 ../constant_time/ct_types
import
../config,
../constant_time/ct_types

# ############################################################
#
Expand Down Expand Up @@ -86,7 +88,7 @@ func smul*(hi, lo: var Ct[uint64], a, b: Ct[uint64]) {.inline.} =
##
## Inputs are intentionally unsigned
## as we use their unchecked raw representation for cryptography
##
##
## This is constant-time on most hardware
## See: https://www.bearssl.org/ctmul.html
block:
Expand Down
25 changes: 13 additions & 12 deletions constantine/platforms/intrinsics/extended_precision_vartime.nim
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@

import ../abstractions

func div2n1n_nim_vartime[T: SomeUnsignedInt](q, r: var T, n_hi, n_lo, d: T) {.tags:[VarTime].}=
## Division uint128 by uint64
func div2n1n_nim_vartime[T: SomeUnsignedInt](q, r: var T, n_hi, n_lo, d: T) {.used, tags:[VarTime].}=
## Division uint128 by uint64 or uint64 by uint32
## Warning ⚠️ :
## - if n_hi == d, quotient does not fit in an uint64 and will throw SIGFPE
## - if n_hi > d result is undefined
Expand Down Expand Up @@ -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
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].}
## Division 128 by 64, Microsoft only, 64-bit only,
## returns quotient as return value remainder as var parameter
Expand All @@ -74,7 +74,7 @@ when sizeof(int) == 8 and defined(vcc):
## - if n_hi > d result is undefined
q = udiv128_vartime(n_hi, n_lo, d, r)

elif sizeof(int) == 8 and GCC_Compatible:
elif not(CTT_32) and GCC_Compatible:
type
uint128{.importc: "unsigned __int128".} = object

Expand Down Expand Up @@ -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.
## i.e. shifted (== multiplied by the same power of 2)
## 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 divisor = uint64(d)
q = uint32(dividend div divisor)
r = uint32(dividend mod divisor)
when nimvm:
div2n1n_nim_vartime(BaseType q, BaseType r, BaseType n_hi, BaseType n_lo, BaseType d)
q = SecretWord(dividend div divisor)
r = SecretWord(dividend mod divisor)
else:
when declared(div2n1n_128_vartime):
div2n1n_128_vartime(BaseType q, BaseType r, BaseType n_hi, BaseType n_lo, BaseType d)
else:
when nimvm:
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)
2 changes: 1 addition & 1 deletion constantine/platforms/isa/macro_assembler_x86.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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.

const UseAsmSyntaxIntel* {.booldefine.} = true
import ../config

when UseAsmSyntaxIntel:
# We need Intel syntax.
Expand Down
22 changes: 12 additions & 10 deletions constantine/platforms/isa/macro_assembler_x86_att.nim
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
# * 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 std/[macros, strutils, sets, hashes, algorithm]
import
std/[macros, strutils, sets, hashes, algorithm],
../config

# A compile-time inline assembler

Expand Down Expand Up @@ -39,22 +41,22 @@ type
# Clobbered register
ClobberedReg

when sizeof(int) == 8 and not defined(CTT_32):
type
Register* = enum
rbx
rdx
r8
rax
xmm0
else:
when CTT_32:
type
Register* = enum
rbx = "ebx"
rdx = "edx"
r8 = "r8d"
rax = "eax"
xmm0
else:
type
Register* = enum
rbx
rdx
r8
rax
xmm0

type
Constraint* = enum
Expand Down
Loading