diff --git a/crypto/crypto.go b/crypto/crypto.go index 57b51426..a734f91d 100644 --- a/crypto/crypto.go +++ b/crypto/crypto.go @@ -17,6 +17,9 @@ var txidPrefix = []byte("TX") // bidPrefix is prepended to a bid when signing it var bidPrefix = []byte("aB") +// bytesPrefix is prepended to bytes when signing +var bytesPrefix = []byte("NF") + // RandomBytes fills the passed slice with randomness, and panics if it is // unable to do so func RandomBytes(s []byte) { @@ -87,6 +90,23 @@ func rawSignTransaction(sk ed25519.PrivateKey, tx types.Transaction) (s types.Si return } +// SignBytes signs the bytes and returns the signature +func SignBytes(sk ed25519.PrivateKey, bytesToSign []byte) (signature []byte, err error) { + // prepend the prefix for signing bytes + toBeSigned := bytes.Join([][]byte{bytesPrefix, bytesToSign}, nil) + + // sign the bytes + signature = ed25519.Sign(sk, toBeSigned) + return +} + +//VerifyBytes verifies that the signature is valid +func VerifyBytes(pk ed25519.PublicKey, message, signature []byte) bool { + msgParts := [][]byte{bytesPrefix, message} + toBeVerified := bytes.Join(msgParts, nil) + return ed25519.Verify(pk, toBeVerified, signature) +} + // SignBid accepts a private key and a bid, and returns the signature of the // bid under that key func SignBid(sk ed25519.PrivateKey, bid types.Bid) (signedBid []byte, err error) { diff --git a/crypto/crypto_test.go b/crypto/crypto_test.go index f9604933..ce907ad0 100644 --- a/crypto/crypto_test.go +++ b/crypto/crypto_test.go @@ -4,6 +4,7 @@ import ( "github.com/algorand/go-algorand-sdk/encoding/msgpack" "github.com/algorand/go-algorand-sdk/mnemonic" "testing" + "math/rand" "github.com/stretchr/testify/require" "golang.org/x/crypto/ed25519" @@ -116,3 +117,18 @@ func TestMergeMultisigTransactions(t *testing.T) { expectedTxid := "2U2QKCYSYA3DUJNVP5T2KWBLWVUMX4PPIGN43IPPVGVZKTNFKJFQ" require.Equal(t, expectedTxid, txid) } + +func TestSignBytes(t *testing.T) { + account := GenerateAccount() + message := make([]byte, 15) + rand.Read(message) + signature, err := SignBytes(account.PrivateKey, message) + require.NoError(t, err) + require.True(t, VerifyBytes(account.PublicKey, message, signature)) + if message[0] == 255 { + message[0] = 0 + } else { + message[0] = message[0]+1 + } + require.False(t, VerifyBytes(account.PublicKey, message, signature)) +}