# # the prime fields Fp and Fr with sizes # # p = 21888242871839275222246405745257275088696311157297823662689037894645226208583 # r = 21888242871839275222246405745257275088548364400416034343698204186575808495617 # import sugar import std/bitops import std/sequtils import constantine/math/arithmetic import constantine/math/io/io_fields import constantine/math/io/io_bigints import constantine/named/properties_fields as tff import constantine/math/extension_fields/towers as ext #------------------------------------------------------------------------------- type B* = BigInt[256] func mkFp2* (i: Fp[BN254_Snarks], u: Fp[BN254_Snarks]) : Fp2[BN254_Snarks] = let c : array[2, Fp[BN254_Snarks]] = [i,u] return ext.QuadraticExt[Fp[BN254_Snarks]]( coords: c ) #------------------------------------------------------------------------------- const primeR* : B = fromHex( B, "0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001", bigEndian ) const primeP* : B = fromHex( B, "0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47", bigEndian ) #------------------------------------------------------------------------------- const zeroFp* = fromHex( Fp[BN254_Snarks], "0x00" ) const zeroFr* = fromHex( Fr[BN254_Snarks], "0x00" ) const oneFp* = fromHex( Fp[BN254_Snarks], "0x01" ) const oneFr* = fromHex( Fr[BN254_Snarks], "0x01" ) const zeroFp2* = mkFp2( zeroFp, zeroFp ) const oneFp2* = mkFp2( oneFp , zeroFp ) const minusOneFp* = fromHex( Fp[BN254_Snarks], "0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd46" ) const minusOneFr* = fromHex( Fr[BN254_Snarks], "0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000" ) #------------------------------------------------------------------------------- func intToB*(a: uint): B = var y : B y.setUint(a) return y func intToFp*(a: int): Fp[BN254_Snarks] = var y : Fp[BN254_Snarks] y.fromInt(a) return y func intToFr*(a: int): Fr[BN254_Snarks] = var y : Fr[BN254_Snarks] y.fromInt(a) return y #------------------------------------------------------------------------------- func isZeroFp* (x: Fp ): bool = bool(isZero(x)) func isZeroFp2*(x: Fp2): bool = bool(isZero(x)) func isZeroFr* (x: Fr ): bool = bool(isZero(x)) func isEqualFp* (x, y: Fp ): bool = bool(x == y) func isEqualFp2*(x, y: Fp2): bool = bool(x == y) func isEqualFr* (x, y: Fr ): bool = bool(x == y) func `===`*(x, y: Fp ): bool = isEqualFp(x,y) func `===`*(x, y: Fp2): bool = isEqualFp2(x,y) func `===`*(x, y: Fr ): bool = isEqualFr(x,y) #------------------- func isEqualFpSeq*(xs, ys: seq[Fp]): bool = let n = xs.len assert( n == ys.len ) var b = true for i in 0.. 0): if bitand(e,1) > 0: a *= s e = (e shr 1) square(s) return a func smallPowFr*(base: Fr, expo: int): Fr = if expo >= 0: return smallPowFr( base, uint(expo) ) else: return smallPowFr( invFr(base) , uint(-expo) ) #------------------------------------------------------------------------------- func deltaFr*[T](i, j: int) : Fr[T] = return (if (i == j): oneFr else: zeroFr) #------------------------------------------------------------------------------- # Montgomery batch inversion func batchInverseFr*( xs: seq[Fr[BN254_Snarks]] ) : seq[Fr[BN254_Snarks]] = let n = xs.len assert(n>0) var us : seq[Fr[BN254_Snarks]] = newSeq[Fr[BN254_Snarks]](n+1) var a = xs[0] us[0] = oneFr us[1] = a for i in 1..