parent
f57d071f11
commit
8b43b55345
|
@ -9,6 +9,7 @@
|
||||||
import
|
import
|
||||||
../config/curves,
|
../config/curves,
|
||||||
../arithmetic,
|
../arithmetic,
|
||||||
|
../io/io_bigints,
|
||||||
../ec_shortweierstrass,
|
../ec_shortweierstrass,
|
||||||
../elliptic/ec_scalar_mul_vartime,
|
../elliptic/ec_scalar_mul_vartime,
|
||||||
../../platforms/[abstractions, allocs, views]
|
../../platforms/[abstractions, allocs, views]
|
||||||
|
@ -47,12 +48,15 @@ func computeRootsOfUnity[EC](ctx: var ECFFT_Descriptor[EC], generatorRootOfUnity
|
||||||
|
|
||||||
doAssert ctx.rootsOfUnity[ctx.order].isOne().bool()
|
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.order = order
|
||||||
result.rootsOfUnity = allocHeapArrayAligned(matchingOrderBigInt(T.EC.F.C), order+1, alignment = 64)
|
result.rootsOfUnity = allocHeapArrayAligned(matchingOrderBigInt(T.EC.F.C), order+1, alignment = 64)
|
||||||
|
|
||||||
result.computeRootsOfUnity(generatorRootOfUnity)
|
result.computeRootsOfUnity(generatorRootOfUnity)
|
||||||
|
|
||||||
|
func delete*(ctx: ECFFT_Descriptor) =
|
||||||
|
ctx.rootsOfUnity.freeHeapAligned()
|
||||||
|
|
||||||
func simpleFT[EC; bits: static int](
|
func simpleFT[EC; bits: static int](
|
||||||
output: var StridedView[EC],
|
output: var StridedView[EC],
|
||||||
vals: StridedView[EC],
|
vals: StridedView[EC],
|
||||||
|
@ -135,13 +139,12 @@ func ifft*[EC](
|
||||||
var voutput = output.toStridedView()
|
var voutput = output.toStridedView()
|
||||||
fft_internal(voutput, vals.toStridedView(), rootz)
|
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.fromUint(vals.len.uint64)
|
||||||
invLen.inv_vartime()
|
invLen.invmod_vartime(invLen, EC.F.C.getCurveOrder())
|
||||||
let inv = invLen.toBig()
|
|
||||||
|
|
||||||
for i in 0 ..< output.len:
|
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
|
return FFTS_Success
|
||||||
|
|
||||||
|
@ -221,7 +224,7 @@ func bit_reversal_permutation*[T](buf: var openArray[T]) =
|
||||||
# Instead we swap B and T to save the overwritten slot.
|
# Instead we swap B and T to save the overwritten slot.
|
||||||
#
|
#
|
||||||
# Due to bitreversal being an involution, we can redo the first loop
|
# 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
|
# Hence
|
||||||
#
|
#
|
||||||
|
@ -349,6 +352,8 @@ when isMainModule:
|
||||||
|
|
||||||
proc roundtrip() =
|
proc roundtrip() =
|
||||||
let fftDesc = ECFFT_Descriptor[EC_G1].new(order = 1 shl 4, ctt_eth_kzg_fr_pow2_roots_of_unity[4])
|
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)
|
var data = newSeq[EC_G1](fftDesc.order)
|
||||||
data[0].fromAffine(BLS12_381.getGenerator("G1"))
|
data[0].fromAffine(BLS12_381.getGenerator("G1"))
|
||||||
for i in 1 ..< fftDesc.order:
|
for i in 1 ..< fftDesc.order:
|
||||||
|
@ -417,6 +422,8 @@ when isMainModule:
|
||||||
let ns = inNanoseconds((stop-start) div NumIters)
|
let ns = inNanoseconds((stop-start) div NumIters)
|
||||||
echo &"FFT scale {scale:>2} {ns:>8} ns/op"
|
echo &"FFT scale {scale:>2} {ns:>8} ns/op"
|
||||||
|
|
||||||
|
fftDesc.delete()
|
||||||
|
|
||||||
|
|
||||||
proc bit_reversal() =
|
proc bit_reversal() =
|
||||||
let k = 28
|
let k = 28
|
||||||
|
|
|
@ -167,7 +167,10 @@ proc genEthereumKzgTestingTrustedSetup(filepath: string, secret: auto, length: i
|
||||||
f.write uint8 0
|
f.write uint8 0
|
||||||
|
|
||||||
# Protocol
|
# 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
|
# Curve
|
||||||
const curve = "bls12_381"
|
const curve = "bls12_381"
|
||||||
|
@ -203,6 +206,7 @@ proc genEthereumKzgTestingTrustedSetup(filepath: string, secret: auto, length: i
|
||||||
# Projective coordinates are slightly faster than jacobian on 𝔾1
|
# Projective coordinates are slightly faster than jacobian on 𝔾1
|
||||||
var fftDesc = ECFFTDescriptor[ECP_ShortW_Prj[Fp[BLS12_381], G1]].new(
|
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)])
|
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
|
block: # Metadata 3 - roots of unity - bit-reversal permuted
|
||||||
var meta: array[32, byte]
|
var meta: array[32, byte]
|
||||||
|
@ -224,7 +228,7 @@ proc genEthereumKzgTestingTrustedSetup(filepath: string, secret: auto, length: i
|
||||||
|
|
||||||
f.padNUL64()
|
f.padNUL64()
|
||||||
|
|
||||||
block: # Data 2 - srs 𝔾2 points - bit-reversal permuted
|
block: # Data 2 - srs 𝔾2 points
|
||||||
const g2Length = 65
|
const g2Length = 65
|
||||||
let ts2 = ECP_ShortW_Aff[Fp2[BLS12_381], G2].newTrustedSetupMonomial(secret, g2Length)
|
let ts2 = ECP_ShortW_Aff[Fp2[BLS12_381], G2].newTrustedSetupMonomial(secret, g2Length)
|
||||||
# Raw dump requires little-endian
|
# Raw dump requires little-endian
|
||||||
|
@ -233,7 +237,7 @@ proc genEthereumKzgTestingTrustedSetup(filepath: string, secret: auto, length: i
|
||||||
f.padNUL64()
|
f.padNUL64()
|
||||||
|
|
||||||
bit_reversal_permutation(fftDesc.rootsOfUnity.toOpenArray(0, fftDesc.order-1))
|
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
|
# Raw dump requires little-endian
|
||||||
f.writeData(fftDesc.rootsOfUnity, sizeof(fftDesc.rootsOfUnity[0]) * fftDesc.order)
|
f.writeData(fftDesc.rootsOfUnity, sizeof(fftDesc.rootsOfUnity[0]) * fftDesc.order)
|
||||||
|
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue