-
Notifications
You must be signed in to change notification settings - Fork 1
DeroGold Bulletproofs( ) Concept Draft
Concept Draft v0.3 — March 2026
⚠️ DRAFT — for discussion and community feedback. Not for production deployment.
- Executive Summary
- Honest Assessment — Is This Worth It Right Now?
- Current Codebase State
- Bulletproofs — Technical Primer
- Implementation Plan
- Key Design Decisions
- Security Considerations
- Risks & Mitigations
- Open Questions for Community Discussion
- References
This document presents a concept proposal for integrating Monero-style Bulletproofs into the DeroGold (DEGO) network. DeroGold runs its own derogold-core C++ codebase. Bulletproofs are short, non-interactive zero-knowledge (NIZK) range proofs that require no trusted setup and scale logarithmically with transaction size.
The driver for this change is chain efficiency and reduced blockchain bloat. Under the current CryptoNote range proof model, each transaction output carries proof overhead that grows linearly with the number of outputs. Bulletproofs replace this with a single aggregated proof that grows only O(log n), delivering an estimated 70–80% reduction in transaction size for typical 2-output transactions — mirroring the gains Monero achieved after its October 2018 network upgrade.
DeroGold uses flat transaction fees (MINIMUM_FEE_V2 = 10,000 atomic units at current fork level), independent of transaction size. Fee restructuring is explicitly not part of this proposal.
- ~70–80% reduction in transaction size for standard 2-output transfers
- Faster blockchain sync and lower node bandwidth requirements
- Reduced blockchain storage growth under the 300-second block target
- No change to the flat fee model
- Lays the groundwork for optional confidential amounts in a future version
This section is intentionally placed before the technical detail. The question of whether to implement Bulletproofs is at least as important as how.
Two features landed in the current derogold-core release that directly address the problems Bulletproofs are classically cited as solving:
--sync-from-height — A new node can bootstrap from block 2,700,000 in under 30 minutes, using approximately 1 GB of storage. This completely eliminates the sync and disk-space barrier for new node operators without any cryptographic protocol changes.
Pruning (--prune) — Raw block data is pruned to a configurable rolling window (default ~2,016 blocks ≈ 7 days). Measured savings: approximately 60% reduction in storage for a running node. This matches or exceeds the storage reduction Bulletproofs would deliver on transaction data alone.
Both features are live, require no hard fork, carry no cryptographic risk, and have already solved the practical problems that motivated this RFC.
DeroGold currently produces roughly 3–4 transactions per block, of which one is always the coinbase (miner reward). That means on average 2–3 user transactions per block at a 300-second block interval — approximately 1 user transaction every 2–3 minutes at current activity levels.
At that transaction volume:
- The P2P bandwidth consumed by larger range proof blobs is negligible
- The ongoing chain growth rate is slow enough that pruning handles it comfortably
- Nobody is waiting for blocks because they're full — blocks are nearly empty
- The flat fee (
MINIMUM_FEE_V2 = 10,000 atomic units) is already effectively zero in real-world value terms
Bulletproofs would optimise something that is not currently a bottleneck.
Most production privacy coins cannot afford to explore major protocol changes casually. Market price pressure, exchange dependencies, large miner communities, and high transaction volumes make every hard fork a high-stakes event.
DeroGold is in the opposite position — and that is genuinely an advantage:
-
10 successful hard forks already executed (
FORK_HEIGHTS[0]through[10]), covering mining algorithm changes, block target changes, fee restructuring, mixin limits, TX PoW, and more. Hard forks are routine here, not exceptional. - 7 block major versions deployed without network failure.
- A small, technically engaged community where consensus can be reached quickly.
- No price pressure means no rush, no panic, and no external stakeholder forcing decisions.
- Pre-allocated fork slots up to block 6,000,000 mean the infrastructure for future upgrades is already in place.
This makes DeroGold an excellent environment to research and prototype Bulletproofs — but that is different from saying this should be the next hard fork.
| Consideration | Weight | Assessment |
|---|---|---|
| Solves an active bottleneck | High | ❌ No — pruning + sync-from-height already solved storage/sync |
| Transaction volume justifies it | High | ❌ No — 2–3 user txs/block at 300s intervals |
| Implementation risk | High | |
| Strategic / future-proofing value | Medium | ✅ Yes — prerequisite for confidential amounts if ever desired |
| Good learning/research project | Low-Medium | ✅ Yes — low-pressure environment is ideal for exploration |
| Hard fork overhead | Medium |
Conclusion: Bulletproofs are not the right next hard fork for DeroGold at current network activity levels. The problems they solve have been addressed by other means. The implementation scope is larger than it appears (see Section 5.1), and the effort-to-benefit ratio is poor right now.
The better path: Keep this document as a living RFC. If transaction volume grows meaningfully, if confidential amounts become a community priority, or if the research interest alone justifies the work, this foundation is ready. The pre-allocated fork slots and the TRANSACTION_VERSION_2 stub mean nothing expires — this can be picked up whenever the conditions change.
All figures in this section are taken directly from the derogold-core source tree.
| Parameter | Value | Source file |
|---|---|---|
| Ticker / Coin name |
DEGO / DeroGold
|
WalletConfig.h, CryptoNoteConfig.h
|
| Address prefix | dg |
WalletConfig.h |
| Total supply |
10,000,000,000,000,000 atomic units |
CryptoNoteConfig.h |
| Decimal places | 2 | CryptoNoteConfig.h |
| Current block version |
BLOCK_MAJOR_VERSION_7 (CN-UPX) |
CryptoNoteConfig.h |
| Current block target | 300 seconds (DIFFICULTY_TARGET_V3) |
CryptoNoteConfig.h |
| Storage backend | RocksDB only | CryptoNoteConfig.h |
| Wallet interfaces |
wallet-api, zedwallet++
|
src/walletapi/, src/zedwallet++/
|
| P2P port | 42069 | CryptoNoteConfig.h |
| RPC port | 6969 | CryptoNoteConfig.h |
All three difficulty targets are defined and gated in CryptoNoteConfig.h:
DIFFICULTY_TARGET = 10s // Genesis
DIFFICULTY_TARGET_V2 = 20s // from block 700,000
DIFFICULTY_TARGET_V3 = 300s // from block 2,325,000 ← currentFork heights are tracked in FORK_HEIGHTS[]. The current fork index (SOFTWARE_SUPPORTED_FORK_INDEX = 10) corresponds to block 2,517,000. Future slots are pre-allocated:
700,000 Fork 0 — 20s block target, mixin limits, extra size reduction
1,470,000 Fork 1 — Fee V1 (1,000,000), mixin V1, extra size V3
1,980,000 Fork 2
2,325,000 Fork 3 — 300s block target, BLOCK_MAJOR_VERSION_6, fusion fee
2,361,823 Fork 4 — MAX_BLOCK_SIZE_V1 (614,400 bytes)
2,370,000 Fork 5 — TX PoW activated
2,420,000 Fork 6 — BLOCK_MAJOR_VERSION_7 (CN-UPX mining algorithm)
2,450,000 Fork 7
2,480,000 Fork 8
2,500,000 Fork 9
2,517,000 Fork 10 — MINIMUM_FEE_V2 (10,000 atomic units) ← CURRENT
3,000,000 Fork 11 — PRE-ALLOCATED ← natural candidate for Bulletproofs
3,500,000 Fork 12 — PRE-ALLOCATED
... Forks 13–17 — PRE-ALLOCATED
A Bulletproofs hard-fork would slot naturally into Fork 11 at block 3,000,000, requiring only SOFTWARE_SUPPORTED_FORK_INDEX = 11 and new block/upgrade version constants.
BLOCK_MAJOR_VERSION_1–3: cn_slow_hash_v0
BLOCK_MAJOR_VERSION_4: cn_lite_slow_hash_v1
BLOCK_MAJOR_VERSION_5–6: cn_turtle_lite_slow_hash_v2
BLOCK_MAJOR_VERSION_7: cn_upx ← currentCN-UPX parameters (hash.h): 131,072-byte scratchpad, 32,768 iterations. Bulletproofs do not affect the block mining algorithm.
The fee schedule from CryptoNoteConfig.h, enforced via Fees.cpp → getMinimumFee(height):
MINIMUM_FEE = 10 // atomic units, genesis
MINIMUM_FEE_V1 = 1,000,000 // from block 1,470,000
MINIMUM_FEE_V2 = 10,000 // from block 2,517,000 ← currentvalidateTransactionFee() in ValidateTransaction.cpp checks fee >= getMinimumFee(height) with no size multiplier. This model does not change with Bulletproofs.
TX PoW is a DeroGold-unique anti-spam mechanism, active from block 2,370,000. From ValidateTransaction.cpp:
// Hash the TransactionPrefix using cn_turtle_lite_slow_hash_v2
// Accept only if hash meets TRANSACTION_POW_DIFFICULTY = 17,000
Crypto::cn_turtle_lite_slow_hash_v2(data.data(), data.size(), hash);
CryptoNote::check_hash(hash, CryptoNote::parameters::TRANSACTION_POW_DIFFICULTY);TX PoW hashes the transaction prefix (inputs, outputs, unlock time) — not range proof blobs. If output amounts change format (e.g., become Pedersen commitments), the prefix data fed into the PoW hash changes in size and structure. The PoW nonce slot in tx_extra (TX_EXTRA_TRANSACTION_POW_NONCE_IDENTIFIER = 0x04) remains valid, but TRANSACTION_POW_DIFFICULTY may need re-tuning post-format change. Benchmarking is required.
DeroGold's current transaction amounts are plaintext uint64_t values. There are no Borromean range proof blobs in the current transaction format. Amount validity is enforced in validateTransactionOutputs() via simple integer arithmetic:
// From ValidateTransaction.cpp
if (output.amount == 0) { /* reject */ }
if (std::numeric_limits<uint64_t>::max() - output.amount < sumOfOutputs) { /* overflow check */ }This is the most important architectural difference from Monero's situation in 2018.
Monero's Bulletproofs replaced expensive existing Borromean range proof blobs within its RingCT (hidden-amount) scheme. DeroGold currently has no such blobs because amounts are not hidden. Simply adding Bulletproofs to a plaintext-amount system provides no meaningful transaction size reduction.
To achieve the size gains described in Section 1, Bulletproofs must be introduced together with hidden amounts (Pedersen commitments). This is effectively the same as Monero's original RingCT + Bulletproofs combined upgrade — a larger but well-understood scope.
// Post block 1,470,000 (current):
MINIMUM_MIXIN_V1 = 0
MAXIMUM_MIXIN_V1 = 3
DEFAULT_MIXIN_V1 = 1Ring signature mixin counts are independent of range proofs and are unaffected by this proposal.
TRANSACTION_VERSION_1 = 1 // current
TRANSACTION_VERSION_2 = 2 // defined but not yet active
CURRENT_TRANSACTION_VERSION = TRANSACTION_VERSION_1TRANSACTION_VERSION_2 is already reserved in the codebase. The Bulletproofs / confidential-amount upgrade should activate it at the fork height.
Bulletproofs are a non-interactive zero-knowledge proof system based on the inner product argument, introduced by Bünz, Bootle, Boneh, Poelstra, Wuille and Maxwell (Stanford/Blockstream, 2017). They allow a prover to convince a verifier that a Pedersen-committed value lies within a valid range [0, 2^n) without revealing the value itself, and without requiring any trusted setup ceremony.
Why "no trusted setup" matters
Systems like zk-SNARKs (e.g., Zcash Sapling) require a one-time multi-party "ceremony" to generate public parameters. If that ceremony is compromised, an attacker could mint arbitrary coins undetected. Bulletproofs derive their parameters solely from publicly auditable hash outputs — no ceremony, no trapdoor.
Instead of sending two vectors of length N to the verifier, the prover engages in a logarithmic-round recursive halving protocol, sending only O(log N) elements. For a 64-bit range proof:
-
Borromean range proof:
O(N)= 64 group elements per output -
Bulletproof (single output):
O(log 64)= 6 rounds → ~2 kB -
Bulletproof (aggregated, k outputs):
O(log(k × 64))→ ~2.5 kB for 2 outputs
A single Bulletproof proves all outputs in a transaction are in range simultaneously. Size growth from 1 to 8 outputs is logarithmic rather than linear.
A Pedersen commitment to value v with blinding factor r is:
C = v·G + r·H
where G and H are independent Ed25519 generator points. The commitment hides v (computationally) while binding to it. Nodes verify transaction balance via commitment algebra (ΣC_inputs = ΣC_outputs + fee_commitment) without seeing individual amounts.
The interactive protocol is made non-interactive via Fiat-Shamir: challenges are derived by hashing public inputs. The resulting proof blob is static and independently verifiable by any node, compatible with DeroGold's P2P propagation model.
As established in Section 2.7, a meaningful Bulletproofs deployment requires introducing hidden amounts simultaneously. The recommended scope for the next hard fork is:
- Hidden output amounts via Pedersen commitments
- Bulletproof range proofs proving committed amounts are non-negative
-
Commitment balance check replacing the plaintext
sum(inputs) - sum(outputs) = feecheck -
TRANSACTION_VERSION_2activation at fork height
This is the equivalent of Monero's combined RingCT + Bulletproofs upgrade from 2018. It is a substantial change but is well-understood, with audited reference code available.
Out of scope: Full ring confidential transactions hiding sender identity via commitment-based ring signatures (Monero's MLSAG/CLSAG). This proposal keeps the existing ring signature scheme on key images unchanged — only output amounts are hidden.
| Module | Files | Changes |
|---|---|---|
src/crypto/ |
New: bulletproof.cpp, bulletproof.h
|
Pedersen commitment primitives (commit()); inner product prove/verify; batch verifier; Ed25519 generator point H definition |
src/cryptonotecore/ValidateTransaction.cpp/.h |
Existing | Add validateBulletproof(); replace integer overflow check with commitment balance check post-fork; gate on TRANSACTION_VERSION_2
|
src/cryptonotecore/CryptoNoteFormatUtils.cpp/.h |
Existing | Serialization of new BulletproofRangeProof field; dual-mode read (v1 plaintext / v2 commitment) |
src/config/CryptoNoteConfig.h |
Existing | Add UPGRADE_HEIGHT_V8 = 3000000; BLOCK_MAJOR_VERSION_8 = 8; set SOFTWARE_SUPPORTED_FORK_INDEX = 11; add BULLETPROOF_FORK_HEIGHT alias |
src/cryptonotecore/Currency.cpp/.h |
Existing | Commitment-based balance validation rules; max transaction size review |
src/walletbackend/Transfer.cpp |
Existing | Transaction builder: generate Pedersen commitments and Bulletproof post-fork; manage blinding factors |
src/walletbackend/WalletSynchronizer.cpp |
Existing | Output scanner: handle commitment-based outputs; blinding factor recovery from one-time keys |
src/walletapi/ApiDispatcher.cpp |
Existing | Update balance and transaction endpoints for commitment outputs |
src/serialization/ |
Existing |
BulletproofV1 struct: V[], A, S, T1, T2, taux, mu, L[], R[], a, b, t
|
| Tests | New | Prove/verify round-trips; batch verify; malformed proof rejection; commitment balance tests; blinding factor round-trip; wallet scan regression |
TX PoW (cn_turtle_lite_slow_hash_v2 on TransactionPrefix, difficulty 17,000) covers the prefix which includes outputs. Post-fork, output amounts become 32-byte commitment points rather than 8-byte uint64_t values. This changes the hash input:
- The PoW nonce slot in
tx_extraremains valid — no structural change needed - Prefix size increases per output (32 bytes vs 8 bytes for amount field)
- This changes the hash input length and may shift nonce search time distribution
TRANSACTION_POW_DIFFICULTYshould be benchmarked and potentially adjusted in the same fork
| Phase | Name | Deliverables |
|---|---|---|
| 0 | Research & RFC | Finalise scope; design BulletproofV1 struct and serialization format; confirm fork height; publish RFC for community comment (this document) |
| 1 | Core Crypto |
bulletproof.cpp: Pedersen commitments, IPA prove/verify, batch verifier; Ed25519 compatibility verification; passing Monero test vectors |
| 2 | Transaction Layer | Update TransactionPrefix; ValidateTransaction dual-mode; CryptoNoteFormatUtils serialization; commitment balance check |
| 3 | Wallet Integration |
Transfer.cpp builder; WalletSynchronizer scanner; zedwallet++ and wallet-api updates; blinding factor management |
| 4 | Devnet | Full local devnet at mock fork height; prove/verify benchmarks; TX PoW interaction benchmarks; size measurements; wallet upgrade path test |
| 5 | Review & Audit | Code review (community minimum; external audit preferred); RFC comment period; node operator and exchange communications |
| 6 | Hard-Fork | Set SOFTWARE_SUPPORTED_FORK_INDEX = 11; minimum 4-week upgrade announcement; post-fork monitoring (mempool, orphan rate, sync times) |
| Bulletproofs (original) | Bulletproofs+ | |
|---|---|---|
| Audit history | Quarkslab + Kudelski, 2018 | Less audited |
| Proof size | Baseline | ~96 bytes smaller per tx |
| Generation speed | Baseline | ~10% faster |
| Verification speed | Baseline | Faster |
| Port risk | Low (from audited Monero bulletproofs.cc) |
Higher |
Recommendation: Original Bulletproofs first, Bulletproofs+ as a follow-up upgrade — exactly how Monero staged it.
DeroGold uses Ed25519 via crypto-ops.c (same curve as Monero). Monero's bulletproofs.cc targets the same curve and generator points. The port is algebraically compatible. The Phase 1 priority is verifying that DeroGold's crypto-ops multi-exponentiation primitives (used in Straus/Pippenger algorithms) produce identical results to Monero's for commitment and inner product operations.
Batch verification amortises multi-exponentiation across multiple proofs and is essential for fast Initial Block Download. It must be integrated into the block validation loop in Core.cpp from day one — not bolted on later.
Already reserved in CryptoNoteConfig.h. Activate at BULLETPROOF_FORK_HEIGHT. Pre-fork blocks accept only VERSION_1; post-fork blocks require VERSION_2 for new transactions while remaining readable for historical VERSION_1 transactions.
⚠️ Lessons from Monero's 2018 AuditQuarkslab and Kudelski Security found: integer overflow in proof-size computation (BP-F-003); missing canonical Ed25519 point validation on prover inputs; environment variable injection into Straus step size; DoS via many-output transactions; Java/C++ implementation divergence. All must be re-examined in the DeroGold port because serialization, memory management, and transaction structure differ from Monero.
Sound under the discrete logarithm assumption in the random oracle model. No trusted setup. The Ed25519 generator H used for Pedersen commitments must be derived from a public, auditable hash-to-curve operation (as in Monero) — not a chosen point with a known discrete log relation to G.
Every element of BulletproofV1 (V[], A, S, T1, T2, L[], R[]) must be validated as a canonical Ed25519 point before any computation. Use DeroGold's existing check_key() in crypto.cpp. Skipping this allows crafted proofs to bypass verification or trigger undefined behaviour in multi-exponentiation.
The commitment balance check replaces the plaintext sum(inputs) = sum(outputs) + fee check:
Σ(input commitments) == Σ(output commitments) + commit(fee, 0)
A bug here is the most dangerous possible vulnerability — it could allow undetected inflation. This check must have dedicated unit tests with adversarially crafted inputs.
The TransactionPrefix hashed for TX PoW must serialise commitment points deterministically. Any non-determinism (e.g., from map iteration order or padding) would make PoW nonces non-reproducible across nodes, causing valid transactions to be incorrectly rejected.
Version gating: VERSION_1 valid only in BLOCK_MAJOR_VERSION <= 7; VERSION_2 required in BLOCK_MAJOR_VERSION >= 8. Enforce in Core.cpp's existing block version infrastructure. The dual-mode validator window must be precise — accepting old proofs in new blocks or vice versa is a security failure.
| Risk | Likelihood | Mitigation |
|---|---|---|
| Commitment balance bug enables inflation | Low–Medium | Port from audited Monero code; dedicated adversarial unit tests; independent review |
| Range proof bug allows negative hidden amounts | Low (audited source) | Monero test vectors; fuzz verifier with malformed proofs |
| Chain split from insufficient upgrade uptake | Medium | 4–8 week announcement window; pre-built binaries all platforms; pool and exchange coordination; P2P_CURRENT_VERSION bump |
| TX PoW difficulty shifts unfavourably post-format change | Low–Medium | Pre-fork benchmarking; adjust TRANSACTION_POW_DIFFICULTY in same fork if needed |
| Wallet scanning regression for commitment outputs | Low | Blinding factor round-trip tests; devnet wallet upgrade regression suite |
TRANSACTION_VERSION_2 stub interacts unexpectedly with existing code paths |
Low | Audit all CURRENT_TRANSACTION_VERSION branch points in the codebase before the fork |
-
Scope confirmation: Is the combined confidential amounts + Bulletproofs scope (Option B) the right call, or should a preparatory fork restructure the transaction format first without hiding amounts?
-
Fork height: Fork 11 at block 3,000,000 is the natural next slot. Is the Phase 0–5 timeline achievable before that height is reached?
-
TX PoW difficulty: Should
TRANSACTION_POW_DIFFICULTYbe reviewed and adjusted in the same fork given the changed prefix structure? -
Bulletproofs vs. Bulletproofs+: Original for safety, or invest the extra time to go straight to Bulletproofs+?
-
External audit: Is a paid cryptographic audit feasible? MAGIC Grants (which funded Bulletproofs+ for Monero) or OSTIF community funding could be explored.
-
Wallet ecosystem readiness: What minimum devnet testing period is required before the mainnet fork announcement, given that
zedwallet++,wallet-api, and exchange integrations all need updating? -
Mixin policy review: With hidden amounts, does the
MAXIMUM_MIXIN_V1 = 3limit need revisiting for improved privacy, or is it out of scope for this fork?
- Bünz, B. et al. (2017). Bulletproofs: Short Proofs for Confidential Transactions and More. eprint.iacr.org
- Chung, H. et al. (2020). Bulletproofs+: Shorter Proofs for a Privacy-Enhanced Protocol. eprint.iacr.org
- Monero Research Lab. Bulletproof deployment and Stagenet release (2018). getmonero.org
- Quarkslab (2018). Security audit of Monero Bulletproofs. via OSTIF. Report PDF
- Kudelski Security (2018). Evaluation of Bulletproof Implementation for Monero. via OSTIF. Report PDF
-
github.com/monero-project/monero—src/ringct/bulletproofs.cc -
github.com/derogold/derogold-core— DeroGold core repository -
src/config/CryptoNoteConfig.h— canonical source for all network parameters referenced here -
src/cryptonotecore/ValidateTransaction.cpp— transaction validation pipeline including TX PoW -
src/utilities/Fees.cpp— flat fee model implementation
Document status: DRAFT v0.3 — written against actual derogold-core source. For discussion and community feedback. Not a binding specification.
DeroGold Bulletproofs Concept Draft — March 2026