From befbf303196b9b4711a03801f6c3ccd974bdbd83 Mon Sep 17 00:00:00 2001 From: mratsim Date: Sun, 2 Dec 2018 00:35:55 +0100 Subject: [PATCH] Add modular addition over Fp --- constantine/{bigint.nim => bigints.nim} | 18 ++++++-- constantine/field_arith.nim | 8 ---- constantine/field_fp.nim | 60 +++++++++++++++++++++++++ constantine/word_types.nim | 11 +++-- 4 files changed, 82 insertions(+), 15 deletions(-) rename constantine/{bigint.nim => bigints.nim} (86%) delete mode 100644 constantine/field_arith.nim create mode 100644 constantine/field_fp.nim diff --git a/constantine/bigint.nim b/constantine/bigints.nim similarity index 86% rename from constantine/bigint.nim rename to constantine/bigints.nim index 2a2d72d..935adcf 100644 --- a/constantine/bigint.nim +++ b/constantine/bigints.nim @@ -5,8 +5,13 @@ # * 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. -# Big int internal representation. + +# ############################################################ # +# BigInt representation +# +# ############################################################ + # To avoid carry issues we don't use the # most significant bit of each word. # i.e. for a uint64 base we only use 63-bit. @@ -16,6 +21,10 @@ # - https://cryptojedi.org/peter/data/pairing-20131122.pdf # - http://docs.milagro.io/en/amcl/milagro-crypto-library-white-paper.html # +# Note that this might also be beneficial in terms of performance. +# Due to opcode latency, on Nehalem ADC is 6x times slower than ADD +# if it has dependencies (i.e the ADC depends on a previous ADC result) + # Control flow should only depends on the static maximum number of bits # This number is defined per Finite Field/Prime/Elliptic Curve # @@ -58,8 +67,11 @@ const highLimb* = (not Ct[uint64](0)) shr 1 # if it is a placebo operation. It stills performs the # same memory accesses to be side-channel attack resistant -# For efficiency we define templates and will create functions -# specialized for runtime and compile-time inputs +# For efficiency we can define templates and will create functions +# specialised for runtime and compile-time inputs. +# +# We don't specialise for the control word, any optimizing compiler +# will keep it in registers. template addImpl[bits](result: CTBool[Limb], a: var BigInt[bits], b: BigInt[bits], ctl: CTBool[Limb]) = ## Constant-time big integer in-place addition diff --git a/constantine/field_arith.nim b/constantine/field_arith.nim deleted file mode 100644 index d5f32f6..0000000 --- a/constantine/field_arith.nim +++ /dev/null @@ -1,8 +0,0 @@ -# Constantine -# Copyright (c) 2018 Status Research & Development GmbH -# 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. - - diff --git a/constantine/field_fp.nim b/constantine/field_fp.nim new file mode 100644 index 0000000..e77aa7a --- /dev/null +++ b/constantine/field_fp.nim @@ -0,0 +1,60 @@ +# Constantine +# Copyright (c) 2018 Status Research & Development GmbH +# 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. + +# ############################################################ +# +# Field arithmetic over Fp +# +# ############################################################ + +# We assume that p is prime known at compile-time + +import + ./word_types, ./bigints + +type + Fp[P: static BigInt] = object + ## P is a prime number + ## All operations on a field are modulo P + value: type(P) + +# ############################################################ +# +# Aliases +# +# ############################################################ + +const + True = ctrue(Limb) + False = cfalse(Limb) + +template add(a: var Fp, b: Fp, ctl: CTBool[Limb]): CTBool[Limb] = + add(a.value, b.value, ctl) + +template sub(a: var Fp, b: Fp, ctl: CTBool[Limb]): CTBool[Limb] = + sub(a.value, b.value, ctl) + +# ############################################################ +# +# Field arithmetic primitives +# +# ############################################################ + +func `+`*(a, b: Fp): Fp = + ## Addition over Fp + + # Non-CT implementation from Stint + # + # let b_from_p = p - b # Don't do a + b directly to avoid overflows + # if a >= b_from_p: + # return a - b_from_p + # return m - b_from_p + a + + result = a + var ctl = add(result, b, True) + ctl = ctl or not sub(result, Fp.P, False) + sub(result, Fp.P, ctl) diff --git a/constantine/word_types.nim b/constantine/word_types.nim index c4f6757..b684f10 100644 --- a/constantine/word_types.nim +++ b/constantine/word_types.nim @@ -15,11 +15,11 @@ type ## by conditional branches, we don't use booleans. ## We use an int to prevent compiler "optimization" and introduction of branches -func ctrue*(T: type(BaseUint)): auto {.inline.}= - (CTBool[Ct[T]])(true) +func ctrue*(T: type(Ct)): auto {.inline.}= + (CTBool[T])(true) -func cfalse*(T: type(BaseUint)): auto {.inline.}= - (CTBool[Ct[T]])(false) +func cfalse*(T: type(Ct)): auto {.inline.}= + (CTBool[T])(false) func ct*[T: BaseUint](x: T): Ct[T] {.inline.}= (Ct[T])(x) @@ -103,6 +103,9 @@ func `not`*(ctl: CTBool): CTBool {.inline.}= ## Negate a constant-time boolean (type result)(ctl.undistinct xor (type ctl.undistinct)(1)) +func `and`*(x, y: CTBool): CTBool {.magic: "BitandI".} +func `or`*(x, y: CTBool): CTBool {.magic: "BitorI".} + template mux*[T: Ct](ctl: CTBool[T], x, y: T): T = ## Multiplexer / selector ## Returns x if ctl == 1