diff --git a/go.mod b/go.mod index 253385f30dcb0e255a282fe40bb4e9953d77dc64..aad5d99a3a7601e23f9666f2e8816a12ee1bba3a 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.13 require ( github.com/cloudflare/circl v1.1.0 github.com/liyue201/goqr v0.0.0-20200803022322-df443203d4ea - github.com/multiformats/go-multihash v0.2.1 // indirect + github.com/multiformats/go-multihash v0.2.1 github.com/pkg/errors v0.9.1 github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/spf13/jwalterweatherman v1.1.0 diff --git a/partnerships/crust/hash.go b/partnerships/crust/hash.go index b5702d0b974ced9ff9c4e5de63ffa6cb8b3bbae8..e654a08e2f9732497bb8e2542585be8fa757f649 100644 --- a/partnerships/crust/hash.go +++ b/partnerships/crust/hash.go @@ -1,5 +1,5 @@ //////////////////////////////////////////////////////////////////////////////////////////// -// Copyright © 2020 xx network SEZC // +// Copyright © 2022 xx foundation // // // // Use of this source code is governed by a license that can be found in the LICENSE file // //////////////////////////////////////////////////////////////////////////////////////////// diff --git a/partnerships/crust/jointVerification.go b/partnerships/crust/jointVerification.go new file mode 100644 index 0000000000000000000000000000000000000000..eaee19eb67197332b77b4451b3a644874c8aba5f --- /dev/null +++ b/partnerships/crust/jointVerification.go @@ -0,0 +1,36 @@ +//////////////////////////////////////////////////////////////////////////////////////////// +// Copyright © 2022 xx foundation // +// // +// Use of this source code is governed by a license that can be found in the LICENSE file // +//////////////////////////////////////////////////////////////////////////////////////////// + +package crust + +import ( + "github.com/pkg/errors" + "gitlab.com/xx_network/crypto/signature/rsa" + "time" +) + +// JointVerify verifies both the upload and the verification signature at once +// Both will be sent as part of the auth headers to Crust's upload and pinning +// service, this will make proper usage more clear +// Returns nil for the error if the verification is successful +func JointVerify(UDPubkey, userPublicKey *rsa.PublicKey, usernameHash, + fileHash, verificationSignature, uploadSignature []byte, uploadTs, + now time.Time)error{ + + if err := VerifyVerificationSignature(UDPubkey, usernameHash, + userPublicKey, verificationSignature); err!=nil{ + return errors.WithMessage(err, + "Failed to verify the Verification Signature") + } + + if err := VerifyUpload(userPublicKey, now, uploadTs, fileHash, + uploadSignature); err!=nil{ + return errors.WithMessage(err, + "Failed to verify the Upload Signature") + } + + return nil +} diff --git a/partnerships/crust/jointVerify_test.go b/partnerships/crust/jointVerify_test.go new file mode 100644 index 0000000000000000000000000000000000000000..3e53aa16853ad26b509919430efd6bb2a6351dfe --- /dev/null +++ b/partnerships/crust/jointVerify_test.go @@ -0,0 +1,212 @@ +//////////////////////////////////////////////////////////////////////////////////////////// +// Copyright © 2022 xx foundation // +// // +// Use of this source code is governed by a license that can be found in the LICENSE file // +//////////////////////////////////////////////////////////////////////////////////////////// + +package crust + +import ( + "encoding/base64" + "gitlab.com/xx_network/crypto/signature/rsa" + "testing" + "time" +) + +func TestJointVerify(t *testing.T) { + + UDPrivKey, err := rsa.LoadPrivateKeyFromPem([]byte(PrivKeyPemEncoded)) + if err != nil { + t.Fatalf("Failed to load private key: %v", err) + } + + // Process reception keys + receptionKeys := make([]*rsa.PrivateKey, numTests) + for i := 0; i < numTests; i++ { + receptionKeys[i], err = rsa.LoadPrivateKeyFromPem([]byte(ReceptionKeys[i])) + if err!=nil{ + t.Fatalf("Failed to decode reception key %d/%d: %v", + i, numTests, err) + } + + } + + // Process files + files := make([][]byte, numTests) + for i := 0; i < numTests; i++ { + files[i], err = base64.StdEncoding.DecodeString(Files[i]) + if err != nil { + t.Fatalf("Failed to parse file: %v", err) + } + } + + // Process timestamps + now := time.Unix(0, Now) + timestamps := make([]time.Time, numTests) + for i := 0; i < numTests; i++ { + timestamps[i] = time.Unix(0, UnixNanoTimestamps[i]) + } + + // use insecure seeded rng to ensure repeatability + notRand := &CountingReader{count: uint8(0)} + + // Generate signatures and verify them + for i := 0; i < numTests; i++ { + // Sign verification signature + verifSig, err := SignVerification(notRand, UDPrivKey, + Usernames[i], receptionKeys[i].GetPublic()) + if err != nil { + t.Fatalf("Failed to generate verification sig %d/%d: " + + "%v", i, numTests, err) + } + + // Sign upload signatures + uploadSig, err := SignUpload(notRand, receptionKeys[i], files[i], timestamps[i]) + if err != nil { + t.Fatalf("Failed to generate upload sig " + + "%d/%d: %v", i, numTests, err) + } + + //try to verify the signature + fileHash, err := hashFile(files[i]) + if err != nil { + t.Fatalf("Failed to has file %d/%d: %v", i, numTests, err) + } + + if err = JointVerify(UDPrivKey.GetPublic(), receptionKeys[i].GetPublic(), + hashUsername(Usernames[i]), fileHash, verifSig,uploadSig, + timestamps[i], now); err!=nil{ + t.Fatalf("Joint Verification failed %d/%d: %v", i, numTests, err) + } + } +} + +func TestJointVerify_BadVerificationSig(t *testing.T) { + + UDPrivKey, err := rsa.LoadPrivateKeyFromPem([]byte(PrivKeyPemEncoded)) + if err != nil { + t.Fatalf("Failed to load private key: %v", err) + } + + // Process reception keys + receptionKeys := make([]*rsa.PrivateKey, numTests) + for i := 0; i < numTests; i++ { + receptionKeys[i], err = rsa.LoadPrivateKeyFromPem([]byte(ReceptionKeys[i])) + if err!=nil{ + t.Fatalf("Failed to decode reception key %d/%d: %v", + i, numTests, err) + } + + } + + // Process files + files := make([][]byte, numTests) + for i := 0; i < numTests; i++ { + files[i], err = base64.StdEncoding.DecodeString(Files[i]) + if err != nil { + t.Fatalf("Failed to parse file: %v", err) + } + } + + // Process timestamps + now := time.Unix(0, Now) + timestamps := make([]time.Time, numTests) + for i := 0; i < numTests; i++ { + timestamps[i] = time.Unix(0, UnixNanoTimestamps[i]) + } + + // use insecure seeded rng to ensure repeatability + notRand := &CountingReader{count: uint8(0)} + + // Generate signatures and verify them + for i := 0; i < numTests; i++ { + // Generate bad, random verification signature + verifSig := make([]byte, 32) + notRand.Read(verifSig) + + // Sign upload signatures + uploadSig, err := SignUpload(notRand, receptionKeys[i], files[i], timestamps[i]) + if err != nil { + t.Fatalf("Failed to generate upload sig " + + "%d/%d: %v", i, numTests, err) + } + + //try to verify the signature + fileHash, err := hashFile(files[i]) + if err != nil { + t.Fatalf("Failed to has file %d/%d: %v", i, numTests, err) + } + + if err = JointVerify(UDPrivKey.GetPublic(), receptionKeys[i].GetPublic(), + hashUsername(Usernames[i]), fileHash, verifSig,uploadSig, + timestamps[i], now); err==nil{ + t.Fatalf("Joint Verification succeded with bad verification " + + "signature %d/%d: %v", i, numTests, err) + } + } +} + +func TestJointVerify_BadUploadSig(t *testing.T) { + + UDPrivKey, err := rsa.LoadPrivateKeyFromPem([]byte(PrivKeyPemEncoded)) + if err != nil { + t.Fatalf("Failed to load private key: %v", err) + } + + // Process reception keys + receptionKeys := make([]*rsa.PrivateKey, numTests) + for i := 0; i < numTests; i++ { + receptionKeys[i], err = rsa.LoadPrivateKeyFromPem([]byte(ReceptionKeys[i])) + if err!=nil{ + t.Fatalf("Failed to decode reception key %d/%d: %v", + i, numTests, err) + } + + } + + // Process files + files := make([][]byte, numTests) + for i := 0; i < numTests; i++ { + files[i], err = base64.StdEncoding.DecodeString(Files[i]) + if err != nil { + t.Fatalf("Failed to parse file: %v", err) + } + } + + // Process timestamps + now := time.Unix(0, Now) + timestamps := make([]time.Time, numTests) + for i := 0; i < numTests; i++ { + timestamps[i] = time.Unix(0, UnixNanoTimestamps[i]) + } + + // use insecure seeded rng to ensure repeatability + notRand := &CountingReader{count: uint8(0)} + + // Generate signatures and verify them + for i := 0; i < numTests; i++ { + // Sign verification signature + verifSig, err := SignVerification(notRand, UDPrivKey, + Usernames[i], receptionKeys[i].GetPublic()) + if err != nil { + t.Fatalf("Failed to generate verification sig %d/%d: " + + "%v", i, numTests, err) + } + + // Sign upload signatures + uploadSig := make([]byte, 32) + notRand.Read(uploadSig) + + //try to verify the signature + fileHash, err := hashFile(files[i]) + if err != nil { + t.Fatalf("Failed to has file %d/%d: %v", i, numTests, err) + } + + if err = JointVerify(UDPrivKey.GetPublic(), receptionKeys[i].GetPublic(), + hashUsername(Usernames[i]), fileHash, verifSig,uploadSig, + timestamps[i], now); err==nil{ + t.Fatalf("Joint Verification failed %d/%d: %v", i, numTests, err) + } + } +} \ No newline at end of file diff --git a/partnerships/crust/upload.go b/partnerships/crust/upload.go index 24240ad1b008bd59491bbf832963ddbcbec305d3..3df626e78fb06c1c881c866d7e3589bfd80c9fe2 100644 --- a/partnerships/crust/upload.go +++ b/partnerships/crust/upload.go @@ -1,5 +1,5 @@ //////////////////////////////////////////////////////////////////////////////////////////// -// Copyright © 2020 xx network SEZC // +// Copyright © 2022 xx foundation // // // // Use of this source code is governed by a license that can be found in the LICENSE file // //////////////////////////////////////////////////////////////////////////////////////////// @@ -44,7 +44,7 @@ func SignUpload(rand io.Reader, userPrivKey *rsa.PrivateKey, // from the current time passed in as "now". func VerifyUpload(userPublicKey *rsa.PublicKey, now, timestamp time.Time, - file, signature []byte) error { + fileHash, signature []byte) error { // Check if timestamp is within the grace period startOfPeriod := now.Add(-uploadGracePeriod) @@ -55,12 +55,6 @@ func VerifyUpload(userPublicKey *rsa.PublicKey, timestamp, startOfPeriod.String(), endOfPeriod.String()) } - // Hash file - fileHash, err := hashFile(file) - if err != nil { - return errors.Errorf("Failed to hash file: %v", err) - } - // Hash together timestamp and opts := rsa.NewDefaultOptions() opts.Hash = crypto.SHA256 diff --git a/partnerships/crust/upload_test.go b/partnerships/crust/upload_test.go index 04ea9d5c9ee6267e64f5c6888bc62e8669e7b35d..3882ca03af89401edd197b72af069e932de0edc7 100644 --- a/partnerships/crust/upload_test.go +++ b/partnerships/crust/upload_test.go @@ -1,5 +1,5 @@ //////////////////////////////////////////////////////////////////////////////////////////// -// Copyright © 2020 xx network SEZC // +// Copyright © 2022 xx foundation // // // // Use of this source code is governed by a license that can be found in the LICENSE file // //////////////////////////////////////////////////////////////////////////////////////////// @@ -74,8 +74,10 @@ func TestSignVerifyUpload(t *testing.T) { t.Fatalf("Failed to generate sig %d/%d: %v", i, numTests, err) } + fileHash, _ := hashFile(files[i]) + // Use signature provided above and verify - err = VerifyUpload(privKey.GetPublic(), now, timestamps[i], files[i], sig) + err = VerifyUpload(privKey.GetPublic(), now, timestamps[i], fileHash, sig) if err != nil { t.Fatalf("Failed to verify signature for test %d/%v: %v", i, numTests, err) } diff --git a/partnerships/crust/utils_test.go b/partnerships/crust/utils_test.go index 27aee1662fcded811c8c2510f6353f5d128aea41..67d4e2f2263dfe5da22ac75622c9a8d1de878c8f 100644 --- a/partnerships/crust/utils_test.go +++ b/partnerships/crust/utils_test.go @@ -1,5 +1,5 @@ //////////////////////////////////////////////////////////////////////////////////////////// -// Copyright © 2020 xx network SEZC // +// Copyright © 2022 xx foundation // // // // Use of this source code is governed by a license that can be found in the LICENSE file // //////////////////////////////////////////////////////////////////////////////////////////// diff --git a/partnerships/crust/verification.go b/partnerships/crust/verification.go index db4148ab9579db2599916061c6f6ca0595850d05..ee35b5dadcc7c2a78074253b7825a921f49d549a 100644 --- a/partnerships/crust/verification.go +++ b/partnerships/crust/verification.go @@ -1,5 +1,5 @@ //////////////////////////////////////////////////////////////////////////////////////////// -// Copyright © 2020 xx network SEZC // +// Copyright © 2022 xx foundation // // // // Use of this source code is governed by a license that can be found in the LICENSE file // //////////////////////////////////////////////////////////////////////////////////////////// @@ -15,15 +15,15 @@ import ( // SignVerification signs the user's username and reception public key, hashed together. func SignVerification(rand io.Reader, udPrivKey *rsa.PrivateKey, - username string, receptionPubKey []byte) ([]byte, error) { + username string, receptionPubKey *rsa.PublicKey) ([]byte, error) { // Hash username usernameHash := hashUsername(username) // Create hash to sign on opts := rsa.NewDefaultOptions() opts.Hash = crypto.SHA256 - hashed := makeVerificationSignatureHash(usernameHash, receptionPubKey, - opts.Hash.New()) + hashed := makeVerificationSignatureHash(usernameHash, + receptionPubKey.N.Bytes(), opts.Hash.New()) // Return signature return rsa.Sign(rand, udPrivKey, opts.Hash, hashed, opts) @@ -31,16 +31,13 @@ func SignVerification(rand io.Reader, udPrivKey *rsa.PrivateKey, // VerifyVerificationSignature verifies the signature provided from SignVerification. func VerifyVerificationSignature(pubKey *rsa.PublicKey, - username string, receptionPubKey, signature []byte) error { - - // Hash username - usernameHash := hashUsername(username) + usernameHash []byte, receptionPubKey *rsa.PublicKey, signature []byte) error { // Create hash that was signed opts := rsa.NewDefaultOptions() opts.Hash = crypto.SHA256 - hashed := makeVerificationSignatureHash(usernameHash, receptionPubKey, - opts.Hash.New()) + hashed := makeVerificationSignatureHash(usernameHash, + receptionPubKey.N.Bytes(), opts.Hash.New()) // Verify signature return rsa.Verify(pubKey, opts.Hash, hashed, signature, opts) diff --git a/partnerships/crust/verification_test.go b/partnerships/crust/verification_test.go index 04ce7147f74d859094bc8c4d5c3ff1cef9e8f248..a218741bd1de63c90c655aa12598d9a4ea629205 100644 --- a/partnerships/crust/verification_test.go +++ b/partnerships/crust/verification_test.go @@ -1,5 +1,5 @@ //////////////////////////////////////////////////////////////////////////////////////////// -// Copyright © 2020 xx network SEZC // +// Copyright © 2022 xx foundation // // // // Use of this source code is governed by a license that can be found in the LICENSE file // //////////////////////////////////////////////////////////////////////////////////////////// @@ -8,6 +8,7 @@ package crust import ( "encoding/base64" + "fmt" "gitlab.com/xx_network/crypto/signature/rsa" "reflect" "testing" @@ -22,15 +23,15 @@ var ( } ReceptionKeys = []string{ - "TE1OT1BRUlNUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpams=", - "bG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJios=", - "jI2Oj5CRkpOUlZaXmJmam5ydnp+goaKjpKWmp6ipqqs=", + "-----BEGIN RSA PRIVATE KEY-----\nMIICXQIBAAKBgQCheF8LRTgCWMO3w3k1gXs1AU/x65Bgs1DV67PdM8Ik8NTV0eTw\nIEGXNbYxm/1tyMzbuOPkhF7h5bsj3V7TWwWa95zPbpgdt1Qpz2uvtLxAf9YWPCIz\nByp+dzQJOLRrFK21eKtDjkgfJbc+31701F/V/EzWKxRA2rDtCWKSCrMIRwIDAQAB\nAoGBAIdLdc/auth0ieGzHx+vE45RQCxDpiDwfv4P1hC1qqoLRTq3+W0eifbqIXQl\n8U6I3uYIYKN8Koh7VrfxZ+AOt31Rnr5EUfYqE84C8EZwT6jtU9gIMg2f54bnNKkk\n4lEdIP2q/rpwSuRa6k7XD6SjNyTLUJc30OQVtUxNmHaA0tYRAkEA00xZSiyAa9+k\n51bkWLSLrkkNBC4Ho1XpbPuJzKvygZ15TZ4Sgv0KclTxs5T26rxmpki639tH01CK\naTgLpg1f+QJBAMOhZcm3jNjpdCS8cwEJzZZfovWMi5DI2ou1Ie3oSPz48LvUjBdg\nHMfdiSiuk5WQ/gfTFFKG+yumLJScPPF6Oj8CQEIzWIJRwQaLMko8whw8rMq1Hnvh\nxAjboN/BS2IxuS/824WC8f/SMdSyYmvGTzoqPur4PHxoYm+Fe2gN5DBpXlkCQCRX\nAN99ty47/5UrZHmW5pe+YDkYyHw2s1IsbYcSFSzY2W8qxnM5KV9/KZFjDItGCcpO\nTYIfDN1I2xMoCrIYsGUCQQCpx9ojdsUvxywFsm/AAEZBwTSiE15Y1HVI8fnQwuK7\nGbBiAK/KoW+RTb1Ik7QJ5k8lzCgLI1JAXzxLpdp8/GZO\n-----END RSA PRIVATE KEY-----", + "-----BEGIN RSA PRIVATE KEY-----\nMIICXAIBAAKBgQCnfGhO0O/3sH/S0x73YorXGt4LdWXw9BP0AAdNYnrDf8DZgczy\nwVlkWj4MvDYik2ITtC2RuFMSuixvudwkMUwfH1pUJq1ZrKFg6chtwOTZmhCTbsRZ\nXyWvJ81ugi8+cb5S1W/cSwWe5s9hXYhILkeCM+SngBJ3evdZqgAlJxKqzwIDAQAB\nAoGATg2OVtzMWHQqvceh8Mw9xA1DWbe2cFpvShERViEE8UMCTttM9fzhegEMVccI\nu4hP9rrLWdO680lMGC1XyI4o2L7hddCflnNuzdwVnqSpDL0ZYAggEWJu//1vdv9p\n1i59gmc4uBHLuL8nJBPEeCcGTitxoAD4Qrkuku3evYuJ74ECQQDDT8EJpn67eOhf\nYdZn9xbtcXoGVYPLSLWAm3kt2NCNHsDUFxL/+XeQddcOdBAHgloPgqlUp5GcPGOQ\n5dCEvzPhAkEA24c9wFyK9BCBKqIuL4qf1n8avIk9yz9gCvG/1Cvej1CfQmGGs/lO\nfX6CyoXlNVnO5MymFm1UzQAG+blKNGS0rwJAarhPgFhrc0CzqDqrjw9ihce1p3Re\nmVtXYbiSVEzeV93v+3PIO/oyLMtXAVzFzXSahVMd91XAqKAOv4PzljVrwQJATiJ+\nqh7GHkRZlPEQez9d0JyAyaYXZmXyKzMMUdojZuMNLDVGGnyboTMMHkU15Z1HdEwa\nuVTEoApocS2v6aIGZQJBAKzHcE9HUrh7AqxrIR/vD8ekl6iP56K6IWRzSOWjQHlQ\nb+xuX1qrDkWgcJv2JpXaOirrKk+8T7v7pxFp6ERKC64=\n-----END RSA PRIVATE KEY-----", + "-----BEGIN RSA PRIVATE KEY-----\nMIICWwIBAAKBgQC8lFHNs6pvBDDo9DK3NL3JuRohLwRblPWXmiTj+/o1RvwitYua\nVfNmnp5gI4Tm1b85pQMMJv6brN6uwY3wK94P2sz7WDIPWntNofJIBMsoBohCKZ9d\n9teqk1w9nwTmgE40gFK3koc3g6Bo6SZEDmqhwIKL+JmxQPSy6BOrRTkQfwIDAQAB\nAoGAT31RshyepeclWry8t/8SVPqiagRwmM4Ea9/81uD7CgQe+d5+txKt477O0YWH\nWuoUjg7hZvj079gBkbZixy8mjdwIB3JQgg+iwLpXF5jckznLMUhENWgUvF+Fkv/+\nIwZSxHifeEByfKkXxAwNEn/bG/WR2i+CxN/xwJEJAKwxU/kCQQD0jeKWfjtngGxF\nuLW5/TLWt3QvHIABzs2QIb1EegB7M3iA7g1pX8YpchQlLyyumwwo7auGJ6TzC7Hi\n1PpsplzNAkEAxWfGNmubYdoLSHzn5EExE2Y0ufizFeJ8DyfVNx95xKnysApsksDr\n2zEXZF21Z4/K0LbS7FWYSzeJbEduqNRiewJAGYzFUpHHpQ2ewj4FBnR0nkg2ZEGn\nAglYIqnTu1a/vB9phJbaYdr2uhfIEQZ3tZpPT+tc0zxLGHVtVVSJAVb0NQJAP/4V\nDj0x4LWrZLNBBQhxHUXLn+HURCroZo1WHAlzEuK4zoKCkcxCaQrv91Q9YzYE3EX3\n+C8DMJbvUI+Tet1mkwJAamSH6SvLm2CrchvUVtO48YwKgzhX9zRISsuotvidMcsA\n7SDQ026qBrTnqBWosng2PZ12kG3nbsrfzFfI5irzlA==\n-----END RSA PRIVATE KEY-----", } ExpectedVerificationSignatures = []string{ - "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", } ) @@ -49,13 +50,14 @@ func TestSignVerifyVerification(t *testing.T) { } // Process reception keys - receptionKeys := make([][]byte, numTests) + receptionKeys := make([]*rsa.PublicKey, numTests) for i := 0; i < numTests; i++ { - receptionKeys[i], err = base64.StdEncoding.DecodeString(ReceptionKeys[i]) - if err != nil { + priv, err := rsa.LoadPrivateKeyFromPem([]byte(ReceptionKeys[i])) + if err!=nil{ t.Fatalf("Failed to decode reception key %d/%d: %v", i, numTests, err) } + receptionKeys[i] = priv.GetPublic() } // Sign and verify @@ -68,7 +70,8 @@ func TestSignVerifyVerification(t *testing.T) { } // Use signature provided above and verify - err = VerifyVerificationSignature(privKey.GetPublic(), Usernames[i], receptionKeys[i], sig) + err = VerifyVerificationSignature(privKey.GetPublic(), + hashUsername(Usernames[i]), receptionKeys[i], sig) if err != nil { t.Fatalf("Failed to verify signature for test %d/%v: %v", i, numTests, err) } @@ -76,6 +79,7 @@ func TestSignVerifyVerification(t *testing.T) { } + // Unit test: Generate signatures using pre-canned data // and compare it against the expected pre-canned data. func TestSignVerification_Consistency(t *testing.T) { @@ -87,13 +91,14 @@ func TestSignVerification_Consistency(t *testing.T) { } // Process reception keys - receptionKeys := make([][]byte, numTests) + receptionKeys := make([]*rsa.PublicKey, numTests) for i := 0; i < numTests; i++ { - receptionKeys[i], err = base64.StdEncoding.DecodeString(ReceptionKeys[i]) - if err != nil { + priv, err := rsa.LoadPrivateKeyFromPem([]byte(ReceptionKeys[i])) + if err!=nil{ t.Fatalf("Failed to decode reception key %d/%d: %v", i, numTests, err) } + receptionKeys[i] = priv.GetPublic() } // Generate signatures @@ -107,12 +112,13 @@ func TestSignVerification_Consistency(t *testing.T) { t.Fatalf("Failed to generate sig %d/%d: %v", i, numTests, err) } signatures[i] = base64.StdEncoding.EncodeToString(sig) + fmt.Println(signatures[i]) } // Check generated output is consisted with precanned output if !reflect.DeepEqual(ExpectedVerificationSignatures, signatures) { - t.Fatalf("Generated data does not match pre-canned data."+ + t.Errorf("Generated data does not match pre-canned data."+ "\nExpected: %v"+ "\nReceived: %v", ExpectedVerificationSignatures, signatures) }