Skip to content

Commit

Permalink
FFT + Trusted setup fixes (#254)
Browse files Browse the repository at this point in the history
* FFT fixes

* trusted setup fixes
  • Loading branch information
mratsim authored Aug 27, 2023
1 parent f57d071 commit 8b43b55
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 9 deletions.
19 changes: 13 additions & 6 deletions constantine/math/polynomials/fft.nim
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import
../config/curves,
../arithmetic,
../io/io_bigints,
../ec_shortweierstrass,
../elliptic/ec_scalar_mul_vartime,
../../platforms/[abstractions, allocs, views]
Expand Down Expand Up @@ -47,12 +48,15 @@ func computeRootsOfUnity[EC](ctx: var ECFFT_Descriptor[EC], generatorRootOfUnity

doAssert ctx.rootsOfUnity[ctx.order].isOne().bool()

func new(T: type ECFFT_Descriptor, order: int, generatorRootOfUnity: auto): T =
func new*(T: type ECFFT_Descriptor, order: int, generatorRootOfUnity: auto): T =
result.order = order
result.rootsOfUnity = allocHeapArrayAligned(matchingOrderBigInt(T.EC.F.C), order+1, alignment = 64)

result.computeRootsOfUnity(generatorRootOfUnity)

func delete*(ctx: ECFFT_Descriptor) =
ctx.rootsOfUnity.freeHeapAligned()

func simpleFT[EC; bits: static int](
output: var StridedView[EC],
vals: StridedView[EC],
Expand Down Expand Up @@ -135,13 +139,12 @@ func ifft*[EC](
var voutput = output.toStridedView()
fft_internal(voutput, vals.toStridedView(), rootz)

var invLen {.noInit.}: Fr[EC.F.C]
var invLen {.noInit.}: matchingOrderBigInt(EC.F.C)
invLen.fromUint(vals.len.uint64)
invLen.inv_vartime()
let inv = invLen.toBig()
invLen.invmod_vartime(invLen, EC.F.C.getCurveOrder())

for i in 0 ..< output.len:
output[i].scalarMul_minHammingWeight_windowed_vartime(inv, window = 5)
output[i].scalarMul_minHammingWeight_windowed_vartime(invLen, window = 5)

return FFTS_Success

Expand Down Expand Up @@ -221,7 +224,7 @@ func bit_reversal_permutation*[T](buf: var openArray[T]) =
# Instead we swap B and T to save the overwritten slot.
#
# Due to bitreversal being an involution, we can redo the first loop
# to place the overwritten data in there corect slot.
# to place the overwritten data in its correct slot.
#
# Hence
#
Expand Down Expand Up @@ -349,6 +352,8 @@ when isMainModule:

proc roundtrip() =
let fftDesc = ECFFT_Descriptor[EC_G1].new(order = 1 shl 4, ctt_eth_kzg_fr_pow2_roots_of_unity[4])
defer: fftDesc.delete()

var data = newSeq[EC_G1](fftDesc.order)
data[0].fromAffine(BLS12_381.getGenerator("G1"))
for i in 1 ..< fftDesc.order:
Expand Down Expand Up @@ -417,6 +422,8 @@ when isMainModule:
let ns = inNanoseconds((stop-start) div NumIters)
echo &"FFT scale {scale:>2} {ns:>8} ns/op"

fftDesc.delete()


proc bit_reversal() =
let k = 28
Expand Down
10 changes: 7 additions & 3 deletions constantine/trusted_setups/gen_eth_kzg_testing_setups.nim
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,10 @@ proc genEthereumKzgTestingTrustedSetup(filepath: string, secret: auto, length: i
f.write uint8 0

# Protocol
f.write"ethereum_deneb_kzg"
const protocol = "ethereum_deneb_kzg"
f.write protocol
let padProtocol = default(array[32 - protocol.len, byte]) # zero-init padding
f.writeData(padProtocol[0].unsafeAddr, padProtocol.len)

# Curve
const curve = "bls12_381"
Expand Down Expand Up @@ -203,6 +206,7 @@ proc genEthereumKzgTestingTrustedSetup(filepath: string, secret: auto, length: i
# Projective coordinates are slightly faster than jacobian on 𝔾1
var fftDesc = ECFFTDescriptor[ECP_ShortW_Prj[Fp[BLS12_381], G1]].new(
order = length, ctt_eth_kzg_fr_pow2_roots_of_unity[log2_vartime(length.uint)])
defer: fftDesc.delete()

block: # Metadata 3 - roots of unity - bit-reversal permuted
var meta: array[32, byte]
Expand All @@ -224,7 +228,7 @@ proc genEthereumKzgTestingTrustedSetup(filepath: string, secret: auto, length: i

f.padNUL64()

block: # Data 2 - srs 𝔾2 points - bit-reversal permuted
block: # Data 2 - srs 𝔾2 points
const g2Length = 65
let ts2 = ECP_ShortW_Aff[Fp2[BLS12_381], G2].newTrustedSetupMonomial(secret, g2Length)
# Raw dump requires little-endian
Expand All @@ -233,7 +237,7 @@ proc genEthereumKzgTestingTrustedSetup(filepath: string, secret: auto, length: i
f.padNUL64()

bit_reversal_permutation(fftDesc.rootsOfUnity.toOpenArray(0, fftDesc.order-1))
block: # Data 2 - roots of unity - bit-reversal permuted
block: # Data 3 - roots of unity - bit-reversal permuted
# Raw dump requires little-endian
f.writeData(fftDesc.rootsOfUnity, sizeof(fftDesc.rootsOfUnity[0]) * fftDesc.order)

Expand Down
Binary file not shown.
Binary file not shown.

0 comments on commit 8b43b55

Please sign in to comment.