Add modular addition over Fp
This commit is contained in:
parent
463b8a4fcb
commit
befbf30319
|
@ -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
|
|
@ -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.
|
||||
|
||||
|
|
@ -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)
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue