<p>Disclaimer: This is an educational exercise. This Python code is for testing and should not be used in production or with mainnet Bitcoin. A private key of <code>3</code> is absolutely insecure.</p>
<p>There are two Python files in the BIPs repo <code>reference.py</code> and <code>test_vectors.py</code> which you can view by cloning the BIPs repo.</p>
<pre><code>git clone https://github.com/bitcoin/bips.git
</code></pre>
<p>These two files are in <code>/bitcoin/bips/tree/master/bip-0340</code>.</p>
<p>If you run <code>python3 test-vectors.py</code> from within the bip-0340 directory you will get the output and error messages that are in the CSV file <code>test-vectors.csv</code>.</p>
<p>If you open <code>test-vectors.py</code> with your text editor e.g. <code>vim test-vectors.py</code></p>
<p>you can edit any of the test vectors' secret key (private key), message, auxiliary randomness.</p>
<p>For example <code>vector0</code> has the secret key <code>3</code>.</p>
<pre><code>seckey = bytes_from_int(3)
</code></pre>
<p>You could change the secret from <code>3</code> to <code>4</code>.</p>
<pre><code>seckey = bytes_from_int(4)
</code></pre>
<p>Save and close your text editor and then run <code>python3 test-vectors.py</code> again.</p>
<p>This will generate an AssertionError.</p>
<pre><code>Traceback (most recent call last):
  File &quot;test-vectors.py&quot;, line 253, in &lt;module&gt;
    vector0(),
  File &quot;test-vectors.py&quot;, line 31, in vector0
    assert(not has_square_y(pubkey_point))
AssertionError
</code></pre>
<p>There is an assert that checks that for a particular public key (X,Y) (calculated from the secret (private) key) the Y coordinate isn't square. This is a check implemented due to a previous <a href="https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-August/018081.html" rel="nofollow noreferrer">design decision</a> to use squaredness as the tiebreaker for two Y coordinates. The tiebreaker is now evenness rather than squaredness. This test is included to catch when an implementer is mistakenly using squaredness rather than evenness. In this case the public key has a square Y coordinate.</p>
<p>Every private key (scalar) maps to a single corresponding public key (point). In BIP 340 we restrict ourselves to public keys with an even Y coordinate. This could lead to only half of the public keys being valid and hence only half of the private keys being valid too. Instead we say that every private key has a public key and if <code>d.G</code> has an odd Y coordinate we effectively sign with -d (the negated private key) instead.</p>
<p>Negated means taking the complement with the group order n</p>
<p><code>-m = n-m (mod n)</code></p>
<p>With that change you could say that every scalar is a valid private key but there are two private keys that map to the same public key. Only one private key maps to a public key with an even Y coordinate though. (Only one BIP 340 private key maps to a BIP 340 public key.)</p>
<p>Remember when you are finished experimenting you can use this to reset:</p>
<p><code>git reset --hard HEAD</code></p>
<p>This will discard the changes you have made and go back to the state of the code before you started experimenting.</p>
<p>Thanks to Pieter Wuille on IRC for some additions.</p>

CC BY-SA 4.0
2020-10-10T12:23:48.693Z
2020-10-14T10:10:56.633Z
2020-10-14T10:10:56.633Z
Michael Folkson
<p>I now <a href="https://bitcoin.stackexchange.com/questions/99362/im-digging-further-into-the-open-taproot-pr-can-you-explain-the-bip340-test-ve">understand</a> why some of the <code>bip340_test_vectors</code> fail signature verification.</p>
<p>I would like to tweak these test vectors to check that signature verification fails for other test vectors. How do I do this?</p>

<bitcoin-core-development><taproot><schnorr-signatures><functional-test>
How do I tweak the bip340_test_vectors to check that signature verification fails for other test vectors?
Michael Folkson
# How do I tweak the bip340_test_vectors to check that signature verification fails for other test vectors?

(Asked by: username_0 on 2020-10-10)

I now [understand](https://bitcoin.stackexchange.com/questions/99362/im-digging-further-into-the-open-taproot-pr-can-you-explain-the-bip340-test-ve) why some of the `bip340_test_vectors` fail signature verification.

I would like to tweak these test vectors to check that signature verification fails for other test vectors. How do I do this?

**Tags:** bitcoin-core-development, taproot, schnorr-signatures, functional-test


---

## 1 answers

### Answer by username_0 on 2020-10-10. Score: 1 | Accepted answer

Disclaimer: This is an educational exercise. This Python code is for testing and should not be used in production or with mainnet Bitcoin. A private key of `3` is absolutely insecure.

There are two Python files in the BIPs repo `reference.py` and `test_vectors.py` which you can view by cloning the BIPs repo.

```
git clone https://github.com/bitcoin/bips.git

```

These two files are in `/bitcoin/bips/tree/master/bip-0340`.

If you run `python3 test-vectors.py` from within the bip-0340 directory you will get the output and error messages that are in the CSV file `test-vectors.csv`.

If you open `test-vectors.py` with your text editor e.g. `vim test-vectors.py`

you can edit any of the test vectors' secret key (private key), message, auxiliary randomness.

For example `vector0` has the secret key `3`.

```
seckey = bytes_from_int(3)

```

You could change the secret from `3` to `4`.

```
seckey = bytes_from_int(4)

```

Save and close your text editor and then run `python3 test-vectors.py` again.

This will generate an AssertionError.

```
Traceback (most recent call last):
  File "test-vectors.py", line 253, in <module>
    vector0(),
  File "test-vectors.py", line 31, in vector0
    assert(not has_square_y(pubkey_point))
AssertionError

```

There is an assert that checks that for a particular public key (X,Y) (calculated from the secret (private) key) the Y coordinate isn't square. This is a check implemented due to a previous [design decision](https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-August/018081.html) to use squaredness as the tiebreaker for two Y coordinates. The tiebreaker is now evenness rather than squaredness. This test is included to catch when an implementer is mistakenly using squaredness rather than evenness. In this case the public key has a square Y coordinate.

Every private key (scalar) maps to a single corresponding public key (point). In BIP 340 we restrict ourselves to public keys with an even Y coordinate. This could lead to only half of the public keys being valid and hence only half of the private keys being valid too. Instead we say that every private key has a public key and if `d.G` has an odd Y coordinate we effectively sign with -d (the negated private key) instead.

Negated means taking the complement with the group order n

`-m = n-m (mod n)`

With that change you could say that every scalar is a valid private key but there are two private keys that map to the same public key. Only one private key maps to a public key with an even Y coordinate though. (Only one BIP 340 private key maps to a BIP 340 public key.)

Remember when you are finished experimenting you can use this to reset:

`git reset --hard HEAD`

This will discard the changes you have made and go back to the state of the code before you started experimenting.

Thanks to Pieter Wuille on IRC for some additions.


---

