Skip to content

Commit 863b134

Browse files
authored
Merge pull request #6558 from oasisprotocol/peternose/trivial/batch-signature
go/roothash/api: Add batch signature to proposal
2 parents 27cd0fc + d4c9288 commit 863b134

3 files changed

Lines changed: 51 additions & 3 deletions

File tree

.changelog/6557.trivial.md

Whitespace-only changes.

go/roothash/api/api.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,10 @@ func (ev *EquivocationProposalEvidence) ValidateBasic(id common.Namespace) error
361361
return fmt.Errorf("batch should be empty for equivocation evidence")
362362
}
363363

364+
if ev.ProposalA.BatchSignature != nil || ev.ProposalB.BatchSignature != nil {
365+
return fmt.Errorf("batch signature should be empty for equivocation evidence")
366+
}
367+
364368
// Since we did the Equal check above, either BatchHash or PreviousHash must be different.
365369

366370
// Verify signatures.

go/roothash/api/commitment/proposal.go

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,20 @@ import (
99
"github.com/oasisprotocol/oasis-core/go/common/crypto/signature"
1010
)
1111

12-
// ProposalSignatureContext is the context used for signing propose batch dispatch messages.
12+
// ProposalSignatureContext is the context used for signing proposal headers.
1313
var ProposalSignatureContext = signature.NewContext(
1414
"oasis-core/roothash: proposal",
1515
signature.WithChainSeparation(),
1616
signature.WithDynamicSuffix(" for runtime ", common.NamespaceHexSize),
1717
)
1818

19+
// ProposalBatchSignatureContext is the context used for signing proposal batches.
20+
var ProposalBatchSignatureContext = signature.NewContext(
21+
"oasis-core/roothash: proposal batch",
22+
signature.WithChainSeparation(),
23+
signature.WithDynamicSuffix(" for runtime ", common.NamespaceHexSize),
24+
)
25+
1926
// ProposalHeader is the header of the batch proposal.
2027
type ProposalHeader struct {
2128
// Round is the proposed round number.
@@ -67,9 +74,17 @@ type Proposal struct {
6774
// Signature is the proposal header signature.
6875
Signature signature.RawSignature `json:"sig"`
6976

70-
// Batch is an ordered list of all transaction hashes that should be in a batch. In case of
71-
// the proposal being submitted as equivocation evidence, this field should be omitted.
77+
// Batch is an ordered list of all transaction hashes that should be in a batch.
78+
//
79+
// In case of the proposal being submitted as equivocation evidence,
80+
// this field should be omitted.
7281
Batch []hash.Hash `json:"batch,omitempty"`
82+
83+
// BatchSignature is the proposal batch signature.
84+
//
85+
// In case of the proposal being submitted as equivocation evidence,
86+
// this field should be omitted.
87+
BatchSignature *signature.RawSignature `json:"batch_sig,omitempty"`
7388
}
7489

7590
// Sign signs the proposal header and sets the signature on the proposal.
@@ -83,6 +98,23 @@ func (p *Proposal) Sign(signer signature.Signer, runtimeID common.Namespace) err
8398
return err
8499
}
85100
p.Signature = *sig
101+
102+
// TODO: Sign the batch once most of the compute nodes have been upgraded to a version
103+
// that supports batch signatures.
104+
if false {
105+
batchSigCtx, err := ProposalBatchSignatureContext.WithSuffix(runtimeID.String())
106+
if err != nil {
107+
return fmt.Errorf("roothash/commitment: batch signature context error: %w", err)
108+
}
109+
110+
signature, err := signature.Sign(signer, batchSigCtx, cbor.Marshal(p.Batch))
111+
if err != nil {
112+
return err
113+
}
114+
115+
p.BatchSignature = &signature.Signature
116+
}
117+
86118
return nil
87119
}
88120

@@ -96,5 +128,17 @@ func (p *Proposal) Verify(runtimeID common.Namespace) error {
96128
if !p.NodeID.Verify(sigCtx, cbor.Marshal(p.Header), p.Signature[:]) {
97129
return fmt.Errorf("roothash/commitment: signature verification failed")
98130
}
131+
132+
if p.BatchSignature != nil {
133+
batchSigCtx, err := ProposalBatchSignatureContext.WithSuffix(runtimeID.String())
134+
if err != nil {
135+
return fmt.Errorf("roothash/commitment: batch signature context error: %w", err)
136+
}
137+
138+
if !p.NodeID.Verify(batchSigCtx, cbor.Marshal(p.Batch), p.BatchSignature[:]) {
139+
return fmt.Errorf("roothash/commitment: batch signature verification failed")
140+
}
141+
}
142+
99143
return nil
100144
}

0 commit comments

Comments
 (0)