docs: Phase 2 crypto bridge documentation

Updated architecture.md with crypto/ package details (CGo bridge pattern,
build flow, exposed operations, 1/8 premultiplication semantics).
Updated history.md with Phase 2 completion (files, findings, tests).
Updated CLAUDE.md with CMake build prerequisite.

Co-Authored-By: Charon <charon@lethean.io>
This commit is contained in:
Claude 2026-02-20 18:49:21 +00:00
parent 1c763a8c31
commit 8af95d457a
No known key found for this signature in database
GPG key ID: AF404715446AEB41
3 changed files with 140 additions and 13 deletions

View file

@ -1,9 +1,21 @@
# CLAUDE.md
Pure Go implementation of the Lethean blockchain protocol (config, types, wire, difficulty).
Go implementation of the Lethean blockchain protocol with CGo crypto bridge.
Module: `forge.lthn.ai/core/go-blockchain`
## Build
```bash
# First time: build the crypto C++ library (requires cmake, g++, libssl-dev, libboost-dev)
cmake -S crypto -B crypto/build -DCMAKE_BUILD_TYPE=Release
cmake --build crypto/build --parallel
# Then: run tests
go test -race ./...
go vet ./...
```
## Commands
```bash
@ -11,6 +23,7 @@ go test ./... # run all tests
go test -race ./... # race detector (required before commit)
go test -v -run Name ./... # single test
go vet ./... # vet check
cmake --build crypto/build --parallel # rebuild C++ after bridge.cpp changes
```
## Standards

View file

