mirror of
https://github.com/logos-storage/constantine.git
synced 2026-01-09 16:43:09 +00:00
* Pairing - initial commit - line functions - sparse Fp12 functions * Small fixes: - Line parametrized by twist for generic algorithm - Add a conjugate operator for quadratic extensions - Have frobenius use it - Create an Affine coordinate type for elliptic curve * Implement (failing) pairing test * Stash pairing debug session, temp switch Fp12 over Fp4 * Proper naive pairing on BLS12-381 * Frobenius map * Implement naive pairing for BN curves * Add pairing tests to CI + reduce time spent on lower-level tests * Test without assembler in Github Actions + less base layers test iterations
108 lines
3.6 KiB
Nim
108 lines
3.6 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
|
||
# Standard library
|
||
std/typetraits,
|
||
# Internal
|
||
./io_bigints, ./io_fields,
|
||
../config/curves,
|
||
../arithmetic/finite_fields,
|
||
../towers
|
||
|
||
# No exceptions allowed
|
||
{.push raises: [].}
|
||
{.push inline.}
|
||
|
||
# ############################################################
|
||
#
|
||
# Parsing from canonical inputs to internal representation
|
||
#
|
||
# ############################################################
|
||
|
||
func appendHex*(accum: var string, f: Fp2 or Fp4 or Fp6 or Fp12, order: static Endianness = bigEndian) =
|
||
## Hex accumulator
|
||
accum.add static($f.typeof.genericHead() & '(')
|
||
for fieldName, fieldValue in fieldPairs(f):
|
||
when fieldName != "c0":
|
||
accum.add ", "
|
||
accum.add fieldName & ": "
|
||
accum.appendHex(fieldValue, order)
|
||
accum.add ")"
|
||
|
||
func toHex*(f: Fp2 or Fp4 or Fp6 or Fp12, order: static Endianness = bigEndian): string =
|
||
## Stringify a tower field element to hex.
|
||
## Note. Leading zeros are not removed.
|
||
## Result is prefixed with 0x
|
||
##
|
||
## Output will be padded with 0s to maintain constant-time.
|
||
##
|
||
## CT:
|
||
## - no leaks
|
||
result.appendHex(f, order)
|
||
|
||
func fromHex*(dst: var Fp2, c0, c1: string) {.raises: [ValueError].}=
|
||
## Convert 2 coordinates to an element of 𝔽p2
|
||
## with dst = c0 + β * c1
|
||
## β is the quadratic non-residue chosen to construct 𝔽p2
|
||
dst.c0.fromHex(c0)
|
||
dst.c1.fromHex(c1)
|
||
|
||
func fromHex*(T: typedesc[Fp2], c0, c1: string): T {.raises: [ValueError].}=
|
||
## Convert 2 coordinates to an element of 𝔽p2
|
||
## with dst = c0 + β * c1
|
||
## β is the quadratic non-residue chosen to construct 𝔽p2
|
||
result.fromHex(c0, c1)
|
||
|
||
func fromHex*(dst: var Fp4,
|
||
c0, c1, c2, c3: string) {.raises: [ValueError].}=
|
||
## Convert 4 coordinates to an element of 𝔽p4
|
||
dst.c0.fromHex(c0, c1)
|
||
dst.c1.fromHex(c2, c3)
|
||
|
||
func fromHex*(T: typedesc[Fp4],
|
||
c0, c1, c2: string,
|
||
c3, c4, c5: string): T {.raises: [ValueError].}=
|
||
## Convert 4 coordinates to an element of 𝔽p4
|
||
result.fromHex(c0, c1, c2, c3)
|
||
|
||
func fromHex*(dst: var Fp6,
|
||
c0, c1, c2: string,
|
||
c3, c4, c5: string) {.raises: [ValueError].}=
|
||
## Convert 6 coordinates to an element of 𝔽p6
|
||
dst.c0.fromHex(c0, c1)
|
||
dst.c1.fromHex(c2, c3)
|
||
dst.c2.fromHex(c4, c5)
|
||
|
||
func fromHex*(T: typedesc[Fp6],
|
||
c0, c1, c2: string,
|
||
c3, c4, c5: string): T {.raises: [ValueError].}=
|
||
## Convert 6 coordinates to an element of 𝔽p6
|
||
result.fromHex(c0, c1, c2, c3, c4, c5)
|
||
|
||
func fromHex*(dst: var Fp12,
|
||
c0, c1, c2, c3: string,
|
||
c4, c5, c6, c7: string,
|
||
c8, c9, c10, c11: string) {.raises: [ValueError].}=
|
||
## Convert 12 coordinates to an element of 𝔽p12
|
||
when Fp12.c0 is Fp6:
|
||
dst.c0.fromHex(c0, c1, c2, c3, c4, c5)
|
||
dst.c1.fromHex(c6, c7, c8, c9, c10, c11)
|
||
else:
|
||
dst.c0.fromHex(c0, c1, c2, c3)
|
||
dst.c1.fromHex(c4, c5, c6, c7)
|
||
dst.c2.fromHex(c8, c9, c10, c11)
|
||
|
||
func fromHex*(T: typedesc[Fp12],
|
||
c0, c1, c2, c3: string,
|
||
c4, c5, c6, c7: string,
|
||
c8, c9, c10, c11: string): T {.raises: [ValueError].}=
|
||
## Convert 12 coordinates to an element of 𝔽p12
|
||
result.fromHex(c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11)
|