Conversation
The `1<<32-1` literal in MultiExpGLVWide's nbPoints guard overflows the 32-bit int on GOARCH=386, breaking the CI `go test -json` step that runs on ./ecc/bn254/... under 32-bit. The build failure emits a JSON event with empty Package, which makes gotestfmt v2.5.0 panic with "BUG: Empty package name encountered" and fails the test job. Cast through uint64 and compare against math.MaxUint32 so the constant compiles cleanly under both 32- and 64-bit int. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ivokub
left a comment
There was a problem hiding this comment.
Sending first round of review. This is mostly about the code generation part.
I think for some implementation having hand-written files is fine, but in that case they should explicilty not have the "DO NOT EDIT" header, this breaks the automatic deletion logic. And I think we can still even now have more code-generation coverage and avoid switching in the generator function on concrete curves (and rather use attribute-base generation logic). Please see the inline comments.
I will do the curve implementation and multiset hash in another round. But it would be easier if we would have more code-generated parts (for the ECC even), so that I know everything matches the templates. What was the block change why files in ecc/kb8 had to be hand-written, not generated? Imo seems quite similar to other curves?
ivokub
left a comment
There was a problem hiding this comment.
I now extended the review to the Octobear curve as well. This looks good. I tried locally implementing code-generation for octobear curve and it seems to work. But it is a bit bigger change and imo we should do it in a separate PR after this PR is done.
I also started looking at the multi-set hash. There are a few quickly fixable issues. However, to estimate the security level, it would be better to have concrete references to the paper (right now we just referene as ECMSH_PQ without concrete link), right now I'm not sure about the claim :)
After the small fixes and paper references I think the PR is ready to merge (I'll run another round of review though to be sure)
There was a problem hiding this comment.
Checked now multiset-hash as well. Imo the implementation is clear, but I'm still a bit unsure about the soundness level.
Left a few more comments about potentially making the accumulator more parallelizable. See if it makes sense.
And I still think we should code-generate octobear. But perhaps when it is a bit more settled as a separate PR :) My local experiments show that its doable, the issue is mostly about serialization (due to E8 case handling we need to add) and some different formulas for EC imo.
Created an issue for the code-generation #846. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit f6b0b47. Configure here.

Description
This PR adds support for the Octobear curve over the degree-8 extension of KoalaBear field and introduces a native multiset hash built on top of it, including a post-quantum vector extension. The target use case is circuit-friendly multiset hashing for computations defined over the KoalaBear field, in particular zkVM memory arguments that will later be verified inside SNARK circuits.
Concretely, this PR:
ecc.OCTOBEARcurve and theecc/octobearpackagefield/koalabearfor the base field and adds sharedE8support infield/koalabear/extensionsoctobearcurve arithmetic, scalar field, generator config, and testsecc/octobear/multiset-hash, implementing three flavors of multiset hash onoctobear:y-increment map (uint16 messages)N=23coordinates,T=128,M=2^18, uint32 messages)N=23coordinates,T=256, width-16 sponge, uint64 messages)octobearwhile keeping the rest of the repository greenThe one-point construction maps
uint16messages by searchingy = 256*m + kfork < 256, solving the resulting depressed cubic overFp^8, and accumulating mapped points onoctobear. The final implementation uses recursive Cardano with binary Lucas sequences at every extension level.The vector construction keeps
N=23independently domain-separated ECMSH accumulators. After Shor's algorithm computes discrete logarithms, a collision in the vector digest reduces to a bounded modular linear relation, i.e. a SIS-shaped problem with modulusr ≈ 2^248and dimensionN=23(23·248 = 5704bits, matching the Linea KoalaBear LtHash baseline). The linear separator is cheap but leaves a "probably" structurally regular post-Shor matrix; the Poseidon2 separator pays a sponge cost but yields a less structured matrix and is the preferred concrete derivation. Both variants preserve inverse-freeness (y_i < p/2) by construction.Type of change
How has this been tested?
The following checks pass locally:
go test ./field/koalabear/extensions ./ecc/octobear/...Additional validation performed during development:
Map(uint16)validation over all65536inputs of the one-point varianty_i < p/2) checked on sampled messages for both vector variantsHash(A ∪ B) == Hash(A) + Hash(B)componentwise) for both vector variantsHow has this been benchmarked?
Benchmarks were run locally on a MacBook Pro class machine (
darwin/arm64, Apple M5, 32GB RAM) with:Current results:
BenchmarkMap-10:25440 ns/opBenchmarkAccumulatorInsert-10:6896592 ns/op(256 inserts of the one-point variant)BenchmarkHash256-10:6802114 ns/op(one-point hash over 256 messages)BenchmarkMapLinear-10:512971 ns/op(linear vector map for one message → 23 points)BenchmarkMapPoseidon2-10:570382 ns/op(Poseidon2 vector map for one message → 23 points)BenchmarkHashLinear256-10:157928583 ns/op(linear vector hash over 256 messages)BenchmarkHashPoseidon2_256-10:160487518 ns/op(Poseidon2 vector hash over 256 messages)Checklist:
golangci-lintdoes not output errors locallyNote
High Risk
Introduces a large body of new curve and scalar-field cryptography (including cube roots and multiset hashes) intended for security-sensitive zkVM arguments, with limited audit coverage called out in generated code.
Overview
This PR registers the Octobear curve (
ecc.OCTOBEAR) and wires scalar/base field metadata inecc/ecc_field.go, with misspell configured to ignore the nameoctobear.It adds the
ecc/octobeartree:fpis a thin alias overfield/koalabearso imports match other curves;fris a full generated ~248-bit scalar field (Montgomery arithmetic, amd64/arm64 asm, vectors, Tonelli–ShanksSqrtand cubic-rootCbrtwith dedicated exp chains and tests). The curve package targets 𝔽_p⁸ over KoalaBear for circuit-friendly use (per package docs), including multiset-hash variants described in the PR (classical ECMSH, vector ECMSH with linear or Poseidon2 domain separation).Review focus: correctness of new field/curve parameters,
Cbrt/extension math used by hashing, and performance/security assumptions of the multiset-hash constructions—not re-auditing every generatedfrline unless behavior diverges from other curves.Reviewed by Cursor Bugbot for commit f6b0b47. Bugbot is set up for automated code reviews on this repo. Configure here.