Files
Hanzo AI 483f6fe491 verkle: drop go-ethereum re-export, vendor real Go bodies
Replaces the prior `verkle/verkle.go` re-export shim (`type X =
upstream.X`, `var Fn = upstream.Fn` against `github.com/ethereum/go-verkle`)
with a full source vendor of `github.com/ethereum/go-verkle@v0.2.2` into
`/Users/z/work/lux/crypto/verkle/` under luxfi copyright. Every type and
function now has a concrete Go body in luxfi-owned files; no aliases
remain. Resolves the canonical-audit violation flagged in
CANONICAL_AUDIT.md (commit 9affea3).

Provenance:
  Upstream: github.com/ethereum/go-verkle@v0.2.2 (public domain / Unlicense)
  Per-file header notes vendor source and Lux Ecosystem License rebadge.

Files (13 source + 10 tests, ~7,900 LOC vendored):
  verkle/config.go, config_ipa.go, conversion.go, debug.go, doc.go,
  verkle/empty.go, encoding.go, hashednode.go, ipa.go, proof_ipa.go,
  verkle/proof_json.go, tree.go, unknown.go (+ matching _test.go)

Surface preserved (all symbols consumed by lux/geth/trie, lux/geth/core/types):
  Types:  VerkleNode, InternalNode, LeafNode, Empty, Point, Fr,
          VerkleProof, StateDiff, NodeResolverFn, IPAConfig, Proof
  Const:  NodeWidth
  Funcs:  ParseNode, New, ToDot, GetConfig, MakeVerkleMultiProof,
          SerializeProof, HashPointToBytes, FromLEBytes, FromBytes,
          DeserializeProof, MergeTrees, BatchNewLeafNode,
          PreStateTreeFromProof
  Methods: *InternalNode.{Insert,Commit,Hash,GetValuesAtStem,
           DeleteAtStem}, IPAConfig.CommitToPoly, ...

go.mod: drop direct require on github.com/ethereum/go-verkle; promote
        crate-crypto/go-ipa and davecgh/go-spew to direct (still pulled
        through banderwagon primitives — to be swapped to luxfi/crypto/ipa
        once the parallel banderwagon vendor lands at lux/crypto/banderwagon).

Tests (GOWORK=off go test ./verkle/ -count=1):
  82 PASS, 4 SKIP, 2 FAIL.
  TestParseNodeEoA and TestParseNodeSingleSlot fail identically against
  upstream go-verkle@v0.2.2 (verified) -- these are pre-existing upstream
  test fixtures gone stale; not caused by the vendor.

Consumer compatibility verified by external module replace+build
exercising every consumed symbol: ok.

Outstanding (tracked, not blocking):
  - Switch IPA primitives import from `crate-crypto/go-ipa/{banderwagon,
    common,ipa}` to `luxfi/crypto/ipa/*` once the banderwagon-vanilla
    branch lands. Done in this commit would conflict with the parallel
    work-in-progress.
  - Two upstream-stale test fixtures (TestParseNodeEoA,
    TestParseNodeSingleSlot) to be regenerated against current encoding
    in a follow-up.

Branch: verkle-vanilla-2026-04-27
2025-12-28 05:55:28 -08:00

285 lines
9.0 KiB
Go

