Estou muito orgulhoso de lançar a primeira versão do Constantine, uma pilha de criptografia modular de alto desempenho para blockchains e sistemas de prova.
Atualmente, em julho de 2024, é a implementação mais rápida de primitivas criptográficas específicas do Ethereum:
- Assinaturas BLS
- Pré-compilações BN254 (EIP-196 e EIP-197, reavaliadas em EIP-1108)
- Pré-compilações BLS12-381 (EIP-2537)
- Compromissos polinomiais KZG (EIP-4844)
Constantine possui ligações em C, Go, Nim e Rust.
História
Constantine é escrito em Nim, a linguagem foi escolhida pela Status para Nimbus por sua expressividade, força do sistema de tipos, facilidade de encapsular C e C++ e proximidade sintática com Python para que ethereum/research e PyEVM pudessem ser portados com facilidade.
Em fevereiro de 2018, após problemas com C++ no Nimbus, a primeira biblioteca que construí foi uma biblioteca de números inteiros grandes de precisão fixa para uint256.
Então nós (na Status) percebemos que também precisaríamos de curvas elípticas para secp256k1 e BN254 (também conhecido como BN256 ou alt_bn128).
Quão difícil seria implementar curvas elípticas, com proteção criptográfica, uma vez que você soubesse escrever números inteiros grandes?
Acontece que era muito difícil, depois de uma semana ou mais, outra abordagem foi adotada por motivos de tempo de lançamento no mercado e correção:
- Use libsecp256k1 do Bitcoin
- Porta 1-1 bncurves de Zcash para BN254
- Use Apache Milagro para BLS12-381
Ele foi então reiniciado como um projeto paralelo pessoal em fevereiro de 2020, depois de aprender muito com a implementação de hashing-to-curve e assinaturas Ethereum BLS e identificar uma lacuna significativa de desempenho. Observe que isso é anterior ao BLST, que foi lançado inicialmente em junho de 2020.
Desde então, Constantine tem visto contribuições regulares (às vezes com intervalos de alguns meses) até onde está hoje.
Desempenho
Assinaturas Ethereum BLS (camada de consenso)
Os benchmarks são feitos em um AMD Ryzen 7840U, uma CPU ultramóvel de 8 núcleos de baixo consumo de 2023.
BLST (através de nim-blscurve)
Nim-blscurve é o backend do Nimbus-eth2. Como o Nim compila para código de máquina por meio de C (ou C++), chamar C tem sobrecarga zero do Nim.
Repro.
Instale a versão mais recente do Nim, Nim v2.0.8.
git clone https://github.com/status-im/nim-blscurve
cd nim-blscurve
git submodule update --init
nimble bench
2 benchmarks serão feitos com 2 soluções diferentes de gerenciamento de memória (diferentes implementações de recontagem)
BLST é v0.3.12 (maio de 2024) com detecção de recursos de CPU em tempo de execução
Backend: BLST, mode: 64-bit
====================================================================================================================================
Scalar multiplication G1 (255-bit, constant-time) 10332.180 ops/s 96785 ns/op 318784 cycles
Scalar multiplication G2 (255-bit, constant-time) 4622.247 ops/s 216345 ns/op 712585 cycles
EC add G1 (constant-time) 1795332.136 ops/s 557 ns/op 1836 cycles
EC add G2 (constant-time) 713775.874 ops/s 1401 ns/op 4617 cycles
------------------------------------------------------------------------------------------------------------------------------------
Pairing (Miller loop + Final Exponentiation) 1484.823 ops/s 673481 ns/op 2218271 cycles
------------------------------------------------------------------------------------------------------------------------------------
Hash to G2 (Draft #9) + affine conversion 6795.232 ops/s 147162 ns/op 484712 cycles
------------------------------------------------------------------------------------------------------------------------------------
BLS signature 3490.864 ops/s 286462 ns/op 943532 cycles
BLS verification 1212.302 ops/s 824877 ns/op 2716928 cycles
BLS agg verif of 1 msg by 128 pubkeys 1139.886 ops/s 877281 ns/op 2889519 cycles
------------------------------------------------------------------------------------------------------------------------------------
BLS verif of 6 msgs by 6 pubkeys 203.231 ops/s 4920498 ns/op 16206824 cycles
Serial batch verify 6 msgs by 6 pubkeys (with blinding) 359.968 ops/s 2778025 ns/op 9150078 cycles
Parallel batch verify of 6 msgs by 6 pubkeys (with blinding) 615.452 ops/s 1624822 ns/op 5351722 cycles
------------------------------------------------------------------------------------------------------------------------------------
BLS verif of 60 msgs by 60 pubkeys 20.310 ops/s 49236672 ns/op 162172626 cycles
Serial batch verify 60 msgs by 60 pubkeys (with blinding) 42.709 ops/s 23414406 ns/op 77120772 cycles
Parallel batch verify of 60 msgs by 60 pubkeys (with blinding) 250.298 ops/s 3995236 ns/op 13159139 cycles
------------------------------------------------------------------------------------------------------------------------------------
BLS verif of 180 msgs by 180 pubkeys 6.746 ops/s 148237745 ns/op 488256390 cycles
Serial batch verify 180 msgs by 180 pubkeys (with blinding) 14.419 ops/s 69354258 ns/op 228434104 cycles
Parallel batch verify of 180 msgs by 180 pubkeys (with blinding) 99.467 ops/s 10053540 ns/op 33113513 cycles
------------------------------------------------------------------------------------------------------------------------------------
Using nthreads = 16. The number of threads can be changed with TP_NUM_THREADS environment variable.
Constantino
O GCC gera código ruim sempre que o assembly não é usado, portanto, forçamos o Clang como um compilador.
git clone https://github.com/mratsim/constantine
cd constantine
CC=clang nimble bench_eth_bls_signatures
--------------------------------------------------------------------------------------------------------------------------------------------------
Pubkey deserialization (full checks) BLS12_381 G1 22295.550 ops/s 44852 ns/op 147729 CPU cycles (approx)
Pubkey deserialization (skip checks) BLS12_381 G1 92515.496 ops/s 10809 ns/op 35602 CPU cycles (approx)
Signature deserialization (full checks) BLS12_381 G2 16808.418 ops/s 59494 ns/op 195958 CPU cycles (approx)
Signature deserialization (skip checks) BLS12_381 G2 46453.291 ops/s 21527 ns/op 70906 CPU cycles (approx)
--------------------------------------------------------------------------------------------------------------------------------------------------
BLS signature BLS12_381 G2 4005.078 ops/s 249683 ns/op 822392 CPU cycles (approx)
BLS verification BLS12_381 1498.960 ops/s 667129 ns/op 2197347 CPU cycles (approx)
--------------------------------------------------------------------------------------------------------------------------------------------------
BLS agg verif of 1 msg by 128 pubkeys BLS12_381 1423.694 ops/s 702398 ns/op 2313504 CPU cycles (approx)
--------------------------------------------------------------------------------------------------------------------------------------------------
BLS verif of 6 msgs by 6 pubkeys BLS12_381 249.683 ops/s 4005085 ns/op 13191614 CPU cycles (approx)
BLS serial batch verify of 6 msgs by 6 pubkeys (with blinding) BLS12_381 420.912 ops/s 2375795 ns/op 7825187 CPU cycles (approx)
BLS parallel batch verify (16 threads) of 6 msgs by 6 pubkeys (with blinding) BLS12_381 683.399 ops/s 1463273 ns/op 4819062 CPU cycles (approx)
--------------------------------------------------------------------------------------------------------------------------------------------------
BLS verif of 60 msgs by 60 pubkeys BLS12_381 24.863 ops/s 40220998 ns/op 132477024 CPU cycles (approx)
BLS serial batch verify of 60 msgs by 60 pubkeys (with blinding) BLS12_381 48.878 ops/s 20459201 ns/op 67387049 CPU cycles (approx)
BLS parallel batch verify (16 threads) of 60 msgs by 60 pubkeys (with blinding) BLS12_381 280.961 ops/s 3559207 ns/op 11722847 CPU cycles (approx)
--------------------------------------------------------------------------------------------------------------------------------------------------
BLS verif of 180 msgs by 180 pubkeys BLS12_381 8.334 ops/s 119995222 ns/op 395232558 CPU cycles (approx)
BLS serial batch verify of 180 msgs by 180 pubkeys (with blinding) BLS12_381 16.488 ops/s 60650899 ns/op 199767961 CPU cycles (approx)
BLS parallel batch verify (16 threads) of 180 msgs by 180 pubkeys (with blinding) BLS12_381 112.215 ops/s 8911481 ns/op 29351939 CPU cycles (approx)
--------------------------------------------------------------------------------------------------------------------------------------------------
Análise
- Melhoria de desempenho de 15% nas assinaturas
- Melhoria de desempenho de 24% na verificação
Além disso, é em teoria possível obter uma melhoria de desempenho de 2x na assinatura, se houver necessidade.
Compromisso polinomial KZG para EIP-4844 (camada de consenso)
Vou reutilizar meus benchmarks de dezembro de 2023: Productionize KZG EIP-4844 por mratsim · Pull Request #304 · mratsim/constantine · GitHub
| Banco | c-kzg-4844 (série) | go-kzg-4844 (série) | go-kzg-4844 (paralelo) | Constantino (série) | Constantino (paralelo) |
|---|---|---|---|---|---|
| blob_to_kzg_commitment | 37,773ms | – | 5,823ms | 23,765ms | 4,425ms |
| computar_kzg_proof | 39,945ms | – | 7,146ms | 24,255ms | 4,710ms |
| computar_blob_kzg_proof | 40,212ms | – | 7,205ms | 24,288ms | 4,794ms |
| verificar_kzg_proof | 0,915ms | 0,923ms | – | 0,782ms | – |
| verificar_blob_kzg_proof | 1,531ms | – | 1,390ms | 1,266ms | 1,113ms |
| verificar_blob_kzg_proof_batch 1 | 1,528ms | 1,392ms | 1,405ms | 1,286ms | 1,130ms |
| verificar_blob_kzg_proof_batch 2 | 2,589ms | 3,233ms | 1,591ms | 2,006ms | 1,152ms |
| verificar_blob_kzg_proof_batch 4 | 4,553ms | 4,671ms | 1,914ms | 3,437ms | 1.250ms |
| verificar_blob_kzg_proof_batch 8 | 8,446ms | 7,410ms | 2,738ms | 6,115ms | 1,891ms |
| verificar_blob_kzg_proof_batch 16 | 16,228ms | 12,734ms | 3,542ms | 11,567ms | 3,091ms |
| verificar_blob_kzg_proof_batch 32 | 32,016ms | 23,048ms | 7,215ms | 21,779ms | 6,764ms |
| verificar_blob_kzg_proof_batch 64 | 63,415ms | 43,224ms | 14,438ms | 43,099ms | 11,538ms |
- Uma melhoria de desempenho de 37% em relação ao c-kzg-4844 para comprometimento serial
- Uma melhoria de 39% na geração de provas
- Uma melhoria de 17% para uma verificação de blob único
- Uma melhoria de 32% na verificação de 64 blobs
E Constantine oferece paralelização para melhorar esses números de 4 a 6x na minha máquina de 8 núcleos.
Pré-compilações EVM (camada de execução)
Observação:
- Constantine também oferece uma pré-compilação MODEXP rápida que atinge 80% a 110% de GMP, sem montagem.
- SHA256 é mais rápido que OpenSSL e BLST para tamanhos de dados inferiores a 4 MB e dentro de 3% caso contrário.
git clone https://github.com/mratsim/constantine
cd constantine
CC=clang nimble bench_eth_evm_precompiles
--------------------------------------------------------------------------------------------------------------------------------
SHA256 - 32 bytes 72 gas 1714.29 MGas/s 23809523.810 ops/s 42 ns/op 140 CPU cycles (approx)
SHA256 - 64 bytes 84 gas 1584.91 MGas/s 18867924.528 ops/s 53 ns/op 176 CPU cycles (approx)
SHA256 - 96 bytes 96 gas 1777.78 MGas/s 18518518.519 ops/s 54 ns/op 179 CPU cycles (approx)
SHA256 - 128 bytes 108 gas 1333.33 MGas/s 12345679.012 ops/s 81 ns/op 267 CPU cycles (approx)
SHA256 - 160 bytes 120 gas 1481.48 MGas/s 12345679.012 ops/s 81 ns/op 268 CPU cycles (approx)
SHA256 - 192 bytes 132 gas 1233.64 MGas/s 9345794.393 ops/s 107 ns/op 353 CPU cycles (approx)
SHA256 - 224 bytes 144 gas 1321.10 MGas/s 9174311.927 ops/s 109 ns/op 359 CPU cycles (approx)
SHA256 - 256 bytes 156 gas 1130.43 MGas/s 7246376.812 ops/s 138 ns/op 454 CPU cycles (approx)
--------------------------------------------------------------------------------------------------------------------------------
BN254_G1ADD 150 gas 87.41 MGas/s 582750.583 ops/s 1716 ns/op 5652 CPU cycles (approx)
BN254_G1MUL 6000 gas 229.66 MGas/s 38276.047 ops/s 26126 ns/op 86050 CPU cycles (approx)
--------------------------------------------------------------------------------------------------------------------------------
BN254_PAIRINGCHECK 1 79000 gas 166.99 MGas/s 2113.754 ops/s 473092 ns/op 1558009 CPU cycles (approx)
BN254_PAIRINGCHECK 2 113000 gas 191.99 MGas/s 1699.056 ops/s 588562 ns/op 1938370 CPU cycles (approx)
BN254_PAIRINGCHECK 3 147000 gas 183.15 MGas/s 1245.930 ops/s 802613 ns/op 2642801 CPU cycles (approx)
BN254_PAIRINGCHECK 4 181000 gas 191.76 MGas/s 1059.434 ops/s 943900 ns/op 3108745 CPU cycles (approx)
BN254_PAIRINGCHECK 5 215000 gas 169.72 MGas/s 789.374 ops/s 1266827 ns/op 4171120 CPU cycles (approx)
BN254_PAIRINGCHECK 6 249000 gas 181.10 MGas/s 727.321 ops/s 1374909 ns/op 4528210 CPU cycles (approx)
BN254_PAIRINGCHECK 7 283000 gas 189.03 MGas/s 667.965 ops/s 1497084 ns/op 4930714 CPU cycles (approx)
BN254_PAIRINGCHECK 8 317000 gas 204.18 MGas/s 644.095 ops/s 1552566 ns/op 5113680 CPU cycles (approx)
--------------------------------------------------------------------------------------------------------------------------------
BLS12_G1ADD 500 gas 164.10 MGas/s 328191.664 ops/s 3047 ns/op 10034 CPU cycles (approx)
BLS12_G2ADD 800 gas 161.75 MGas/s 202183.583 ops/s 4946 ns/op 16289 CPU cycles (approx)
BLS12_G1MUL 12000 gas 141.66 MGas/s 11805.400 ops/s 84707 ns/op 279001 CPU cycles (approx)
BLS12_G2MUL 45000 gas 325.51 MGas/s 7233.639 ops/s 138243 ns/op 455333 CPU cycles (approx)
BLS12_MAP_FP_TO_G1 5500 gas 161.82 MGas/s 29422.149 ops/s 33988 ns/op 111947 CPU cycles (approx)
BLS12_MAP_FP2_TO_G2 75000 gas 659.96 MGas/s 8799.486 ops/s 113643 ns/op 374305 CPU cycles (approx)
--------------------------------------------------------------------------------------------------------------------------------
BLS12_PAIRINGCHECK 1 108000 gas 216.83 MGas/s 2007.665 ops/s 498091 ns/op 1640562 CPU cycles (approx)
BLS12_PAIRINGCHECK 2 151000 gas 222.00 MGas/s 1470.214 ops/s 680173 ns/op 2240287 CPU cycles (approx)
BLS12_PAIRINGCHECK 3 194000 gas 219.98 MGas/s 1133.901 ops/s 881911 ns/op 2904762 CPU cycles (approx)
BLS12_PAIRINGCHECK 4 237000 gas 222.97 MGas/s 940.782 ops/s 1062946 ns/op 3500927 CPU cycles (approx)
BLS12_PAIRINGCHECK 5 280000 gas 221.08 MGas/s 789.576 ops/s 1266502 ns/op 4171417 CPU cycles (approx)
BLS12_PAIRINGCHECK 6 323000 gas 223.09 MGas/s 690.679 ops/s 1447851 ns/op 4768780 CPU cycles (approx)
BLS12_PAIRINGCHECK 7 366000 gas 222.28 MGas/s 607.311 ops/s 1646603 ns/op 5423299 CPU cycles (approx)
BLS12_PAIRINGCHECK 8 409000 gas 221.94 MGas/s 542.640 ops/s 1842844 ns/op 6069597 CPU cycles (approx)
--------------------------------------------------------------------------------------------------------------------------------
BLS12_G1MSM 2 21312 gas 120.40 MGas/s 5649.430 ops/s 177009 ns/op 583004 CPU cycles (approx)
BLS12_G1MSM 4 30768 gas 101.53 MGas/s 3299.960 ops/s 303034 ns/op 998108 CPU cycles (approx)
BLS12_G1MSM 8 43488 gas 81.23 MGas/s 1867.787 ops/s 535393 ns/op 1763434 CPU cycles (approx)
BLS12_G1MSM 16 64128 gas 66.43 MGas/s 1035.864 ops/s 965378 ns/op 3179510 CPU cycles (approx)
BLS12_G1MSM 32 103296 gas 57.99 MGas/s 561.362 ops/s 1781382 ns/op 5867248 CPU cycles (approx)
BLS12_G1MSM 64 170496 gas 50.89 MGas/s 298.504 ops/s 3350039 ns/op 11034035 CPU cycles (approx)
BLS12_G1MSM 128 267264 gas 42.24 MGas/s 158.035 ops/s 6327700 ns/op 20841720 CPU cycles (approx)
--------------------------------------------------------------------------------------------------------------------------------
BLS12_G2MSM 2 79920 gas 269.62 MGas/s 3373.637 ops/s 296416 ns/op 976301 CPU cycles (approx)
BLS12_G2MSM 4 115380 gas 225.12 MGas/s 1951.109 ops/s 512529 ns/op 1688121 CPU cycles (approx)
BLS12_G2MSM 8 163080 gas 177.21 MGas/s 1086.654 ops/s 920256 ns/op 3031066 CPU cycles (approx)
BLS12_G2MSM 16 240480 gas 130.56 MGas/s 542.920 ops/s 1841892 ns/op 6066436 CPU cycles (approx)
BLS12_G2MSM 32 387360 gas 126.36 MGas/s 326.195 ops/s 3065648 ns/op 10097244 CPU cycles (approx)
BLS12_G2MSM 64 639360 gas 118.26 MGas/s 184.965 ops/s 5406423 ns/op 17807268 CPU cycles (approx)
BLS12_G2MSM 128 1002240 gas 100.70 MGas/s 100.471 ops/s 9953136 ns/op 32782906 CPU cycles (approx)
--------------------------------------------------------------------------------------------------------------------------------
Constantine atinge mais de 200Mgas/s para uma ampla gama de pré-compilações criptográficas em uma CPU de laptop com consumo de energia restrito (7840U, 15W a 30W)
observação, sugiro uma reavaliação do EIP-2537 para ajudar os aplicativos SNARKS.
Segurança
Constantine, como o nome indica, como um forte foco na segurança e especialmente na criptografia de tempo constante, é usado por padrão no núcleo da biblioteca.
Ainda NÃO foi auditado, mas passou por extensa difusão por Guido Vranken, graças ao patrocínio da Fundação Ethereum no verão de 2023. Também foi adicionado ao OSS-Fuzz ((assinaturas bls) Remover Chia, adicionar Constantine por guidovranken · Pull Request #10710 · google/oss-fuzz · GitHub), a iniciativa de fuzzing de código aberto 24 horas por dia, 7 dias por semana do Google.
O Futuro
Constantine seguirá e apoiará as futuras necessidades criptográficas da Ethereum. Em particular, agradeço ao Programa de Bolsas e Status da Fundação Ethereum por patrocinar o trabalho na implementação do Verkle Tries em Constantine no ano passado.
Constantine também oferece suporte à aceleração de sistemas à prova de Conhecimento Zero, por exemplo, é possível usá-lo através de PSE (Privacy Scaling Explorations, um ramo da EF) Halo2: ZAL: ZK Accel Layer por mratsim · Pull Request #308 · mratsim/constantine · GitHub.
Constantine tem o MSM mais rápido em x86, todas as bibliotecas avaliadas em julho de 2024 (Arkworks, Barretenberg, Bellman, Gnark, Halo2) e por um fator 2x sobre as populares bibliotecas Rust Arkworks e Halo2. E pretendo construir sistemas de prova por cima.
Hidden in Constantine é um compilador para geração de código GPU e há planos para acelerar o ARM.
Agora não sei como será um EVM snarkificado, mas certamente espero contribuir para torná-lo realidade.
Fontesethresear



