Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stateproof message #4006

Merged
merged 12 commits into from
May 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions crypto/stateproof/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ type sigslot struct {
}

// Builder keeps track of signatures on a message and eventually produces
// a stater proof for that message.
// a state proof for that message.
type Builder struct {
data MessageHash
round uint64
Expand All @@ -64,7 +64,7 @@ type Builder struct {
// MkBuilder constructs an empty builder. After adding enough signatures and signed weight, this builder is used to create a stateproof.
func MkBuilder(data MessageHash, round uint64, provenWeight uint64, part []basics.Participant, parttree *merklearray.Tree, strengthTarget uint64) (*Builder, error) {
npart := len(part)
lnProvenWt, err := lnIntApproximation(provenWeight)
lnProvenWt, err := LnIntApproximation(provenWeight)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -199,7 +199,7 @@ func (b *Builder) Build() (*StateProof, error) {
}

// Reveal sufficient number of signatures
c := &StateProof{
s := &StateProof{
SigCommit: sigtree.Root(),
SignedWeight: b.signedWeight,
Reveals: make(map[uint64]Reveal),
Expand All @@ -214,8 +214,8 @@ func (b *Builder) Build() (*StateProof, error) {
choice := coinChoiceSeed{
partCommitment: b.parttree.Root(),
lnProvenWeight: b.lnProvenWeight,
sigCommitment: c.SigCommit,
signedWeight: c.SignedWeight,
sigCommitment: s.SigCommit,
signedWeight: s.SignedWeight,
data: b.data,
}

Expand All @@ -237,13 +237,13 @@ func (b *Builder) Build() (*StateProof, error) {
revealsSequence[j] = pos

// If we already revealed pos, no need to do it again
_, alreadyRevealed := c.Reveals[pos]
_, alreadyRevealed := s.Reveals[pos]
if alreadyRevealed {
continue
}

// Generate the reveal for pos
c.Reveals[pos] = Reveal{
s.Reveals[pos] = Reveal{
SigSlot: b.sigs[pos].sigslotCommit,
Part: b.participants[pos],
}
Expand All @@ -261,9 +261,9 @@ func (b *Builder) Build() (*StateProof, error) {
return nil, err
}

c.SigProofs = *sigProofs
c.PartProofs = *partProofs
c.PositionsToReveal = revealsSequence
s.SigProofs = *sigProofs
s.PartProofs = *partProofs
s.PositionsToReveal = revealsSequence

return c, nil
return s, nil
}
14 changes: 7 additions & 7 deletions crypto/stateproof/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,17 +83,17 @@ func generateTestSigner(firstValid uint64, lastValid uint64, interval uint64, a
return signer
}

func generateProofForTesting(a *require.Assertions) paramsForTest {
// Doing a full test of 1M accounts takes too much CPU time in CI.
doLargeTest := false
func generateProofForTesting(a *require.Assertions, doLargeTest bool) paramsForTest {

totalWeight := 10000000
npartHi := 10
npartLo := 9990
npartHi := 2
npartLo := 100
stateproofIntervals := uint64(4) // affects the number of keys that will be generated

if doLargeTest {
npartHi *= 100
npartLo *= 100
stateproofIntervals = 20
}

npart := npartHi + npartLo
Expand All @@ -102,7 +102,7 @@ func generateProofForTesting(a *require.Assertions) paramsForTest {
provenWt := uint64(totalWeight / 2)

// Share the key; we allow the same vote key to appear in multiple accounts..
key := generateTestSigner(0, uint64(stateProofIntervalForTests)*20+1, stateProofIntervalForTests, a)
key := generateTestSigner(0, uint64(stateProofIntervalForTests)*stateproofIntervals+1, stateProofIntervalForTests, a)
var parts []basics.Participant
var sigs []merklesignature.Signature
parts = append(parts, createParticipantSliceWithWeight(totalWeight, npartHi, key.GetVerifier())...)
Expand Down Expand Up @@ -151,7 +151,7 @@ func TestBuildVerify(t *testing.T) {

a := require.New(t)

p := generateProofForTesting(a)
p := generateProofForTesting(a, true)
sProof := p.sp

var someReveal Reveal
Expand Down
12 changes: 11 additions & 1 deletion crypto/stateproof/verifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ type Verifier struct {
// MkVerifier constructs a verifier to check the state proof. the arguments for this function
// represent all the verifier's trusted data
func MkVerifier(partcom crypto.GenericDigest, provenWeight uint64, strengthTarget uint64) (*Verifier, error) {
lnProvenWt, err := lnIntApproximation(provenWeight)
lnProvenWt, err := LnIntApproximation(provenWeight)
if err != nil {
return nil, err
}
Expand All @@ -52,6 +52,16 @@ func MkVerifier(partcom crypto.GenericDigest, provenWeight uint64, strengthTarge
}, nil
}

// MkVerifierWithLnProvenWeight constructs a verifier to check the state proof. the arguments for this function
// represent all the verifier's trusted data. This function uses the Ln(provenWeight) approximation value
func MkVerifierWithLnProvenWeight(partcom crypto.GenericDigest, lnProvenWt uint64, strengthTarget uint64) *Verifier {
return &Verifier{
strengthTarget: strengthTarget,
lnProvenWeight: lnProvenWt,
participantsCommitment: partcom,
}
}

// Verify checks if s is a valid state proof for the data on a round.
// it uses the trusted data from the Verifier struct
func (v *Verifier) Verify(round uint64, data MessageHash, s *StateProof) error {
Expand Down
24 changes: 21 additions & 3 deletions crypto/stateproof/verifier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func TestVerifyRevelForEachPosition(t *testing.T) {
partitiontest.PartitionTest(t)
a := require.New(t)

p := generateProofForTesting(a)
p := generateProofForTesting(a, false)
sProof := p.sp

verifier, err := MkVerifier(p.partCommitment, p.provenWeight, stateProofStrengthTargetForTests)
Expand Down Expand Up @@ -61,7 +61,7 @@ func TestVerifyWrongCoinSlot(t *testing.T) {
partitiontest.PartitionTest(t)
a := require.New(t)

p := generateProofForTesting(a)
p := generateProofForTesting(a, false)
sProof := p.sp
verifier, err := MkVerifier(p.partCommitment, p.provenWeight, stateProofStrengthTargetForTests)
a.NoError(err)
Expand Down Expand Up @@ -105,7 +105,7 @@ func TestVerifyBadSignature(t *testing.T) {
partitiontest.PartitionTest(t)
a := require.New(t)

p := generateProofForTesting(a)
p := generateProofForTesting(a, false)
sProof := p.sp

verifier, err := MkVerifier(p.partCommitment, p.provenWeight, stateProofStrengthTargetForTests)
Expand Down Expand Up @@ -137,3 +137,21 @@ func TestVerifyZeroProvenWeight(t *testing.T) {
_, err := MkVerifier(partcommit, 0, stateProofStrengthTargetForTests)
a.ErrorIs(err, ErrIllegalInputForLnApprox)
}

func TestEqualVerifiers(t *testing.T) {
partitiontest.PartitionTest(t)
a := require.New(t)

p := generateProofForTesting(a, false)
sProof := p.sp

verifier, err := MkVerifier(p.partCommitment, p.provenWeight, stateProofStrengthTargetForTests)
a.NoError(err)
err = verifier.Verify(stateProofIntervalForTests, p.data, &sProof)
a.NoError(err)

lnProvenWeight, err := LnIntApproximation(p.provenWeight)
verifierLnP := MkVerifierWithLnProvenWeight(p.partCommitment, lnProvenWeight, stateProofStrengthTargetForTests)

a.Equal(verifierLnP, verifier)
}
4 changes: 2 additions & 2 deletions crypto/stateproof/weights.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ func bigInt(num uint64) *big.Int {
return (&big.Int{}).SetUint64(num)
}

// lnIntApproximation returns a uint64 approximation
func lnIntApproximation(x uint64) (uint64, error) {
// LnIntApproximation returns a uint64 approximation
func LnIntApproximation(x uint64) (uint64, error) {
if x == 0 {
return 0, ErrIllegalInputForLnApprox
}
Expand Down
22 changes: 11 additions & 11 deletions crypto/stateproof/weights_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func TestMaxNumberOfRevealsInVerify(t *testing.T) {

signedWeight := uint64(10)
provenWeight := uint64(10)
lnProvenWt, err := lnIntApproximation(provenWeight)
lnProvenWt, err := LnIntApproximation(provenWeight)
a.NoError(err)

err = verifyWeights(signedWeight, lnProvenWt, MaxReveals+1, stateProofStrengthTargetForTests)
Expand All @@ -43,7 +43,7 @@ func TestMaxNumberOfReveals(t *testing.T) {

signedWeight := uint64(1<<10 + 1)
provenWeight := uint64(1 << 10)
lnProvenWt, err := lnIntApproximation(provenWeight)
lnProvenWt, err := LnIntApproximation(provenWeight)
a.NoError(err)

_, err = numReveals(signedWeight, lnProvenWt, stateProofStrengthTargetForTests)
Expand All @@ -56,7 +56,7 @@ func TestVerifyProvenWeight(t *testing.T) {

signedWeight := uint64(1 << 11)
provenWeight := uint64(1 << 10)
lnProvenWt, err := lnIntApproximation(provenWeight)
lnProvenWt, err := LnIntApproximation(provenWeight)
a.NoError(err)

numOfReveals, err := numReveals(signedWeight, lnProvenWt, stateProofStrengthTargetForTests)
Expand All @@ -75,7 +75,7 @@ func TestVerifyZeroNumberOfRevealsEquation(t *testing.T) {

signedWeight := uint64(1<<15 + 1)
provenWeight := uint64(1 << 15)
lnProvenWt, err := lnIntApproximation(provenWeight)
lnProvenWt, err := LnIntApproximation(provenWeight)
a.NoError(err)

_, err = numReveals(signedWeight, lnProvenWt, stateProofStrengthTargetForTests)
Expand All @@ -86,7 +86,7 @@ func TestLnWithPrecision(t *testing.T) {
partitiontest.PartitionTest(t)
a := require.New(t)

val, err := lnIntApproximation(2)
val, err := LnIntApproximation(2)
a.NoError(err)

// check that precisionBits will not overflow
Expand All @@ -96,7 +96,7 @@ func TestLnWithPrecision(t *testing.T) {
a.GreaterOrEqual(float64(val)/float64(exp), math.Log(2))
a.Greater(math.Log(2), float64(val-1)/float64(exp))

ln2, err := lnIntApproximation(2)
ln2, err := LnIntApproximation(2)
a.NoError(err)
a.Equal(ln2IntApproximation, ln2)
}
Expand All @@ -107,7 +107,7 @@ func TestVerifyLimits(t *testing.T) {

signedWeight := uint64(0)
provenWeight := uint64(1<<10 - 1)
lnProvenWt, err := lnIntApproximation(provenWeight)
lnProvenWt, err := LnIntApproximation(provenWeight)
a.NoError(err)

err = verifyWeights(signedWeight, lnProvenWt, MaxReveals-1, stateProofStrengthTargetForTests)
Expand Down Expand Up @@ -135,7 +135,7 @@ func TestNumRevealsApproxBound(t *testing.T) {
func checkRatio(i int, sigWt uint64, secParam uint64, a *require.Assertions) {
provenWtRatio := 3 - (float64(i) / 10)
provenWt := uint64(float64(sigWt) / (provenWtRatio))
lnProvenWt, err := lnIntApproximation(provenWt)
lnProvenWt, err := LnIntApproximation(provenWt)
a.NoError(err)

numOfReveals, err := numReveals(sigWt, lnProvenWt, secParam)
Expand All @@ -159,7 +159,7 @@ func TestNumReveals(t *testing.T) {
microalgo := uint64(1000 * 1000)
provenWeight := 2 * billion * microalgo
strengthTarget := uint64(stateProofStrengthTargetForTests)
lnProvenWt, err := lnIntApproximation(provenWeight)
lnProvenWt, err := LnIntApproximation(provenWeight)
a.NoError(err)

for i := uint64(3); i < 10; i++ {
Expand All @@ -183,7 +183,7 @@ func BenchmarkVerifyWeights(b *testing.B) {
signedWeight := 110 * billion * microalgo
strengthTarget := uint64(stateProofStrengthTargetForTests)

lnProvenWt, err := lnIntApproximation(provenWeight)
lnProvenWt, err := LnIntApproximation(provenWeight)
require.NoError(b, err)

nr, err := numReveals(signedWeight, lnProvenWt, strengthTarget)
Expand All @@ -203,7 +203,7 @@ func BenchmarkNumReveals(b *testing.B) {
provenWeight := 100 * billion * microalgo
signedWeight := 110 * billion * microalgo
strengthTarget := uint64(stateProofStrengthTargetForTests)
lnProvenWt, err := lnIntApproximation(provenWeight)
lnProvenWt, err := LnIntApproximation(provenWeight)
require.NoError(b, err)

nr, err := numReveals(signedWeight, lnProvenWt, strengthTarget)
Expand Down
Loading