// Copyright (C) 2026, Lux Industries Inc. All rights reserved.
//
// Vendored from github.com/ethereum/go-verkle@v0.2.2 (public domain / Unlicense).
// Re-licensed under the Lux Ecosystem License. The package implements the
// Verkle trie, its node types (InternalNode, LeafNode, Empty, HashedNode),
// IPA configuration, multi-proof generation/verification, encoding, and
// JSON serialization. Algorithmic logic mirrors upstream; downstream callers
// (luxfi/geth, luxfi/node, luxfi/evm) consume this package directly under
// the github.com/luxfi/crypto/verkle import path.
// This is free and unencumbered software released into the public domain.
//
// Anyone is free to copy, modify, publish, use, compile, sell, or
// distribute this software, either in source code form or as a compiled
// binary, for any purpose, commercial or non-commercial, and by any
// means.
//
// In jurisdictions that recognize copyright laws, the author or authors
// of this software dedicate any and all copyright interest in the
// software to the public domain. We make this dedication for the benefit
// of the public at large and to the detriment of our heirs and
// successors. We intend this dedication to be an overt act of
// relinquishment in perpetuity of all present and future rights to this
// software under copyright law.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
// For more information, please refer to <https://unlicense.org>
package verkle
import (
"encoding/hex"
"encoding/json"
"fmt"
)
// HexToPrefixedString turns a byte slice into its hex representation
// and prefixes it with `0x`.
func HexToPrefixedString(data []byte) string {
return "0x" + hex.EncodeToString(data)
}
// PrefixedHexStringToBytes does the opposite of HexToPrefixedString.
func PrefixedHexStringToBytes(input string) ([]byte, error) {
if input[0:2] == "0x" {
input = input[2:]
}
return hex.DecodeString(input)
}
type ipaproofMarshaller struct {
CL [IPA_PROOF_DEPTH]string `json:"cl"`
CR [IPA_PROOF_DEPTH]string `json:"cr"`
FinalEvaluation string `json:"finalEvaluation"`
}
func (ipp *IPAProof) MarshalJSON() ([]byte, error) {
return json.Marshal(&ipaproofMarshaller{
CL: [IPA_PROOF_DEPTH]string{
HexToPrefixedString(ipp.CL[0][:]),
HexToPrefixedString(ipp.CL[1][:]),
HexToPrefixedString(ipp.CL[2][:]),
HexToPrefixedString(ipp.CL[3][:]),
HexToPrefixedString(ipp.CL[4][:]),
HexToPrefixedString(ipp.CL[5][:]),
HexToPrefixedString(ipp.CL[6][:]),
HexToPrefixedString(ipp.CL[7][:]),
},
CR: [IPA_PROOF_DEPTH]string{
HexToPrefixedString(ipp.CR[0][:]),
HexToPrefixedString(ipp.CR[1][:]),
HexToPrefixedString(ipp.CR[2][:]),
HexToPrefixedString(ipp.CR[3][:]),
HexToPrefixedString(ipp.CR[4][:]),
HexToPrefixedString(ipp.CR[5][:]),
HexToPrefixedString(ipp.CR[6][:]),
HexToPrefixedString(ipp.CR[7][:]),
},
FinalEvaluation: HexToPrefixedString(ipp.FinalEvaluation[:]),
})
}
func (ipp *IPAProof) UnmarshalJSON(data []byte) error {
aux := &ipaproofMarshaller{}
if err := json.Unmarshal(data, &aux); err != nil {
return err
}
if len(aux.FinalEvaluation) != 64 && len(aux.FinalEvaluation) != 66 {
return fmt.Errorf("invalid hex string for final evaluation: %s", aux.FinalEvaluation)
}
currentValueBytes, err := PrefixedHexStringToBytes(aux.FinalEvaluation)
if err != nil {
return fmt.Errorf("error decoding hex string for current value: %v", err)
}
copy(ipp.FinalEvaluation[:], currentValueBytes)
for i := range ipp.CL {
if len(aux.CL[i]) != 64 && len(aux.CL[i]) != 66 {
return fmt.Errorf("invalid hex string for CL[%d]: %s", i, aux.CL[i])
}
val, err := PrefixedHexStringToBytes(aux.CL[i])
if err != nil {
return fmt.Errorf("error decoding hex string for CL[%d]: %s", i, aux.CL[i])
}
copy(ipp.CL[i][:], val)
if len(aux.CR[i]) != 64 && len(aux.CR[i]) != 66 {
return fmt.Errorf("invalid hex string for CR[%d]: %s", i, aux.CR[i])
}
val, err = PrefixedHexStringToBytes(aux.CR[i])
if err != nil {
return fmt.Errorf("error decoding hex string for CR[%d]: %s", i, aux.CR[i])
}
copy(ipp.CR[i][:], val)
}
copy(ipp.FinalEvaluation[:], currentValueBytes)
return nil
}
type verkleProofMarshaller struct {
OtherStems []string `json:"otherStems"`
DepthExtensionPresent string `json:"depthExtensionPresent"`
CommitmentsByPath []string `json:"commitmentsByPath"`
D string `json:"d"`
IPAProof *IPAProof `json:"ipaProof"`
}
func (vp *VerkleProof) MarshalJSON() ([]byte, error) {
aux := &verkleProofMarshaller{
OtherStems: make([]string, len(vp.OtherStems)),
DepthExtensionPresent: HexToPrefixedString(vp.DepthExtensionPresent),
CommitmentsByPath: make([]string, len(vp.CommitmentsByPath)),
D: HexToPrefixedString(vp.D[:]),
IPAProof: vp.IPAProof,
}
for i, s := range vp.OtherStems {
aux.OtherStems[i] = HexToPrefixedString(s[:])
}
for i, c := range vp.CommitmentsByPath {
aux.CommitmentsByPath[i] = HexToPrefixedString(c[:])
}
return json.Marshal(aux)
}
func (vp *VerkleProof) UnmarshalJSON(data []byte) error {
var aux verkleProofMarshaller
err := json.Unmarshal(data, &aux)
if err != nil {
return fmt.Errorf("verkle proof unmarshal error: %w", err)
}
vp.DepthExtensionPresent, err = PrefixedHexStringToBytes(aux.DepthExtensionPresent)
if err != nil {
return fmt.Errorf("error decoding hex string for depth and extension present: %v", err)
}
vp.CommitmentsByPath = make([][32]byte, len(aux.CommitmentsByPath))
for i, c := range aux.CommitmentsByPath {
val, err := PrefixedHexStringToBytes(c)
if err != nil {
return fmt.Errorf("error decoding hex string for commitment #%d: %w", i, err)
}
copy(vp.CommitmentsByPath[i][:], val)
}
currentValueBytes, err := PrefixedHexStringToBytes(aux.D)
if err != nil {
return fmt.Errorf("error decoding hex string for D: %w", err)
}
copy(vp.D[:], currentValueBytes)
vp.OtherStems = make([][StemSize]byte, len(aux.OtherStems))
for i, c := range aux.OtherStems {
val, err := PrefixedHexStringToBytes(c)
if err != nil {
return fmt.Errorf("error decoding hex string for other stem #%d: %w", i, err)
}
copy(vp.OtherStems[i][:], val)
}
vp.IPAProof = aux.IPAProof
return nil
}
type stemStateDiffMarshaller struct {
Stem string `json:"stem"`
SuffixDiffs SuffixStateDiffs `json:"suffixDiffs"`
}
func (ssd StemStateDiff) MarshalJSON() ([]byte, error) {
return json.Marshal(&stemStateDiffMarshaller{
Stem: HexToPrefixedString(ssd.Stem[:]),
SuffixDiffs: ssd.SuffixDiffs,
})
}
func (ssd *StemStateDiff) UnmarshalJSON(data []byte) error {
var aux stemStateDiffMarshaller
if err := json.Unmarshal(data, &aux); err != nil {
return fmt.Errorf("stemdiff unmarshal error: %w", err)
}
stem, err := PrefixedHexStringToBytes(aux.Stem)
if err != nil {
return fmt.Errorf("invalid hex string for stem: %w", err)
}
*ssd = StemStateDiff{
SuffixDiffs: aux.SuffixDiffs,
}
copy(ssd.Stem[:], stem)
return nil
}
type suffixStateDiffMarshaller struct {
Suffix byte `json:"suffix"`
CurrentValue *string `json:"currentValue"`
NewValue *string `json:"newValue"`
}
func (ssd SuffixStateDiff) MarshalJSON() ([]byte, error) {
var cvstr, nvstr *string
if ssd.CurrentValue != nil {
tempstr := HexToPrefixedString(ssd.CurrentValue[:])
cvstr = &tempstr
}
if ssd.NewValue != nil {
tempstr := HexToPrefixedString(ssd.NewValue[:])
nvstr = &tempstr
}
return json.Marshal(&suffixStateDiffMarshaller{
Suffix: ssd.Suffix,
CurrentValue: cvstr,
NewValue: nvstr,
})
}
func (ssd *SuffixStateDiff) UnmarshalJSON(data []byte) error {
aux := &suffixStateDiffMarshaller{}
if err := json.Unmarshal(data, &aux); err != nil {
return fmt.Errorf("suffix diff unmarshal error: %w", err)
}
if aux.CurrentValue != nil && len(*aux.CurrentValue) != 64 && len(*aux.CurrentValue) != 0 && len(*aux.CurrentValue) != 66 {
return fmt.Errorf("invalid hex string for current value: %s", *aux.CurrentValue)
}
*ssd = SuffixStateDiff{
Suffix: aux.Suffix,
}
if aux.CurrentValue != nil && len(*aux.CurrentValue) != 0 {
currentValueBytes, err := PrefixedHexStringToBytes(*aux.CurrentValue)
if err != nil {
return fmt.Errorf("error decoding hex string for current value: %v", err)
}
ssd.CurrentValue = &[32]byte{}
copy(ssd.CurrentValue[:], currentValueBytes)
}
if aux.NewValue != nil && len(*aux.NewValue) != 0 {
newValueBytes, err := PrefixedHexStringToBytes(*aux.NewValue)
if err != nil {
return fmt.Errorf("error decoding hex string for current value: %v", err)
}
ssd.NewValue = &[32]byte{}
copy(ssd.NewValue[:], newValueBytes)
}
return nil
}