@ -16,6 +16,7 @@ config/ Chain parameters (mainnet/testnet), hardfork schedule
types/ Core data types: Hash, PublicKey, Address, Block, Transaction
wire/ Binary serialisation (CryptoNote varint encoding)
difficulty/ PoW + PoS difficulty adjustment (LWMA variant)
crypto/ CGo bridge to vendored C++ libcryptonote (keys, signatures, proofs)
```
### config/
@ -294,11 +295,55 @@ are available (early chain), the algorithm uses whatever data exists. Division
by zero is prevented by clamping the time span to a minimum of 1 second.
`StarterDifficulty` (value 1) is returned when insufficient data is available.
### crypto/ -- CGo Bridge to libcryptonote
Bridges Go to the upstream CryptoNote C++ crypto library via CGo. The C++ code
is vendored in `crypto/upstream/` (37 files from Zano commit `fa1608cf`) and
built as a static library (`libcryptonote.a`) via CMake.
**Build flow:** `CMakeLists.txt``cmake --build``libcryptonote.a` → CGo links.
**C API contract:** `bridge.h` defines the stable C boundary. Go code calls ONLY
these functions -- no C++ types cross the boundary. All parameters are raw
`uint8_t*` pointers with explicit sizes. This is the same CGo pattern used by
`core/go-ai` for the MLX backend.
**Compat layer:** `crypto/compat/` provides minimal stubs replacing epee/Boost
dependencies (logging macros, warnings pragmas, zero-init, profile tools). The
upstream files are unmodified copies; all adaptation lives in the compat headers.
**Provenance:** `crypto/PROVENANCE.md` maps each vendored file to its upstream
origin path and modification status, with an update workflow for tracking Zano
upstream changes.
**Exposed operations:**
| Category | Functions |
|----------|-----------|
| Hashing | `FastHash` (Keccak-256) |
| Key ops | `GenerateKeys`, `SecretToPublic`, `CheckKey` |
| Key derivation | `GenerateKeyDerivation`, `DerivePublicKey`, `DeriveSecretKey` |
| Key images | `GenerateKeyImage`, `ValidateKeyImage` |
| Standard sigs | `GenerateSignature`, `CheckSignature` |
| Ring sigs (NLSAG) | `GenerateRingSignature`, `CheckRingSignature` |
| CLSAG (HF4+) | `GenerateCLSAGGG`, `VerifyCLSAGGG`, `VerifyCLSAGGGX`, `VerifyCLSAGGGXXG` |
| Point helpers | `PointMul8`, `PointDiv8` (cofactor 1/8 premultiplication) |
| Proof verification | `VerifyBPPE`, `VerifyBGE`, `VerifyZarcanum` (stubs -- Phase 4) |
**Ring buffer convention:** Ring entries are flat byte arrays. CLSAG ring entries
pack 32-byte public keys per dimension (GG=64B, GGX=96B, GGXXG=128B per entry).
Signatures are serialised as flat buffers with documented layouts in `bridge.h`.
**1/8 premultiplication:** On-chain commitments are stored premultiplied by the
cofactor inverse (1/8). The `PointMul8`/`PointDiv8` helpers convert between
representations. CLSAG generate takes full points; CLSAG verify takes
premultiplied values.
### ADR-001: Go Shell + C++ Crypto Library
This package follows ADR-001. All protocol logic, data types, serialisation,
and configuration live in pure Go. Only the mathematically complex cryptographic
primitives (ring signatures, bulletproofs, Zarcanum proofs) will be delegated to
a cleaned C++ library via CGo in later phases. This boundary keeps the Go code
testable without a C toolchain while preserving access to battle-tested
and configuration live in pure Go. The mathematically complex cryptographic
primitives (ring signatures, bulletproofs, Zarcanum proofs) are delegated to
the vendored C++ library in `crypto/` via CGo. This boundary keeps the pure Go
code testable without a C toolchain while preserving access to battle-tested
cryptographic implementations.

View file

@ -160,12 +160,73 @@ Phase 0 types had several mismatches with the C++ wire format, corrected here:
Wire coverage is reduced by v2+ code paths (0% -- Phase 2 scope). Excluding
v2+ stubs, the v0/v1 serialisation code exceeds 85% coverage.
## Phase 2 -- Crypto Bridge (Planned)
## Phase 2 -- Crypto Bridge
Create `crypto/` package with CGo bridge to the cleaned C++ `libcryptonote`
library. Implement key derivation (`generate_key_derivation`,
`derive_public_key`), one-time address generation, and key image computation.
Follow the same CGo pattern used by the MLX backend in `go-ai`.
Phase 2 created the `crypto/` package with a CGo bridge to the vendored C++
CryptoNote crypto library. The upstream code (37 files from Zano commit
`fa1608cf`) is built as a static library via CMake, with a thin C API
(`bridge.h`) separating Go from C++ types.
### Files added
| File | Purpose |
|------|---------|
| `crypto/upstream/` | 37 vendored C++ files (unmodified copies) |
| `crypto/compat/` | 11 compatibility stubs replacing epee/Boost |
| `crypto/build/` | CMake build output (libcryptonote.a, ~680KB) |
| `crypto/CMakeLists.txt` | C11/C++17 static library build |
| `crypto/bridge.h` | Stable C API contract (29 functions) |
| `crypto/bridge.cpp` | C→C++ wrappers with memcpy marshalling |
| `crypto/doc.go` | Package documentation + build instructions |
| `crypto/crypto.go` | CGo flags + FastHash binding |
| `crypto/keygen.go` | Key generation, derivation, DerivePublicKey/SecretKey |
| `crypto/keyimage.go` | Key image generation and validation |
| `crypto/signature.go` | Standard + NLSAG ring signatures |
| `crypto/clsag.go` | CLSAG (GG/GGX/GGXXG) + cofactor helpers |
| `crypto/proof.go` | BPPE, BGE, Zarcanum verification stubs |
| `crypto/PROVENANCE.md` | Upstream origin mapping + update workflow |
| `crypto/crypto_test.go` | 22 tests (19 pass, 3 skipped proof stubs) |
### Key findings
- **CMake build required 5 iterations** to resolve all include paths. The
upstream files use relative includes (`../currency_core/`, `crypto/crypto-ops.h`)
that assume the full Zano source tree. Solved with symlinks, additional include
paths, and compat stubs.
- **eth_signature.cpp excluded** from build -- requires Bitcoin's secp256k1
library which is not needed for CryptoNote consensus crypto.
- **cn_fast_hash name collision** between bridge.h and hash-ops.h. Resolved by
renaming the bridge wrapper to `bridge_fast_hash`.
- **Zero key is valid on Ed25519** -- it represents the identity element. Tests
use `0xFF...FF` for invalid key checks instead.
- **1/8 premultiplication** is critical for CLSAG correctness. On-chain
commitments are stored as `(1/8)*P`. Generate takes full points; verify takes
premultiplied values. `PointMul8`/`PointDiv8` helpers convert between forms.
- **Proof verification stubs** return "not implemented" -- the serialisation
format for BPPE/BGE/Zarcanum proofs requires matching the exact on-chain binary
layout, which needs real chain data via RPC (Phase 4).
### Tests added
22 test cases in `crypto/crypto_test.go`:
- **Hashing (2):** Known Keccak-256 vector (empty input), non-zero hash
- **Key ops (3):** GenerateKeys round-trip, CheckKey negative, uniqueness
- **Key derivation (2):** ECDH commutativity, output scanning round-trip
(send → receive → derive ephemeral secret → verify public key match)
- **Key images (3):** Generation, determinism, invalid input rejection
- **Standard sigs (3):** Round-trip, wrong key, wrong message
- **Ring sigs NLSAG (2):** 4-member ring round-trip, wrong message
- **CLSAG GG (2):** Generate+verify round-trip with cofactor handling, wrong message
- **CLSAG size (2):** GGX and GGXXG signature size calculations
- **Proof stubs (3):** Skipped -- pending Phase 4 chain data
All passing with `-race` and `go vet`.
## Phase 3 -- P2P Levin Protocol (Planned)
@ -210,9 +271,17 @@ hash computation and coinstake transaction construction.
and verified. The v2+ (Zarcanum) code paths compile but are untested -- they
will be validated in Phase 2 when post-HF4 transactions appear on-chain.
**No cryptographic operations.** Key derivation, ring signatures, bulletproofs,
and all other cryptographic primitives are deferred to Phase 2. Address
encoding/decoding works but key generation and output scanning are not possible.
**Proof verification not yet wired.** Key generation, derivation, signatures
(standard, NLSAG, CLSAG GG) are fully operational. BPPE, BGE, and Zarcanum
proof verification stubs exist but return "not implemented" -- the deserialisation
of on-chain proof blobs requires matching the exact binary format from chain data
(Phase 4). CLSAG GGX/GGXXG verify functions are wired but untested without real
ring data.
**CGo toolchain required.** The `crypto/` package requires CMake, GCC/Clang,
OpenSSL, and Boost headers to build `libcryptonote.a`. Pure Go packages
(`config/`, `types/`, `wire/`, `difficulty/`) remain buildable without a C
toolchain.
**Base58 uses math/big.** The CryptoNote base58 implementation converts each
8-byte block via `big.Int` arithmetic. This is correct but not optimised for