// Use our actual hashing algorithm here. func TestSignaturesAndRecovery(t *testing.T) { curve := secp256k1.S256() r := rand.New(rand.NewSource(54321)) numSigs := 128 sigList := randSigList(curve, numSigs) for _, tv := range sigList { pubkey := tv.pubkey sig := tv.sig // Make sure we can verify the original signature. _, err := schnorrVerify(curve, sig.Serialize(), pubkey, tv.msg, chainhash.HashFuncB) assert.NoError(t, err) ok := Verify(curve, pubkey, tv.msg, sig.R, sig.S) assert.Equal(t, true, ok) // See if we can recover the public keys OK. var pkRecover *secp256k1.PublicKey pkRecover, _, err = schnorrRecover(curve, sig.Serialize(), tv.msg, chainhash.HashFuncB) assert.NoError(t, err) if err == nil { assert.Equal(t, pubkey.Serialize(), pkRecover.Serialize()) } // Screw up the signature at some random bits and make sure // that breaks it. numBadBits := r.Intn(2) sigBad := sig.Serialize() // (numBadBits*2)+1 --> always odd so at least one bit is different for i := 0; i < (numBadBits*2)+1; i++ { pos := r.Intn(63) bitPos := r.Intn(7) sigBad[pos] ^= 1 << uint8(bitPos) } _, err = schnorrVerify(curve, sigBad, pubkey, tv.msg, chainhash.HashFuncB) assert.Error(t, err) // Make sure it breaks pubkey recovery too. valid := false pkRecover, valid, err = schnorrRecover(curve, sigBad, tv.msg, testSchnorrHash) if valid { assert.NotEqual(t, pubkey.Serialize(), pkRecover.Serialize()) } else { assert.Error(t, err) } } }
func TestSchnorrSigning(t *testing.T) { tRand := rand.New(rand.NewSource(54321)) curve := secp256k1.S256() tvs := GetSigningTestVectors() for _, tv := range tvs { _, pubkey := secp256k1.PrivKeyFromBytes(curve, tv.priv) sig, err := schnorrSign(curve, tv.msg, tv.priv, tv.nonce, nil, nil, testSchnorrHash) assert.NoError(t, err) assert.Equal(t, sig.Serialize(), tv.sig) // Make sure they verify too while we're at it. _, err = schnorrVerify(curve, sig.Serialize(), pubkey, tv.msg, testSchnorrHash) assert.NoError(t, err) // See if we can recover the public keys OK. var pkRecover *secp256k1.PublicKey pkRecover, _, err = schnorrRecover(curve, sig.Serialize(), tv.msg, testSchnorrHash) assert.NoError(t, err) if err == nil { assert.Equal(t, pubkey.Serialize(), pkRecover.Serialize()) } // Screw up the signature at a random bit and make sure that breaks it. sigBad := sig.Serialize() pos := tRand.Intn(63) bitPos := tRand.Intn(7) sigBad[pos] ^= 1 << uint8(bitPos) _, err = schnorrVerify(curve, sigBad, pubkey, tv.msg, testSchnorrHash) assert.Error(t, err) // Make sure it breaks pubkey recovery too. valid := false pkRecover, valid, err = schnorrRecover(curve, sigBad, tv.msg, testSchnorrHash) if valid { assert.NotEqual(t, pubkey.Serialize(), pkRecover.Serialize()) } else { assert.Error(t, err) } } }