# # 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/math/config/curves import constantine/math/config/type_ff as tff import constantine/math/extension_fields/towers as ext #------------------------------------------------------------------------------- type B* = BigInt[256] type Fr* = tff.Fr[BN254Snarks] type Fp* = tff.Fp[BN254Snarks] type Fp2* = ext.QuadraticExt[Fp] type Fp12* = ext.Fp12[BN254Snarks] func mkFp2* (i: Fp, u: Fp) : Fp2 = let c : array[2, Fp] = [i,u] return ext.QuadraticExt[Fp]( coords: c ) #------------------------------------------------------------------------------- const primeP* : B = fromHex( B, "0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47", bigEndian ) const primeR* : B = fromHex( B, "0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001", bigEndian ) #------------------------------------------------------------------------------- const zeroFp* : Fp = fromHex( Fp, "0x00" ) const zeroFr* : Fr = fromHex( Fr, "0x00" ) const oneFp* : Fp = fromHex( Fp, "0x01" ) const oneFr* : Fr = fromHex( Fr, "0x01" ) const zeroFp2* : Fp2 = mkFp2( zeroFp, zeroFp ) const oneFp2* : Fp2 = mkFp2( oneFp , zeroFp ) #------------------------------------------------------------------------------- func intToB*(a: uint): B = var y : B y.setUint(a) return y func intToFp*(a: int): Fp = var y : Fp y.fromInt(a) return y func intToFr*(a: int): Fr = var y : Fr 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*(i, j: int) : Fr = return (if (i == j): oneFr else: zeroFr) #------------------------------------------------------------------------------- # Montgomery batch inversion func batchInverseFr*( xs: seq[Fr] ) : seq[Fr] = let n = xs.len assert(n>0) var us : seq[Fr] = newSeq[Fr](n+1) var a = xs[0] us[0] = oneFr us[1] = a for i in 1..