Files
zeekay 2c63fd34fc lens: classical curve threshold kernel — sister to Pulsar
Lens is the curve-based threshold signing kernel for Lux. It is the
classical analogue of Pulsar (the lattice kernel at github.com/luxfi/pulsar).
Both kernels share the same lifecycle shape — Bootstrap → Reshare* →
Reanchor — and the same activation circuit-breaker contract. They differ
only in the math field: Pulsar over R_q (Module-LWE), Lens over a
prime-order curve group (discrete log).

Curves shipped: Ed25519, secp256k1, Ristretto255. Each has a
deterministically-derived secondary Pedersen generator H from a
Lens-specific nothing-up-my-sleeve tag.

Sign math: FROST 2-round Schnorr threshold signing per RFC 9591
(Komlo-Goldberg 2020). Verifier checks z·G ?= R + c·X under the
unchanged group public key.

Reshare math: HJKY97 zero-poly Refresh + Desmedt-Jajodia ReshareToNewSet
over the curve scalar field. Master secret s is preserved; only the
share distribution rotates per epoch.

Activation cert message format: QUASAR-LENS-ACTIVATE-v1, byte-equivalent
shape to QUASAR-PULSAR-ACTIVATE-v1.

Hash suite: HashSuite interface with Lens-SHA3 (production, cSHAKE256 /
KMAC256 / TupleHash256) and Lens-BLAKE3 (legacy) profiles.

DKG: distributed FROST DKG with Feldman commitments. No trusted dealer
required at genesis if the chain prefers proper distributed DKG.

KAT oracles: cmd/reshare_oracle and cmd/dkg_oracle emit deterministic
JSON vectors for cross-language byte-equality validation against a
future luxcpp/crypto/lens/ port.

Tests: full unit + integration coverage on every shipped curve. 60
unique tests, 0 failures.
2026-03-03 12:00:00 -08:00

65 lines
2.0 KiB
Go

// Copyright (C) 2025-2026, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package reshare
import (
"crypto/rand"
"testing"
"github.com/luxfi/lens/primitives"
)
// TestPedersenCommitVerifyHonest — honest (share, blind) verifies.
func TestPedersenCommitVerifyHonest(t *testing.T) {
for _, c := range curves() {
t.Run(c.Name(), func(t *testing.T) {
secret, _ := c.SampleScalar(rand.Reader)
f, _ := primitives.NewPolynomial(c, 2, secret, rand.Reader)
rb, _ := primitives.NewPolynomial(c, 2, nil, rand.Reader)
commits, err := CommitToPoly(c, f.Coefficients(), rb.Coefficients())
if err != nil {
t.Fatalf("CommitToPoly: %v", err)
}
x := c.NewScalar().SetUint64(7)
share := f.Evaluate(x)
blind := rb.Evaluate(x)
if err := VerifyShareAgainstCommits(c, share, blind, commits, x); err != nil {
t.Fatalf("honest verify failed: %v", err)
}
})
}
}
// TestPedersenCommitVerifyTampered — wrong share rejected.
func TestPedersenCommitVerifyTampered(t *testing.T) {
c := primitives.NewSecp256k1()
secret, _ := c.SampleScalar(rand.Reader)
f, _ := primitives.NewPolynomial(c, 2, secret, rand.Reader)
rb, _ := primitives.NewPolynomial(c, 2, nil, rand.Reader)
commits, _ := CommitToPoly(c, f.Coefficients(), rb.Coefficients())
x := c.NewScalar().SetUint64(3)
share := f.Evaluate(x)
blind := rb.Evaluate(x)
tampered := c.NewScalar().Set(share).Add(c.NewScalar().SetUint64(1))
if err := VerifyShareAgainstCommits(c, tampered, blind, commits, x); err == nil {
t.Fatal("tampered share accepted")
}
}
// TestCommitDigestStable — digest is deterministic across calls.
func TestCommitDigestStable(t *testing.T) {
c := primitives.NewEd25519()
secret, _ := c.SampleScalar(rand.Reader)
f, _ := primitives.NewPolynomial(c, 3, secret, rand.Reader)
rb, _ := primitives.NewPolynomial(c, 3, nil, rand.Reader)
commits, _ := CommitToPoly(c, f.Coefficients(), rb.Coefficients())
d1 := CommitDigest(commits, nil)
d2 := CommitDigest(commits, nil)
if d1 != d2 {
t.Fatal("CommitDigest not deterministic")
}
}