|
5 | 5 | "crypto" |
6 | 6 | "crypto/ed25519" |
7 | 7 | "crypto/rand" |
| 8 | + "crypto/sha256" |
8 | 9 | "encoding/hex" |
9 | 10 | "fmt" |
10 | 11 | "io" |
@@ -72,28 +73,40 @@ func (s *Ed25519Signer) Sign(r io.Reader, digest []byte, opts crypto.SignerOpts) |
72 | 73 | } |
73 | 74 |
|
74 | 75 | var P2PAccountKey = "P2P_SIGNER" |
| 76 | +var StandardCapabilitiesPrefix = "STANDARD_CAPABILITIES_MESSAGE_" |
75 | 77 |
|
76 | | -// singleAccountSigner implements Keystore for a single account. |
77 | | -type singleAccountSigner struct { |
| 78 | +// prefixedSingleAccountSigner implements Keystore for a single account. |
| 79 | +type prefixedSingleAccountSigner struct { |
| 80 | + prefix string |
78 | 81 | account *string |
79 | 82 | signer crypto.Signer |
80 | 83 | } |
81 | 84 |
|
82 | | -var _ Keystore = &singleAccountSigner{} |
| 85 | +var _ Keystore = &prefixedSingleAccountSigner{} |
83 | 86 |
|
84 | | -func NewSingleAccountSigner(account *string, signer crypto.Signer) (*singleAccountSigner, error) { |
85 | | - return &singleAccountSigner{account: account, signer: signer}, nil |
| 87 | +func NewPrefixedSingleAccountSigner(account *string, signer crypto.Signer, prefix string) (*prefixedSingleAccountSigner, error) { |
| 88 | + return &prefixedSingleAccountSigner{account: account, signer: signer, prefix: prefix}, nil |
86 | 89 | } |
87 | | -func (c *singleAccountSigner) Accounts(ctx context.Context) (accounts []string, err error) { |
| 90 | + |
| 91 | +func (c *prefixedSingleAccountSigner) Accounts(ctx context.Context) (accounts []string, err error) { |
88 | 92 | if c.account == nil { |
89 | 93 | return nil, fmt.Errorf("account is nil") |
90 | 94 | } |
91 | 95 |
|
92 | 96 | return []string{*c.account}, nil |
93 | 97 | } |
94 | | -func (c *singleAccountSigner) Sign(ctx context.Context, account string, data []byte) (signed []byte, err error) { |
| 98 | + |
| 99 | +// Sign returns data signed by the single account. |
| 100 | +// Data is prefixed with c.prefix and then hashed with SHA-256 before signing. |
| 101 | +func (c *prefixedSingleAccountSigner) Sign(ctx context.Context, account string, data []byte) (signed []byte, err error) { |
95 | 102 | if c.account != nil && *c.account == account { |
96 | | - return c.signer.Sign(rand.Reader, data, crypto.Hash(0)) |
| 103 | + return c.signer.Sign(rand.Reader, CalcPrefixedHash(c.prefix, data), crypto.Hash(0)) |
97 | 104 | } |
98 | 105 | return nil, fmt.Errorf("account not found: %s", account) |
99 | 106 | } |
| 107 | + |
| 108 | +func CalcPrefixedHash(prefix string, data []byte) []byte { |
| 109 | + prefixedData := append([]byte(prefix), data...) |
| 110 | + hash := sha256.Sum256(prefixedData) |
| 111 | + return hash[:] |
| 112 | +} |
0 commit comments