user138591: The steps to convert a private key to a SegWit (version 0, bech32) address are roughly as follows:
1.  public_key = Generator * private_key  (use the compressed version)
2.  public_key_hash = RIPEMD160(SHA256(public_key)))
3.  bech32_encode

For taproot address (version 2 witness), is the tweak mandatory or optional? Are the following calculations correct? (No tweak):
Suppose the private key is 1
1. The corresponding 32-byte compressed key (x-only, without oddness indicator): 79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798

2. Directly encode the above 32 bytes using the new modified bech32m encoding, and witness version 1:
    bech32m_encode(hrp='bc', witness_version=1, bytes.fromhex('79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'))

result: bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqzk5jj0

Also, what the point of adding a tweak step? It doesn’t seem to improve any security by adding a number to privkey. Thanks.

user208: The steps for computing a BIP350 (bech32m) address for a P2TR (pay to taproot) output spendable with a given private key depend on what you want that output to do.
The most straightforward way (but not recommended, see further) is the following:

Compute the public key P = privkey * G.
Let Pb be the serialization of P in x-only form: that's just the 32-byte big endian encoding of its X coordinate. Equivalently, it's the compressed public key encoding with the first byte removed.
The address is bech32m_encode(payload=Pb, version=1). See BIP350 for details.

Spending such outputs is then done by providing a BIP340 signature on that public key, using the message hash mechanism described in BIP341.
However, P2TR outputs are effectively a combination of a pay-to-key and a pay-to-script: each output can be spent for either by signing the output directly, or by revealing how the output commits to a script, and then satisfying that script. Even if you don't want any scripts in there, BIP341 still recommends using a "dummy" script. For simple single-key setups this is unlikely to matter, but it may matter for more advanced cases (see footnote 23 in BIP341), and thus the suggested standard is to always do this. In this case, the procedure would be:

Compute the public key P = privkey * G.
Let Pb be the serialization of P in x-only form.
Compute the tweak t = SHA256(SHA256("TapTweak") || SHA256("TapTweak") || Pb), interpreted as 32-byte big endian encoded integer.
Compute the tweaked public key Q = P + (t * G).
Let Qb be the serialization of Q in x-only form.
The address is bech32m_encode(payload=Qb, version=1).

Signing now requires a BIP340 signature with (privkey + t) as private key.

138591: <p>The steps to convert a private key to a SegWit (version 0, bech32) address are roughly as follows:</p>
<pre><code>1.  public_key = Generator * private_key  (use the compressed version)
2.  public_key_hash = RIPEMD160(SHA256(public_key)))
3.  bech32_encode
</code></pre>
<p>For taproot address (version 2 witness), is the tweak mandatory or optional? Are the following calculations correct? (No tweak):</p>
<p>Suppose the private key is 1</p>
<pre><code>1. The corresponding 32-byte compressed key (x-only, without oddness indicator): 79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798

2. Directly encode the above 32 bytes using the new modified bech32m encoding, and witness version 1:
    bech32m_encode(hrp='bc', witness_version=1, bytes.fromhex('79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'))

result: bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqzk5jj0
</code></pre>
<p>Also, what the point of adding a tweak step? It doesn’t seem to improve any security by adding a number to privkey. Thanks.</p>
 208: <p>The steps for computing a BIP350 (bech32m) address for a P2TR (pay to taproot) output spendable with a given private key depend on what you want that output to do.</p>
<p>The most straightforward way (but not recommended, see further) is the following:</p>
<ul>
<li>Compute the public key <em>P = privkey * G</em>.</li>
<li>Let <em>Pb</em> be the serialization of <em>P</em> in x-only form: that's just the 32-byte big endian encoding of its X coordinate. Equivalently, it's the compressed public key encoding with the first byte removed.</li>
<li>The address is <em>bech32m_encode(payload=Pb, version=1)</em>. See <a href="https://github.com/bitcoin/bips/blob/master/bip-0350.mediawiki" rel="nofollow noreferrer">BIP350</a> for details.</li>
</ul>
<p>Spending such outputs is then done by providing a <a href="https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki" rel="nofollow noreferrer">BIP340</a> signature on that public key, using the message hash mechanism described in <a href="https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#taproot-key-path-spending-signature-validation" rel="nofollow noreferrer">BIP341</a>.</p>
<p>However, P2TR outputs are effectively a combination of a pay-to-key and a pay-to-script: each output can be spent for either by signing the output directly, or by revealing how the output commits to a script, and then satisfying that script. Even if you don't want any scripts in there, <a href="https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#constructing-and-spending-taproot-outputs" rel="nofollow noreferrer">BIP341</a> still recommends using a &quot;dummy&quot; script. For simple single-key setups this is unlikely to matter, but it may matter for more advanced cases (see footnote 23 in BIP341), and thus the suggested standard is to always do this. In this case, the procedure would be:</p>
<ul>
<li>Compute the public key <em>P = privkey * G</em>.</li>
<li>Let <em>Pb</em> be the serialization of <em>P</em> in x-only form.</li>
<li>Compute the tweak <em>t = SHA256(SHA256(&quot;TapTweak&quot;) || SHA256(&quot;TapTweak&quot;) || Pb)</em>, interpreted as 32-byte big endian encoded integer.</li>
<li>Compute the tweaked public key <em>Q = P + (t * G)</em>.</li>
<li>Let <em>Qb</em> be the serialization of <em>Q</em> in x-only form.</li>
<li>The address is <em>bech32m_encode(payload=Qb, version=1)</em>.</li>
</ul>
<p>Signing now requires a BIP340 signature with <em>(privkey + t)</em> as private key.</p>
