2020-03-20 23:03:52 +01:00
|
|
|
# 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.
|
|
|
|
|
|
|
|
|
|
import
|
2021-01-22 00:09:52 +01:00
|
|
|
../config/[curves, type_ff],
|
2020-03-21 02:31:31 +01:00
|
|
|
./bigints,
|
2020-09-27 21:00:35 +02:00
|
|
|
../curves/zoo_inversions
|
2020-03-20 23:03:52 +01:00
|
|
|
|
2020-09-27 21:00:35 +02:00
|
|
|
export zoo_inversions
|
2020-09-04 19:04:32 +02:00
|
|
|
|
2020-03-20 23:03:52 +01:00
|
|
|
# ############################################################
|
|
|
|
|
#
|
2020-09-27 17:37:02 +02:00
|
|
|
# Finite field inversion
|
2020-03-20 23:03:52 +01:00
|
|
|
#
|
|
|
|
|
# ############################################################
|
|
|
|
|
|
2021-02-06 16:28:38 +01:00
|
|
|
# No exceptions allowed
|
|
|
|
|
{.push raises: [].}
|
|
|
|
|
{.push inline.}
|
|
|
|
|
|
2021-02-06 22:11:17 +01:00
|
|
|
func inv_euclid*(r: var FF, a: FF) =
|
2020-09-04 19:04:32 +02:00
|
|
|
## Inversion modulo p via
|
|
|
|
|
## Niels Moller constant-time version of
|
|
|
|
|
## Stein's GCD derived from extended binary Euclid algorithm
|
2021-02-06 22:11:17 +01:00
|
|
|
r.mres.steinsGCD(a.mres, FF.getR2modP(), FF.fieldMod(), FF.getPrimePlus1div2())
|
2020-09-04 19:04:32 +02:00
|
|
|
|
2021-02-06 22:11:17 +01:00
|
|
|
func inv*(r: var FF, a: FF) =
|
2020-03-20 23:03:52 +01:00
|
|
|
## Inversion modulo p
|
2020-04-14 02:05:42 +02:00
|
|
|
##
|
|
|
|
|
## The inverse of 0 is 0.
|
|
|
|
|
## Incidentally this avoids extra check
|
|
|
|
|
## to convert Jacobian and Projective coordinates
|
|
|
|
|
## to affine for elliptic curve
|
2020-04-12 16:09:38 +02:00
|
|
|
# For now we don't activate the addition chains
|
2022-01-01 16:19:35 +01:00
|
|
|
# Performance is slower than Euclid-based inversion on newer CPUs
|
|
|
|
|
#
|
|
|
|
|
# - Montgomery multiplication/squaring can skip the final substraction
|
|
|
|
|
# - For generalized Mersenne Prime curves, modular reduction can be made extremely cheap.
|
|
|
|
|
# - For BW6-761 the addition chain is over 2x slower than Euclid-based inversion
|
|
|
|
|
# due to multiplication being so costly with 12 limbs (grows quadratically)
|
|
|
|
|
# while Euclid costs grows linearly.
|
|
|
|
|
when false and
|
|
|
|
|
FF is Fp and FF.C.hasInversionAddchain() and
|
|
|
|
|
FF.C notin {BW6_761}:
|
2020-09-04 19:04:32 +02:00
|
|
|
r.inv_addchain(a)
|
2020-09-01 13:40:39 +02:00
|
|
|
else:
|
2020-09-04 19:04:32 +02:00
|
|
|
r.inv_euclid(a)
|
2020-06-15 22:58:56 +02:00
|
|
|
|
2021-02-06 22:11:17 +01:00
|
|
|
func inv*(a: var FF) =
|
2020-06-15 22:58:56 +02:00
|
|
|
## Inversion modulo p
|
|
|
|
|
##
|
|
|
|
|
## The inverse of 0 is 0.
|
|
|
|
|
## Incidentally this avoids extra check
|
|
|
|
|
## to convert Jacobian and Projective coordinates
|
|
|
|
|
## to affine for elliptic curve
|
2021-02-06 22:11:17 +01:00
|
|
|
a.inv(a)
|
2021-02-06 16:28:38 +01:00
|
|
|
|
|
|
|
|
{.pop.} # inline
|
|
|
|
|
{.pop.} # raises no exceptions
|