-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(wire): add ecdsa authentication to wire #51
base: main
Are you sure you want to change the base?
Changes from 3 commits
be977f6
ae8cd3e
6a03dc2
73eef3a
4c96443
99867bb
03ce1db
81b5fc8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,12 +15,12 @@ | |
package wire | ||
|
||
import ( | ||
"bytes" | ||
"errors" | ||
"math/rand" | ||
|
||
"github.com/ethereum/go-ethereum/crypto" | ||
"github.com/perun-network/perun-eth-backend/wallet" | ||
"github.com/perun-network/perun-eth-backend/wallet/test" | ||
"github.com/pkg/errors" | ||
|
||
"perun.network/go-perun/wire" | ||
) | ||
|
@@ -32,7 +32,7 @@ type Address struct { | |
|
||
// NewAddress returns a new address. | ||
func NewAddress() *Address { | ||
return &Address{} | ||
return &Address{Address: &wallet.Address{}} | ||
} | ||
|
||
// Equal returns whether the two addresses are equal. | ||
|
@@ -41,6 +41,7 @@ func (a Address) Equal(b wire.Address) bool { | |
if !ok { | ||
panic("wrong type") | ||
} | ||
|
||
return a.Address.Equal(bTyped.Address) | ||
} | ||
|
||
|
@@ -62,9 +63,28 @@ func NewRandomAddress(rng *rand.Rand) *Address { | |
|
||
// Verify verifies a message signature. | ||
// It returns an error if the signature is invalid. | ||
func (a Address) Verify(_ []byte, sig []byte) error { | ||
if !bytes.Equal(sig, []byte("Authenticate")) { | ||
return errors.New("invalid signature") | ||
func (a Address) Verify(msg []byte, sig []byte) error { | ||
hash := PrefixedHash(msg) | ||
sigCopy := make([]byte, SigLen) | ||
copy(sigCopy, sig) | ||
if len(sigCopy) == SigLen && (sigCopy[SigLen-1] >= sigVSubtract) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it intentional that we don't compare I think this implementation allows 65 byte signatures with arbitrary bytes after it, not sure if that's a problem. From the For example, the following would be seen as valid by this function:
As said: I don't think it's problematic, but I think it would be cleaner if this function would only allow signatures of exactly 65 bytes. |
||
sigCopy[SigLen-1] -= sigVSubtract | ||
} | ||
pk, err := crypto.SigToPub(hash, sigCopy) | ||
if err != nil { | ||
return errors.WithStack(err) | ||
} | ||
addr := crypto.PubkeyToAddress(*pk) | ||
if !a.Equal(&Address{wallet.AsWalletAddr(addr)}) { | ||
return errors.New("signature verification failed") | ||
} | ||
return nil | ||
} | ||
|
||
// PrefixedHash adds an ethereum specific prefix to the hash of given data, rehashes the results | ||
// and returns it. | ||
func PrefixedHash(data []byte) []byte { | ||
hash := crypto.Keccak256(data) | ||
prefix := []byte("\x19Ethereum Signed Message:\n32") | ||
return crypto.Keccak256(prefix, hash) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// Copyright 2024 - See NOTICE file for copyright holders. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
// Package wire contains a simplistic implementation of the perun wire's | ||
// account, and address interfaces. | ||
// An account can be instantiated directly with a random secret key. | ||
// The account and address offer Handshake Authentication through Go-Perun Wire. | ||
package wire // import "github.com/perun-network/perun-eth-backend/wire" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// Copyright 2024 - See NOTICE file for copyright holders. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package wire_test | ||
|
||
import ( | ||
"math/rand" | ||
"testing" | ||
|
||
"github.com/perun-network/perun-eth-backend/wire" | ||
"github.com/stretchr/testify/assert" | ||
perunwire "perun.network/go-perun/wire" | ||
"perun.network/go-perun/wire/test" | ||
pkgtest "polycry.pt/poly-go/test" | ||
) | ||
|
||
var dataToSign = []byte("SomeLongDataThatShouldBeSignedPlease") | ||
|
||
func TestAddress(t *testing.T) { | ||
test.TestAddressImplementation(t, func() perunwire.Address { | ||
return wire.NewAddress() | ||
}, func(rng *rand.Rand) perunwire.Address { | ||
return wire.NewRandomAddress(rng) | ||
}) | ||
} | ||
|
||
func TestSignatures(t *testing.T) { | ||
acc := wire.NewRandomAccount(pkgtest.Prng(t)) | ||
sig, err := acc.Sign(dataToSign) | ||
assert.NoError(t, err, "Sign with new account should succeed") | ||
assert.NotNil(t, sig) | ||
assert.Equal(t, len(sig), wire.SigLen, "Ethereum signature has wrong length") | ||
err = acc.Address().Verify(dataToSign, sig) | ||
assert.NoError(t, err, "Verification should succeed") | ||
DragonDev1906 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wenn wir schon sigVSubtract als konstante haben sollten wir die hier auch verwenden. Evtl. ist
sigVOffset
ein passenderer Name.