Skip to content

Commit

Permalink
Merge pull request algorand#4618 from Algo-devops-service/relstable3.…
Browse files Browse the repository at this point in the history
…10.0

go-algorand 3.10.0-stable Release PR
  • Loading branch information
algojohnlee authored Oct 4, 2022
2 parents 4deb520 + ad69a47 commit c515c12
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 79 deletions.
11 changes: 5 additions & 6 deletions batchverifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ const minBatchVerifierAlloc = 16
// Batch verifications errors
var (
ErrBatchVerificationFailed = errors.New("At least one signature didn't pass verification")
ErrZeroTransactionInBatch = errors.New("Could not validate empty signature set")
)

//export ed25519_randombytes_unsafe
Expand Down Expand Up @@ -104,19 +103,19 @@ func (b *BatchVerifier) expand() {
b.signatures = signatures
}

// GetNumberOfEnqueuedSignatures returns the number of signatures current enqueue onto the bacth verifier object
func (b *BatchVerifier) GetNumberOfEnqueuedSignatures() int {
// getNumberOfEnqueuedSignatures returns the number of signatures current enqueue onto the bacth verifier object
func (b *BatchVerifier) getNumberOfEnqueuedSignatures() int {
return len(b.messages)
}

// Verify verifies that all the signatures are valid. in that case nil is returned
// if the batch is zero an appropriate error is return.
func (b *BatchVerifier) Verify() error {
if b.GetNumberOfEnqueuedSignatures() == 0 {
return ErrZeroTransactionInBatch
if b.getNumberOfEnqueuedSignatures() == 0 {
return nil
}

var messages = make([][]byte, b.GetNumberOfEnqueuedSignatures())
var messages = make([][]byte, b.getNumberOfEnqueuedSignatures())
for i, m := range b.messages {
messages[i] = HashRep(m)
}
Expand Down
4 changes: 2 additions & 2 deletions batchverifier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func TestBatchVerifierBulk(t *testing.T) {
sig := sigSecrets.Sign(msg)
bv.EnqueueSignature(sigSecrets.SignatureVerifier, msg, sig)
}
require.Equal(t, n, bv.GetNumberOfEnqueuedSignatures())
require.Equal(t, n, bv.getNumberOfEnqueuedSignatures())
require.NoError(t, bv.Verify())
}

Expand Down Expand Up @@ -122,5 +122,5 @@ func BenchmarkBatchVerifier(b *testing.B) {
func TestEmpty(t *testing.T) {
partitiontest.PartitionTest(t)
bv := MakeBatchVerifier()
require.Error(t, bv.Verify())
require.NoError(t, bv.Verify())
}
3 changes: 2 additions & 1 deletion merklesignature/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package merklesignature

import (
"fmt"

"github.com/algorand/go-algorand/crypto"
)

Expand All @@ -40,7 +41,7 @@ const (
var NoKeysCommitment = Commitment{}

func init() {
// no keys generated, inner tree of merkle siganture scheme is empty.
// no keys generated, inner tree of merkle signature scheme is empty.
o, err := New(KeyLifetimeDefault+1, KeyLifetimeDefault+2, KeyLifetimeDefault)
if err != nil {
panic(fmt.Errorf("initializing empty merkle signature scheme failed, err: %w", err))
Expand Down
49 changes: 16 additions & 33 deletions multisig.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,33 +216,23 @@ func MultisigAssemble(unisig []MultisigSig) (msig MultisigSig, err error) {
}

// MultisigVerify verifies an assembled MultisigSig
func MultisigVerify(msg Hashable, addr Digest, sig MultisigSig) (verified bool, err error) {
func MultisigVerify(msg Hashable, addr Digest, sig MultisigSig) (err error) {
batchVerifier := MakeBatchVerifier()

if verified, err = MultisigBatchVerify(msg, addr, sig, batchVerifier); err != nil {
if err = MultisigBatchPrep(msg, addr, sig, batchVerifier); err != nil {
return
}
if !verified {
return
}
if batchVerifier.GetNumberOfEnqueuedSignatures() == 0 {
return true, nil
}
if err = batchVerifier.Verify(); err != nil {
return false, err
}
return true, nil
err = batchVerifier.Verify()
return
}

// MultisigBatchVerify verifies an assembled MultisigSig.
// it is the caller responsibility to call batchVerifier.verify()
func MultisigBatchVerify(msg Hashable, addr Digest, sig MultisigSig, batchVerifier *BatchVerifier) (verified bool, err error) {
verified = false
// MultisigBatchPrep performs checks on the assembled MultisigSig and adds to the batch.
// The caller must call batchVerifier.verify() to verify it.
func MultisigBatchPrep(msg Hashable, addr Digest, sig MultisigSig, batchVerifier *BatchVerifier) (err error) {
// short circuit: if msig doesn't have subsigs or if Subsigs are empty
// then terminate (the upper layer should now verify the unisig)
if (len(sig.Subsigs) == 0 || sig.Subsigs[0] == MultisigSubsig{}) {
err = errInvalidNumberOfSignature
return
return errInvalidNumberOfSignature
}

// check the address is correct
Expand All @@ -251,20 +241,17 @@ func MultisigBatchVerify(msg Hashable, addr Digest, sig MultisigSig, batchVerifi
return
}
if addr != addrnew {
err = errInvalidAddress
return
return errInvalidAddress
}

// check that we don't have too many multisig subsigs
if len(sig.Subsigs) > maxMultisig {
err = errInvalidNumberOfSignature
return
return errInvalidNumberOfSignature
}

// check that we don't have too few multisig subsigs
if len(sig.Subsigs) < int(sig.Threshold) {
err = errInvalidNumberOfSignature
return
return errInvalidNumberOfSignature
}

// checks the number of non-blank signatures is no less than threshold
Expand All @@ -275,27 +262,23 @@ func MultisigBatchVerify(msg Hashable, addr Digest, sig MultisigSig, batchVerifi
}
}
if counter < sig.Threshold {
err = errInvalidNumberOfSignature
return
return errInvalidNumberOfSignature
}

// checks individual signature verifies
var verifiedCount int
var sigCount int
for _, subsigi := range sig.Subsigs {
if (subsigi.Sig != Signature{}) {
batchVerifier.EnqueueSignature(subsigi.Key, msg, subsigi.Sig)
verifiedCount++
sigCount++
}
}

// sanity check. if we get here then every non-blank subsig should have
// been verified successfully, and we should have had enough of them
if verifiedCount < int(sig.Threshold) {
err = errInvalidNumberOfSignature
return
if sigCount < int(sig.Threshold) {
return errInvalidNumberOfSignature
}

verified = true
return
}

Expand Down
51 changes: 17 additions & 34 deletions multisig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,15 +136,13 @@ func TestMultisig(t *testing.T) {
require.NoError(t, err, "Multisig: unexpected failure in generating sig from pk 2")
msig, err = MultisigAssemble(sigs)
require.NoError(t, err, "Multisig: unexpected failure when assembling multisig")
verify, err := MultisigVerify(txid, addr, msig)
err = MultisigVerify(txid, addr, msig)
require.NoError(t, err, "Multisig: unexpected verification failure with err")
require.True(t, verify, "Multisig: verification failed, verify flag was false")

//test3: use the batch verification
br := MakeBatchVerifier()
verify, err = MultisigBatchVerify(txid, addr, msig, br)
err = MultisigBatchPrep(txid, addr, msig, br)
require.NoError(t, err, "Multisig: unexpected verification failure with err")
require.True(t, verify, "Multisig: verification failed, verify flag was false")
res := br.Verify()
require.NoError(t, res, "Multisig: batch verification failed")
}
Expand Down Expand Up @@ -200,8 +198,7 @@ func TestMultisigAddAndMerge(t *testing.T) {
require.NoError(t, err, "Multisig: unexpected failure signing with pk 2")
err = MultisigAdd(sigs, &msig1)
require.NoError(t, err, "Multisig: unexpected err adding pk 2 signature to that of pk 0 and 1")
verify, err := MultisigVerify(txid, addr, msig1)
require.True(t, verify, "Multisig: verification failed, verify flag was false")
err = MultisigVerify(txid, addr, msig1)
require.NoError(t, err, "Multisig: unexpected verification failure with err")

// msig2 = {sig3, sig4}
Expand All @@ -215,9 +212,8 @@ func TestMultisigAddAndMerge(t *testing.T) {
// merge two msigs and then verify
msigt, err := MultisigMerge(msig1, msig2)
require.NoError(t, err, "Multisig: unexpected failure merging multisig messages {0, 1, 2} and {3, 4}")
verify, err = MultisigVerify(txid, addr, msigt)
err = MultisigVerify(txid, addr, msigt)
require.NoError(t, err, "Multisig: unexpected verification failure with err")
require.True(t, verify, "Multisig: verification failed, verify flag was false")

// create a valid duplicate on purpose
// msig1 = {sig0, sig1, sig2}
Expand All @@ -230,9 +226,8 @@ func TestMultisigAddAndMerge(t *testing.T) {
require.NoError(t, err, "Multisig: unexpected failure adding pk 2 signature to that of pk 3 and 4")
msigt, err = MultisigMerge(msig1, msig2)
require.NoError(t, err, "Multisig: unexpected failure merging multisig messages {0, 1, 2} and {2, 3, 4}")
verify, err = MultisigVerify(txid, addr, msigt)
err = MultisigVerify(txid, addr, msigt)
require.NoError(t, err, "Multisig: unexpected verification failure with err")
require.True(t, verify, "Multisig: verification failed, verify flag was false")

return
}
Expand All @@ -254,12 +249,10 @@ func TestEmptyMultisig(t *testing.T) {
addr, err := MultisigAddrGen(version, threshold, pks)
require.NoError(t, err, "Multisig: unexpected failure generating message digest")
emptyMutliSig := MultisigSig{Version: version, Threshold: threshold, Subsigs: make([]MultisigSubsig, 0)}
verify, err := MultisigVerify(txid, addr, emptyMutliSig)
require.False(t, verify, "Multisig: verification succeeded, it should failed")
err = MultisigVerify(txid, addr, emptyMutliSig)
require.Error(t, err, "Multisig: did not return error as expected")
br := MakeBatchVerifier()
verify, err = MultisigBatchVerify(txid, addr, emptyMutliSig, br)
require.False(t, verify, "Multisig: verification succeeded, it should failed")
err = MultisigBatchPrep(txid, addr, emptyMutliSig, br)
require.Error(t, err, "Multisig: did not return error as expected")
}

Expand All @@ -282,12 +275,10 @@ func TestIncorrectAddrresInMultisig(t *testing.T) {
MutliSig, err := MultisigSign(txid, addr, version, threshold, pks, *secrets)
require.NoError(t, err, "Multisig: could not create mutlisig")
addr[0] = addr[0] + 1
verify, err := MultisigVerify(txid, addr, MutliSig)
require.False(t, verify, "Multisig: verification succeeded, it should failed")
err = MultisigVerify(txid, addr, MutliSig)
require.Error(t, err, "Multisig: did not return error as expected")
br := MakeBatchVerifier()
verify, err = MultisigBatchVerify(txid, addr, MutliSig, br)
require.False(t, verify, "Multisig: verification succeeded, it should failed")
err = MultisigBatchPrep(txid, addr, MutliSig, br)
require.Error(t, err, "Multisig: did not return error as expected")

}
Expand Down Expand Up @@ -321,12 +312,10 @@ func TestMoreThanMaxSigsInMultisig(t *testing.T) {

msig, err := MultisigAssemble(sigs)
require.NoError(t, err, "Multisig: error assmeble multisig")
verify, err := MultisigVerify(txid, addr, msig)
require.False(t, verify, "Multisig: verification succeeded, it should failed")
err = MultisigVerify(txid, addr, msig)
require.Error(t, err, "Multisig: did not return error as expected")
br := MakeBatchVerifier()
verify, err = MultisigBatchVerify(txid, addr, msig, br)
require.False(t, verify, "Multisig: verification succeeded, it should failed")
err = MultisigBatchPrep(txid, addr, msig, br)
require.Error(t, err, "Multisig: did not return error as expected")
}

Expand Down Expand Up @@ -360,12 +349,10 @@ func TestOneSignatureIsEmpty(t *testing.T) {
msig, err := MultisigAssemble(sigs)
require.NoError(t, err, "Multisig: error assmeble multisig")
msig.Subsigs[0].Sig = Signature{}
verify, err := MultisigVerify(txid, addr, msig)
require.False(t, verify, "Multisig: verification succeeded, it should failed")
err = MultisigVerify(txid, addr, msig)
require.Error(t, err, "Multisig: did not return error as expected")
br := MakeBatchVerifier()
verify, err = MultisigBatchVerify(txid, addr, msig, br)
require.False(t, verify, "Multisig: verification succeeded, it should failed")
err = MultisigBatchPrep(txid, addr, msig, br)
require.Error(t, err, "Multisig: did not return error as expected")
}

Expand Down Expand Up @@ -401,13 +388,11 @@ func TestOneSignatureIsInvalid(t *testing.T) {
sigs[1].Subsigs[1].Sig[5] = sigs[1].Subsigs[1].Sig[5] + 1
msig, err := MultisigAssemble(sigs)
require.NoError(t, err, "Multisig: error assmeble multisig")
verify, err := MultisigVerify(txid, addr, msig)
require.False(t, verify, "Multisig: verification succeeded, it should failed")
err = MultisigVerify(txid, addr, msig)
require.Error(t, err, "Multisig: did not return error as expected")
br := MakeBatchVerifier()
verify, err = MultisigBatchVerify(txid, addr, msig, br)
err = MultisigBatchPrep(txid, addr, msig, br)
require.NoError(t, err, "Multisig: did not return error as expected")
require.True(t, verify, "Multisig: verification succeeded, it should failed")
res := br.Verify()
require.Error(t, res, "Multisig: batch verification passed on broken signature")

Expand Down Expand Up @@ -455,15 +440,13 @@ func TestMultisigLessThanTrashold(t *testing.T) {
msig, err = MultisigAssemble(sigs)
require.NoError(t, err, "should be able to detect insufficient signatures for assembling")
msig.Subsigs[1].Sig = BlankSignature
verify, err := MultisigVerify(txid, addr, msig)
require.False(t, verify, "Multisig: verification passed, should have failed")
err = MultisigVerify(txid, addr, msig)
require.Error(t, err, "Multisig: expected verification failure with err")

msig, err = MultisigAssemble(sigs)
require.NoError(t, err, "should be able to detect insufficient signatures for assembling")
msig.Subsigs = msig.Subsigs[:len(msig.Subsigs)-1]
verify, err = MultisigVerify(txid, addr, msig)
require.False(t, verify, "Multisig: verification passed, should have failed")
err = MultisigVerify(txid, addr, msig)
require.Error(t, err, "Multisig: expected verification failure with err")

}
7 changes: 4 additions & 3 deletions stateproof/coinGenerator.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ package stateproof

import (
"encoding/binary"
"golang.org/x/crypto/sha3"
"math/big"

"golang.org/x/crypto/sha3"

"github.com/algorand/go-algorand/crypto"
"github.com/algorand/go-algorand/protocol"
)
Expand Down Expand Up @@ -75,7 +76,7 @@ func makeCoinGenerator(choice *coinChoiceSeed) coinGenerator {
choice.version = VersionForCoinGenerator
rep := crypto.HashRep(choice)
shk := sha3.NewShake256()
shk.Write(rep)
shk.Write(rep) //nolint:errcheck // ShakeHash.Write may panic, but does not return error

threshold := prepareRejectionSamplingThreshold(choice.signedWeight)
return coinGenerator{shkContext: shk, signedWeight: choice.signedWeight, threshold: threshold}
Expand Down Expand Up @@ -111,7 +112,7 @@ func (cg *coinGenerator) getNextCoin() uint64 {
var randNumFromXof uint64
for {
var shakeDigest [8]byte
cg.shkContext.Read(shakeDigest[:])
cg.shkContext.Read(shakeDigest[:]) //nolint:errcheck // ShakeHash.Read never returns error
randNumFromXof = binary.LittleEndian.Uint64(shakeDigest[:])

z := &big.Int{}
Expand Down

0 comments on commit c515c12

Please sign in to comment.