Skip to content

Commit 281689d

Browse files
authored
Merge pull request #4651 from Algo-devops-service/relbeta3.11.0
2 parents 2145c29 + 6a3156e commit 281689d

File tree

29 files changed

+8823
-6780
lines changed

29 files changed

+8823
-6780
lines changed

cmd/goal/application.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,6 @@ func init() {
191191

192192
panicIfErr(methodAppCmd.MarkFlagRequired("method"))
193193
panicIfErr(methodAppCmd.MarkFlagRequired("from"))
194-
panicIfErr(appCmd.PersistentFlags().MarkHidden("app-arg"))
195194
}
196195

197196
func panicIfErr(err error) {

config/version.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ const VersionMajor = 3
3333

3434
// VersionMinor is the Minor semantic version number (x.#.z) - changed when backwards-compatible features are introduced.
3535
// Not enforced until after initial public release (x > 0).
36-
const VersionMinor = 10
36+
const VersionMinor = 11
3737

3838
// Version is the type holding our full version information.
3939
type Version struct {

crypto/batchverifier.go

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -109,26 +109,34 @@ func (b *BatchVerifier) getNumberOfEnqueuedSignatures() int {
109109
}
110110

111111
// Verify verifies that all the signatures are valid. in that case nil is returned
112-
// if the batch is zero an appropriate error is return.
113112
func (b *BatchVerifier) Verify() error {
113+
_, err := b.VerifyWithFeedback()
114+
return err
115+
}
116+
117+
// VerifyWithFeedback verifies that all the signatures are valid.
118+
// if all sigs are valid, nil will be returned for err (failed will have all false)
119+
// if some signatures are invalid, true will be set in failed at the corresponding indexes, and
120+
// ErrBatchVerificationFailed for err
121+
func (b *BatchVerifier) VerifyWithFeedback() (failed []bool, err error) {
114122
if b.getNumberOfEnqueuedSignatures() == 0 {
115-
return nil
123+
return nil, nil
116124
}
117-
118125
var messages = make([][]byte, b.getNumberOfEnqueuedSignatures())
119126
for i, m := range b.messages {
120127
messages[i] = HashRep(m)
121128
}
122-
if batchVerificationImpl(messages, b.publicKeys, b.signatures) {
123-
return nil
129+
allValid, failed := batchVerificationImpl(messages, b.publicKeys, b.signatures)
130+
if allValid {
131+
return failed, nil
124132
}
125-
return ErrBatchVerificationFailed
126-
133+
return failed, ErrBatchVerificationFailed
127134
}
128135

129136
// batchVerificationImpl invokes the ed25519 batch verification algorithm.
130137
// it returns true if all the signatures were authentically signed by the owners
131-
func batchVerificationImpl(messages [][]byte, publicKeys []SignatureVerifier, signatures []Signature) bool {
138+
// otherwise, returns false, and sets the indexes of the failed sigs in failed
139+
func batchVerificationImpl(messages [][]byte, publicKeys []SignatureVerifier, signatures []Signature) (allSigsValid bool, failed []bool) {
132140

133141
numberOfSignatures := len(messages)
134142

@@ -164,5 +172,10 @@ func batchVerificationImpl(messages [][]byte, publicKeys []SignatureVerifier, si
164172
C.size_t(len(messages)),
165173
(*C.int)(unsafe.Pointer(valid)))
166174

167-
return allValid == 0
175+
failed = make([]bool, numberOfSignatures)
176+
for i := 0; i < numberOfSignatures; i++ {
177+
cint := *(*C.int)(unsafe.Pointer(uintptr(valid) + uintptr(i*C.sizeof_int)))
178+
failed[i] = (cint == 0)
179+
}
180+
return allValid == 0, failed
168181
}

crypto/batchverifier_test.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package crypto
1818

1919
import (
20+
"math/rand"
2021
"testing"
2122

2223
"github.com/stretchr/testify/require"
@@ -123,4 +124,72 @@ func TestEmpty(t *testing.T) {
123124
partitiontest.PartitionTest(t)
124125
bv := MakeBatchVerifier()
125126
require.NoError(t, bv.Verify())
127+
128+
failed, err := bv.VerifyWithFeedback()
129+
require.NoError(t, err)
130+
require.Empty(t, failed)
131+
}
132+
133+
// TestBatchVerifierIndividualResults tests that VerifyWithFeedback
134+
// returns the correct failed signature indexes
135+
func TestBatchVerifierIndividualResults(t *testing.T) {
136+
partitiontest.PartitionTest(t)
137+
138+
for i := 1; i < 64*2+3; i++ {
139+
n := i
140+
bv := MakeBatchVerifierWithHint(n)
141+
var s Seed
142+
badSigs := make([]bool, n, n)
143+
hasBadSig := false
144+
for i := 0; i < n; i++ {
145+
msg := randString()
146+
RandBytes(s[:])
147+
sigSecrets := GenerateSignatureSecrets(s)
148+
sig := sigSecrets.Sign(msg)
149+
if rand.Float32() > 0.5 {
150+
// make a bad sig
151+
sig[0] = sig[0] + 1
152+
badSigs[i] = true
153+
hasBadSig = true
154+
}
155+
bv.EnqueueSignature(sigSecrets.SignatureVerifier, msg, sig)
156+
}
157+
require.Equal(t, n, bv.getNumberOfEnqueuedSignatures())
158+
failed, err := bv.VerifyWithFeedback()
159+
if hasBadSig {
160+
require.ErrorIs(t, err, ErrBatchVerificationFailed)
161+
} else {
162+
require.NoError(t, err)
163+
}
164+
require.Equal(t, len(badSigs), len(failed))
165+
for i := range badSigs {
166+
require.Equal(t, badSigs[i], failed[i])
167+
}
168+
}
169+
}
170+
171+
// TestBatchVerifierIndividualResultsAllValid tests that VerifyWithFeedback
172+
// returns the correct failed signature indexes when all are valid
173+
func TestBatchVerifierIndividualResultsAllValid(t *testing.T) {
174+
partitiontest.PartitionTest(t)
175+
176+
for i := 1; i < 64*2+3; i++ {
177+
n := i
178+
bv := MakeBatchVerifierWithHint(n)
179+
var s Seed
180+
for i := 0; i < n; i++ {
181+
msg := randString()
182+
RandBytes(s[:])
183+
sigSecrets := GenerateSignatureSecrets(s)
184+
sig := sigSecrets.Sign(msg)
185+
bv.EnqueueSignature(sigSecrets.SignatureVerifier, msg, sig)
186+
}
187+
require.Equal(t, n, bv.getNumberOfEnqueuedSignatures())
188+
failed, err := bv.VerifyWithFeedback()
189+
require.NoError(t, err)
190+
require.Equal(t, bv.getNumberOfEnqueuedSignatures(), len(failed))
191+
for _, f := range failed {
192+
require.False(t, f)
193+
}
194+
}
126195
}

crypto/onetimesig.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,12 +319,12 @@ func (v OneTimeSignatureVerifier) Verify(id OneTimeSignatureIdentifier, message
319319
Batch: id.Batch,
320320
}
321321

322-
return batchVerificationImpl(
322+
allValid, _ := batchVerificationImpl(
323323
[][]byte{HashRep(batchID), HashRep(offsetID), HashRep(message)},
324324
[]PublicKey{PublicKey(v), PublicKey(batchID.SubKeyPK), PublicKey(offsetID.SubKeyPK)},
325325
[]Signature{Signature(sig.PK2Sig), Signature(sig.PK1Sig), Signature(sig.Sig)},
326326
)
327-
327+
return allValid
328328
}
329329

330330
// DeleteBeforeFineGrained deletes ephemeral keys before (but not including) the given id.

daemon/kmd/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# kmd - Key Management Daemon
22

33
## Overview
4-
kmd is the Key Management Daemon, the process responsible for securely managing spending keys. It is the implementation of the design [specified here.](https://docs.google.com/document/d/1j7sLC2BphSFqd76GEIJvw4GpY2tNW7nmk_Ea7UfBEWc/edit?usp=sharing)
4+
kmd is the Key Management Daemon, the process responsible for securely managing spending keys.
55

66
## Useful facts
77
- kmd has a data directory separate from algod's data directory. By default, however, the kmd data directory is in the `kmd` subdirectory of algod's data directory.

0 commit comments

Comments
 (0)