Skip to content

Commit

Permalink
shifted to seperate vartime functions
Browse files Browse the repository at this point in the history
  • Loading branch information
advaita-saha committed Feb 11, 2024
1 parent 0ddab7e commit 7ac17bc
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 17 deletions.
43 changes: 41 additions & 2 deletions constantine/math/arithmetic/finite_fields_square_root.nim
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import
../../platforms/abstractions,
../config/curves,
../constants/zoo_square_roots,
./finite_fields_precomp_square_root,
./finite_fields_square_root_precomp,
./bigints, ./finite_fields, ./limbs_exgcd

# ############################################################
Expand Down Expand Up @@ -212,10 +212,13 @@ func invsqrt*[C](r: var Fp[C], a: Fp[C]) =
elif C.has_P_5mod8_primeModulus():
r.invsqrt_p5mod8(a)
elif C == Bandersnatch or C == Banderwagon:
r.inv_sqrt_precomp(a)
r.inv_sqrt_precomp_vartime(a) # should be changed
else:
r.invsqrt_tonelli_shanks(a)

func invsqrt_vartime*[C](r: var Fp[C], a: Fp[C]) =
r.inv_sqrt_precomp_vartime(a)

func sqrt*[C](a: var Fp[C]) =
## Compute the square root of ``a``
##
Expand All @@ -231,6 +234,14 @@ func sqrt*[C](a: var Fp[C]) =
t.invsqrt(a)
a *= t

func sqrt_vartime*[C](a: var Fp[C]) =
## This is a vartime version of sqrt
## It is not constant-time
## This has the precomp optimisation
var t {.noInit.}: Fp[C]
t.invsqrt_vartime(a)
a *= t

func sqrt_invsqrt*[C](sqrt, invsqrt: var Fp[C], a: Fp[C]) =
## Compute the square root and inverse square root of ``a``
##
Expand All @@ -244,6 +255,12 @@ func sqrt_invsqrt*[C](sqrt, invsqrt: var Fp[C], a: Fp[C]) =
invsqrt.invsqrt(a)
sqrt.prod(invsqrt, a)

func sqrt_invsqrt_vartime*[C](sqrt, invsqrt: var Fp[C], a: Fp[C]) =
## It is not constant-time
## This has the precomp optimisation
invsqrt.invsqrt_vartime(a)
sqrt.prod(invsqrt, a)

func sqrt_invsqrt_if_square*[C](sqrt, invsqrt: var Fp[C], a: Fp[C]): SecretBool =
## Compute the square root and ivnerse square root of ``a``
##
Expand All @@ -259,6 +276,14 @@ func sqrt_invsqrt_if_square*[C](sqrt, invsqrt: var Fp[C], a: Fp[C]): SecretBool
test.square(sqrt)
result = test == a

func sqrt_invsqrt_if_square_vartime*[C](sqrt, invsqrt: var Fp[C], a: Fp[C]): SecretBool =
## It is not constant-time
## This has the precomp optimisation
sqrt_invsqrt_vartime(sqrt, invsqrt, a)
var test {.noInit.}: Fp[C]
test.square(sqrt)
result = test == a

func sqrt_if_square*[C](a: var Fp[C]): SecretBool =
## If ``a`` is a square, compute the square root of ``a``
## if not, ``a`` is undefined.
Expand All @@ -282,6 +307,12 @@ func invsqrt_if_square*[C](r: var Fp[C], a: Fp[C]): SecretBool =
var sqrt{.noInit.}: Fp[C]
result = sqrt_invsqrt_if_square(sqrt, r, a)

func invsqrt_if_square_vartime*[C](r: var Fp[C], a: Fp[C]): SecretBool =
## It is not constant-time
## This has the precomp optimisation
var sqrt{.noInit.}: Fp[C]
result = sqrt_invsqrt_if_square_vartime(sqrt, r, a)

# Legendre symbol / Euler's Criterion / Kronecker's symbol
# ------------------------------------------------------------

Expand Down Expand Up @@ -318,4 +349,12 @@ func sqrt_ratio_if_square*(r: var Fp, u, v: Fp): SecretBool {.inline.} =
result = r.invsqrt_if_square(uv) # 1/√uv
r *= u # √u/√v

func sqrt_ratio_if_square_vartime*(r: var Fp, u, v: Fp): SecretBool {.inline.} =
## It is not constant-time
## This has the precomp optimisation
var uv{.noInit.}: Fp
uv.prod(u, v) # uv
result = r.invsqrt_if_square_vartime(uv) # 1/√uv
r *= u # √u/√v

