mirror of
https://github.com/logos-storage/constantine.git
synced 2026-01-02 21:23:11 +00:00
148 lines
4.1 KiB
Nim
148 lines
4.1 KiB
Nim
# 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
|
|
../config/common,
|
|
../primitives,
|
|
../arithmetic
|
|
|
|
# Note: to avoid burdening the Nim compiler, we rely on generic extension
|
|
# to complain if the base field procedures don't exist
|
|
|
|
# Common type definition
|
|
# -------------------------------------------------------------------
|
|
|
|
type
|
|
β* = object
|
|
## Non-Residue β
|
|
##
|
|
## Placeholder for the appropriate quadratic or cubic non-residue
|
|
|
|
CubicExt* = concept x
|
|
## Cubic Extension field concept
|
|
type BaseField = auto
|
|
x.c0 is BaseField
|
|
x.c1 is BaseField
|
|
x.c2 is BaseField
|
|
|
|
QuadraticExt* = concept x
|
|
## Quadratic Extension field concept
|
|
not(x is CubicExt)
|
|
|
|
type BaseField = auto
|
|
x.c0 is BaseField
|
|
x.c1 is BaseField
|
|
|
|
ExtensionField = QuadraticExt or CubicExt
|
|
|
|
# Initialization
|
|
# -------------------------------------------------------------------
|
|
|
|
func setZero*(a: var ExtensionField) =
|
|
## Set ``a`` to 0 in the extension field
|
|
for field in fields(a):
|
|
field.setZero()
|
|
|
|
func setOne*(a: var ExtensionField) =
|
|
## Set ``a`` to 1 in the extension field
|
|
for fieldName, fA in fieldPairs(a):
|
|
when fieldName == "c0":
|
|
fA.setOne()
|
|
else:
|
|
fA.setZero()
|
|
|
|
# Comparison
|
|
# -------------------------------------------------------------------
|
|
|
|
func `==`*(a, b: ExtensionField): SecretBool =
|
|
## Constant-time equality check
|
|
result = CtTrue
|
|
for fA, fB in fields(a, b):
|
|
result = result and (fA == fB)
|
|
|
|
func isZero*(a: ExtensionField): SecretBool =
|
|
## Constant-time check if zero
|
|
result = CtTrue
|
|
for fA in fields(a):
|
|
result = result and fA.isZero()
|
|
|
|
func isOne*(a: ExtensionField): SecretBool =
|
|
## Constant-time check if one
|
|
result = CtTrue
|
|
for fieldName, fA in fieldPairs(a):
|
|
when fieldName == "c0":
|
|
result = result and fA.isOne()
|
|
else:
|
|
result = result and fA.isZero()
|
|
|
|
# Copies
|
|
# -------------------------------------------------------------------
|
|
|
|
func ccopy*(a: var ExtensionField, b: ExtensionField, ctl: SecretBool) =
|
|
## Constant-time conditional copy
|
|
## If ctl is true: b is copied into a
|
|
## if ctl is false: b is not copied and a is unmodified
|
|
## Time and memory accesses are the same whether a copy occurs or not
|
|
for fA, fB in fields(a, b):
|
|
ccopy(fA, fB, ctl)
|
|
|
|
# Abelian group
|
|
# -------------------------------------------------------------------
|
|
|
|
func neg*(r: var ExtensionField, a: ExtensionField) =
|
|
## Field out-of-place negation
|
|
for fR, fA in fields(r, a):
|
|
fR.neg(fA)
|
|
|
|
func `+=`*(a: var ExtensionField, b: ExtensionField) =
|
|
## Addition in the extension field
|
|
for fA, fB in fields(a, b):
|
|
fA += fB
|
|
|
|
func `-=`*(a: var ExtensionField, b: ExtensionField) =
|
|
## Substraction in the extension field
|
|
for fA, fB in fields(a, b):
|
|
fA -= fB
|
|
|
|
func double*(r: var ExtensionField, a: ExtensionField) =
|
|
## Field out-of-place doubling
|
|
for fR, fA in fields(r, a):
|
|
fR.double(fA)
|
|
|
|
func double*(a: var ExtensionField) =
|
|
## Field in-place doubling
|
|
for fA in fields(a):
|
|
fA.double()
|
|
|
|
func div2*(a: var ExtensionField) =
|
|
## Field in-place division by 2
|
|
for fA in fields(a):
|
|
fA.div2()
|
|
|
|
func sum*(r: var QuadraticExt, a, b: QuadraticExt) =
|
|
## Sum ``a`` and ``b`` into ``r``
|
|
r.c0.sum(a.c0, b.c0)
|
|
r.c1.sum(a.c1, b.c1)
|
|
|
|
func sum*(r: var CubicExt, a, b: CubicExt) =
|
|
## Sum ``a`` and ``b`` into ``r``
|
|
r.c0.sum(a.c0, b.c0)
|
|
r.c1.sum(a.c1, b.c1)
|
|
r.c2.sum(a.c2, b.c2)
|
|
|
|
func diff*(r: var QuadraticExt, a, b: QuadraticExt) =
|
|
## Diff ``a`` and ``b`` into ``r``
|
|
r.c0.diff(a.c0, b.c0)
|
|
r.c1.diff(a.c1, b.c1)
|
|
|
|
func diff*(r: var CubicExt, a, b: CubicExt) =
|
|
## Diff ``a`` and ``b`` into ``r``
|
|
r.c0.diff(a.c0, b.c0)
|
|
r.c1.diff(a.c1, b.c1)
|
|
r.c2.diff(a.c2, b.c2)
|