forked from OffchainLabs/nitro
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsignature_verifier.go
127 lines (110 loc) · 3.68 KB
/
signature_verifier.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// Copyright 2024, Offchain Labs, Inc.
// For license information, see https://github.com/nitro/blob/master/LICENSE
package das
import (
"context"
"encoding/hex"
"errors"
"fmt"
"os"
"github.com/ethereum/go-ethereum/crypto"
"github.com/offchainlabs/nitro/solgen/go/bridgegen"
"github.com/offchainlabs/nitro/util/contracts"
)
// SignatureVerifier.Store will try to verify that the passed-in data's signature
// is from the batch poster, or from an injectable verification method.
type SignatureVerifier struct {
addrVerifier *contracts.AddressVerifier
// Extra batch poster verifier, for local installations to have their
// own way of testing Stores.
extraBpVerifier func(message []byte, sig []byte, extraFields ...uint64) bool
}
func NewSignatureVerifier(ctx context.Context, config DataAvailabilityConfig) (*SignatureVerifier, error) {
if config.ParentChainNodeURL == "none" {
return NewSignatureVerifierWithSeqInboxCaller(nil, config.ExtraSignatureCheckingPublicKey)
}
l1client, err := GetL1Client(ctx, config.ParentChainConnectionAttempts, config.ParentChainNodeURL)
if err != nil {
return nil, err
}
seqInboxAddress, err := OptionalAddressFromString(config.SequencerInboxAddress)
if err != nil {
return nil, err
}
if seqInboxAddress == nil {
return NewSignatureVerifierWithSeqInboxCaller(nil, config.ExtraSignatureCheckingPublicKey)
}
seqInboxCaller, err := bridgegen.NewSequencerInboxCaller(*seqInboxAddress, l1client)
if err != nil {
return nil, err
}
return NewSignatureVerifierWithSeqInboxCaller(seqInboxCaller, config.ExtraSignatureCheckingPublicKey)
}
func NewSignatureVerifierWithSeqInboxCaller(
seqInboxCaller *bridgegen.SequencerInboxCaller,
extraSignatureCheckingPublicKey string,
) (*SignatureVerifier, error) {
var addrVerifier *contracts.AddressVerifier
if seqInboxCaller != nil {
addrVerifier = contracts.NewAddressVerifier(seqInboxCaller)
}
var extraBpVerifier func(message []byte, sig []byte, extraFeilds ...uint64) bool
if extraSignatureCheckingPublicKey != "" {
var pubkey []byte
var err error
if extraSignatureCheckingPublicKey[:2] == "0x" {
pubkey, err = hex.DecodeString(extraSignatureCheckingPublicKey[2:])
if err != nil {
return nil, err
}
} else {
pubkeyEncoded, err := os.ReadFile(extraSignatureCheckingPublicKey)
if err != nil {
return nil, err
}
pubkey, err = hex.DecodeString(string(pubkeyEncoded))
if err != nil {
return nil, err
}
}
extraBpVerifier = func(message []byte, sig []byte, extraFields ...uint64) bool {
if len(sig) >= 64 {
return crypto.VerifySignature(pubkey, dasStoreHash(message, extraFields...), sig[:64])
}
return false
}
}
return &SignatureVerifier{
addrVerifier: addrVerifier,
extraBpVerifier: extraBpVerifier,
}, nil
}
func (v *SignatureVerifier) verify(
ctx context.Context, message []byte, sig []byte, extraFields ...uint64) error {
if v.extraBpVerifier == nil && v.addrVerifier == nil {
return errors.New("no signature verification method configured")
}
var verified bool
if v.extraBpVerifier != nil {
verified = v.extraBpVerifier(message, sig, extraFields...)
}
if !verified && v.addrVerifier != nil {
actualSigner, err := DasRecoverSigner(message, sig, extraFields...)
if err != nil {
return err
}
verified, err = v.addrVerifier.IsBatchPosterOrSequencer(ctx, actualSigner)
if err != nil {
return err
}
}
if !verified {
return errors.New("request not properly signed")
}
return nil
}
func (v *SignatureVerifier) String() string {
hasAddrVerifier := v.addrVerifier != nil
hasExtraBpVerifier := v.extraBpVerifier != nil
return fmt.Sprintf("SignatureVerifier{hasAddrVerifier:%v,hasExtraBpVerifier:%v}", hasAddrVerifier, hasExtraBpVerifier)
}