{.pop.} # raises no exceptions
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import
# The returned value is only meaningful modulo 1<<sqrtParam_BlockSize and is fully reduced, i.e. in [0, 1<<sqrtParam_BlockSize )
#
# NOTE: If x is not a root of unity as asserted, the behaviour is undefined.
func sqrtAlg_NegDlogInSmallDyadicSubgroup(x: Fp): int =
func sqrtAlg_NegDlogInSmallDyadicSubgroup_vartime(x: Fp): int {.tags:[VarTime], raises: [].} =
let key = cast[int](x.mres.limbs[0] and SecretWord 0xFFFF)
return Fp.C.sqrtDlog(dlogLUT).getOrDefault(key, 0)

Expand Down Expand Up @@ -134,7 +134,7 @@ func sqrtAlg_ComputeRelevantPowers(z: Fp, squareRootCandidate: var Fp, rootOfUni
squareRootCandidate.prod(acc, z)


func invSqrtEqDyadic(z: var Fp) =
func invSqrtEqDyadic_vartime*(z: var Fp) =
## The algorithm works by essentially computing the dlog of z and then halving it.
## negExponent is intended to hold the negative of the dlog of z.
## We determine this 32-bit value (usually) _sqrtBlockSize many bits at a time, starting with the least-significant bits.
Expand All @@ -147,16 +147,16 @@ func invSqrtEqDyadic(z: var Fp) =
# set powers[i] to z^(1<< (i*blocksize))
var powers: array[4, Fp]
powers[0] = z
for i in 1..<Fp.C.sqrtDlog(Blocks):
for i in 1 ..< Fp.C.sqrtDlog(Blocks):
powers[i] = powers[i - 1]
for j in 0..<Fp.C.sqrtDlog(BlockSize):
for j in 0 ..< Fp.C.sqrtDlog(BlockSize):
powers[i].square(powers[i])

## looking at the dlogs, powers[i] is essentially the wanted exponent, left-shifted by i*_sqrtBlockSize and taken mod 1<<32
## dlogHighDyadicRootNeg essentially (up to sign) reads off the _sqrtBlockSize many most significant bits. (returned as low-order bits)
##
## first iteration may be slightly special if BlockSize does not divide 32
negExponent = sqrtAlg_NegDlogInSmallDyadicSubgroup(powers[Fp.C.sqrtDlog(Blocks) - 1])
negExponent = sqrtAlg_NegDlogInSmallDyadicSubgroup_vartime(powers[Fp.C.sqrtDlog(Blocks) - 1])
negExponent = negExponent shr Fp.C.sqrtDlog(FirstBlockUnusedBits)

# if the exponent we just got is odd, there is no square root, no point in determining the other bits
Expand All @@ -165,26 +165,26 @@ func invSqrtEqDyadic(z: var Fp) =

# result = SecretBool((negExponent and 1) != 1)

for i in 1..<Fp.C.sqrtDlog(Blocks):
for i in 1 ..< Fp.C.sqrtDlog(Blocks):
temp2 = powers[Fp.C.sqrtDlog(Blocks) - 1 - i]
for j in 0..<i:
for j in 0 ..< i:
sqrtAlg_GetPrecomputedRootOfUnity(temp, int( (negExponent shr (j*Fp.C.sqrtDlog(BlockSize))) and Fp.C.sqrtDlog(BitMask) ), uint(j + Fp.C.sqrtDlog(Blocks) - 1 - i))
temp2.prod(temp2, temp)

var newBits = sqrtAlg_NegDlogInSmallDyadicSubgroup(temp2)
var newBits = sqrtAlg_NegDlogInSmallDyadicSubgroup_vartime(temp2)
negExponent = negExponent or (newBits shl ((i*Fp.C.sqrtDlog(BlockSize)) - Fp.C.sqrtDlog(FirstBlockUnusedBits)))

negExponent = negExponent shr 1
z.setOne()

for i in 0..<Fp.C.sqrtDlog(Blocks):
for i in 0 ..< Fp.C.sqrtDlog(Blocks):
sqrtAlg_GetPrecomputedRootOfUnity(temp, int((negExponent shr (i*Fp.C.sqrtDlog(BlockSize))) and Fp.C.sqrtDlog(BitMask)), uint(i))
z.prod(z, temp)

func inv_sqrt_precomp*(dst: var Fp, x: Fp) {.inline.} =
dst.setZero()
var candidate, rootOfUnity: Fp
func inv_sqrt_precomp_vartime*(dst: var Fp, x: Fp) {.inline.} =
dst.setOne()
var candidate, rootOfUnity {.noInit.}: Fp
sqrtAlg_ComputeRelevantPowers(x, candidate, rootOfUnity)
invSqrtEqDyadic(rootOfUnity)
invSqrtEqDyadic_vartime(rootOfUnity)
dst.prod(candidate, rootOfUnity)
dst.inv()
45 changes: 44 additions & 1 deletion constantine/math/elliptic/ec_twistededwards_affine.nim
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import
../../platforms/abstractions,
../config/curves,
../arithmetic,
#../arithmetic/finite_fields_precomp_square_root,
../extension_fields,
../io/[io_fields, io_extfields]

Expand Down Expand Up @@ -126,6 +125,50 @@ func trySetFromCoordX*[F](P: var ECP_TwEdwards_Aff[F], x: F): SecretBool =
P.y = t
P.x = x

func trySetFromCoordX_vartime*[F](P: var ECP_TwEdwards_Aff[F], x: F): SecretBool =
## This is not in constant time
## Try to create a point on the elliptic curve from X co-ordinate
## ax²+y²=1+dx²y² (affine coordinate)
##
## return true and update `P` if `y` leads to a valid point
## return false otherwise, in that case `P` is undefined.

# y² = (1 - ax²)/(1 - dx²)
var t {.noInit.}: F
var one {.noInit.}: F
one.setOne()

# (1 - dx²)
t.square(x)
when F.C.getCoefD() is int:
when F.C.getCoefD() >= 0:
P.y.fromUint uint F.C.getCoefD()
else:
P.y.fromUint uint -F.C.getCoefD()
P.y.neg()
else:
P.y = F.C.getCoefD()
P.y *= t
P.y.neg()
P.y += one

# (1 - ax²)
when F.C.getCoefA() is int:
when F.C.getCoefA() >= 0:
P.x.fromUint uint F.C.getCoefA()
else:
P.x.fromUint uint -F.C.getCoefA()
P.x.neg()
else:
P.x = F.C.getCoefA()
P.x *= t
P.x.neg()
P.x += one

# √((1 - ax²)/(1 - dx²))
result = sqrt_ratio_if_square_vartime(t, P.x, P.y)
P.y = t
P.x = x

func trySetFromCoordY*[F](P: var ECP_TwEdwards_Aff[F], y: F): SecretBool =
## Try to create a point the elliptic curve
Expand Down
19 changes: 19 additions & 0 deletions constantine/math/elliptic/ec_twistededwards_projective.nim
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,25 @@ func trySetFromCoordX*[F](
P.y = Q.y
P.z.setOne()

func trySetFromCoordX_vartime*[F](
P: var ECP_TwEdwards_Prj[F],
x: F): SecretBool =
## this is not in constant time
## Try to create a point on the elliptic curve from X co-ordinate
## ax²+y²=1+dx²y² (affine coordinate)
##
## The `Z` coordinates is set to 1
##
## return true and update `P` if `y` leads to a valid point
## return false otherwise, in that case `P` is undefined.

var Q{.noInit.}: ECP_TwEdwards_Aff[F]
result = Q.trySetFromCoordX_vartime(x)

P.x = Q.x
P.y = Q.y
P.z.setOne()


func trySetFromCoordY*[F](
P: var ECP_TwEdwards_Prj[F],
Expand Down
4 changes: 3 additions & 1 deletion constantine/serialization/codecs_banderwagon.nim
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ func deserialize_unchecked*(dst: var EC_Prj, src: array[32, byte]): CttCodecEccS
var x{.noInit.}: Fp[Banderwagon]
x.fromBig(t)

let onCurve = dst.trySetFromCoordX(x)
let onCurve = dst.trySetFromCoordX_vartime(x) # later to be shifted to a constant time version
if not(bool onCurve):
return cttCodecEcc_PointNotOnCurve

Expand Down Expand Up @@ -161,6 +161,8 @@ func deserialize_scalar*(dst: var matchingOrderBigInt(Banderwagon), src: array[3
return status
return cttCodecScalar_Success

## ############################################################
##
## Banderwagon Batch Serialization
##
## ############################################################
Expand Down

0 comments on commit 7ac17bc

Please sign in to comment.