diff --git a/constantine.nimble b/constantine.nimble index 30d5fdb..99a4882 100644 --- a/constantine.nimble +++ b/constantine.nimble @@ -16,7 +16,7 @@ proc test(fakeCurves: string, path: string, lang = "c") = ### tasks task test, "Run all tests": - test "", "tests/test_word_types.nim" - test "", "tests/test_io.nim" - test "", "tests/test_bigints.nim" - test "-d:testingCurves", "tests/test_field_fp.nim" + test "", "tests/test_word_types.nim" + test "", "tests/test_io.nim" + test "", "tests/test_bigints.nim" + test " -d:testingCurves", "tests/test_field_fp.nim" diff --git a/constantine/bigints.nim b/constantine/bigints.nim index 2f8fa98..8c7e9c0 100644 --- a/constantine/bigints.nim +++ b/constantine/bigints.nim @@ -91,16 +91,18 @@ template `[]=`*(a: var Bigint, idx: int, w: Word) = # # ############################################################ +# No exceptions allowed +{.push raises: [].} # TODO: {.inline.} analysis -func isZero*(a: BigInt): CTBool[Word] {.raises: [].} = +func isZero*(a: BigInt): CTBool[Word] = ## Returns if a big int is equal to zero var accum: Word for i in static(0 ..< a.limbs.len): accum = accum or a.limbs[i] result = accum.isZero() -func `==`*(a, b: BigInt): CTBool[Word] {.raises: [].}= +func `==`*(a, b: BigInt): CTBool[Word] = ## Returns true if 2 big ints are equal var accum: Word for i in static(0 ..< a.limbs.len): diff --git a/constantine/field_fp.nim b/constantine/field_fp.nim index 7e845e6..4d4498c 100644 --- a/constantine/field_fp.nim +++ b/constantine/field_fp.nim @@ -54,7 +54,10 @@ template `[]`(a: Fp, idx: int): Word = # # ############################################################ -func `+`*(a, b: Fp): Fp = +# No exceptions allowed +{.push raises: [].} + +func `+`*(a, b: Fp): Fp {.noInit.}= ## Addition over Fp # Non-CT implementation from Stint diff --git a/constantine/montgomery.nim b/constantine/montgomery.nim index 9715f26..ca7f9d1 100644 --- a/constantine/montgomery.nim +++ b/constantine/montgomery.nim @@ -15,6 +15,9 @@ import ./word_types, ./bigints, ./field_fp, ./curves_config +# No exceptions allowed +{.push raises: [].} + func toMonty*[C: static Curve](a: Fp[C]): Montgomery[C] = ## Convert a big integer over Fp to it's montgomery representation ## over Fp. diff --git a/constantine/montgomery_magic.nim b/constantine/montgomery_magic.nim index 87da9a8..ae53ab5 100644 --- a/constantine/montgomery_magic.nim +++ b/constantine/montgomery_magic.nim @@ -19,6 +19,9 @@ from bitops import fastLog2 # This will only be used at compile-time # so no constant-time worries (it is constant-time if using the De Bruijn multiplication) +# No exceptions allowed +{.push raises: [].} + func montyMagic*(M: static BigInt): static Word {.inline.} = ## Returns the Montgomery domain magic number for the input modulus: ## -1/M[0] mod LimbSize diff --git a/constantine/word_types.nim b/constantine/word_types.nim index 71721d2..6166155 100644 --- a/constantine/word_types.nim +++ b/constantine/word_types.nim @@ -16,25 +16,30 @@ type ## by conditional branches, we don't use booleans. ## We use an int to prevent compiler "optimization" and introduction of branches -func ctrue*(T: typedesc[Ct or BaseUint]): auto {.inline, raises: [].}= +# No exceptions allowed +{.push raises: [].} +# Word primitives are inlined +{.push inline.} + +func ctrue*(T: typedesc[Ct or BaseUint]): auto = when T is Ct: (CTBool[T])(true) else: (CTBool[Ct[T]])(true) -func cfalse*(T: typedesc[Ct or BaseUint]): auto {.inline, raises: [].}= +func cfalse*(T: typedesc[Ct or BaseUint]): auto = when T is Ct: (CTBool[T])(false) else: (CTBool[Ct[T]])(false) -func ct*[T: BaseUint](x: T): Ct[T] {.inline, raises: [].}= +func ct*[T: BaseUint](x: T): Ct[T] = (Ct[T])(x) -func `$`*[T](x: Ct[T]): string {.inline, raises: [].} = +func `$`*[T](x: Ct[T]): string = $T(x) -func `$`*(x: CTBool): string {.inline, raises: [].} = +func `$`*(x: CTBool): string = $bool(x) # ############################################################ @@ -62,7 +67,7 @@ func `$`*(x: CTBool): string {.inline, raises: [].} = # - https://github.com/nim-lang/Nim/pull/8531 # - https://github.com/nim-lang/Nim/issues/4121 (can be workaround with #8531) -func high*(T: typedesc[Ct]): T {.inline, raises: [].}= +func high*(T: typedesc[Ct]): T = not T(0) func `and`*[T: Ct](x, y: T): T {.magic: "BitandI".} @@ -87,7 +92,7 @@ func `*`*[T: Ct](x, y: T): T {.magic: "MulU".} # We don't implement div/mod as we can't assume the hardware implementation # is constant-time -func `-`*(x: Ct): Ct {.inline, raises: [].}= +func `-`*(x: Ct): Ct = ## Unary minus returns the two-complement representation ## of an unsigned integer {.emit:"`result` = -`x`;".} @@ -98,7 +103,7 @@ func `-`*(x: Ct): Ct {.inline, raises: [].}= # # ############################################################ -func isMsbSet*[T: Ct](x: T): CTBool[T] {.inline, raises: [].} = +func isMsbSet*[T: Ct](x: T): CTBool[T] = ## Returns the most significant bit of an integer const msb_pos = T.sizeof * 8 - 1 result = (CTBool[T])(x shr msb_pos) @@ -112,7 +117,7 @@ func isMsbSet*[T: Ct](x: T): CTBool[T] {.inline, raises: [].} = template undistinct[T: Ct](x: CTBool[T]): T = T(x) -func `not`*(ctl: CTBool): CTBool {.inline, raises: [].}= +func `not`*(ctl: CTBool): CTBool = ## Negate a constant-time boolean (type result)(ctl.undistinct xor (type ctl.undistinct)(1)) @@ -131,22 +136,22 @@ template mux*[T: Ct](ctl: CTBool[T], x, y: T): T = # the alternative `(x and ctl) or (y and -ctl)` # is optimized into a branch by Clang :/ -func noteq[T: Ct](x, y: T): CTBool[T] {.inline, raises: [].}= +func noteq[T: Ct](x, y: T): CTBool[T] = const msb = T.sizeof * 8 - 1 let z = x xor y result = (type result)((z or -z) shr msb) -func `==`*[T: Ct](x, y: T): CTBool[T] {.inline, raises: [].}= +func `==`*[T: Ct](x, y: T): CTBool[T] = not(noteq(x, y)) -func `<`*[T: Ct](x, y: T): CTBool[T] {.inline, raises: [].}= +func `<`*[T: Ct](x, y: T): CTBool[T] = result = isMsbSet( x xor ( (x xor y) or ((x - y) xor y) ) ) -func `<=`*[T: Ct](x, y: T): CTBool[T] {.inline, raises: [].}= +func `<=`*[T: Ct](x, y: T): CTBool[T] = not(y < x) # ############################################################ @@ -168,10 +173,10 @@ template trmFixSystemNotEq*{x != y}[T: Ct](x, y: T): CTBool[T] = # # ############################################################ -func isNonZero*[T: Ct](x: T): CTBool[T] {.inline, raises: [].} = +func isNonZero*[T: Ct](x: T): CTBool[T] = isMsbSet(x or -x) -func isZero*[T: Ct](x: T): CTBool[T] {.inline, raises: [].} = +func isZero*[T: Ct](x: T): CTBool[T] = not x.isNonZero # ############################################################