mimblewimble / grin

Minimal implementation of the Mimblewimble protocol.
https://grin.mw/
Apache License 2.0
5.04k stars 989 forks source link

why is tx signature 64 bytes, rather than 65 bytes? #3673

Closed jackzhp closed 2 years ago

jackzhp commented 2 years ago

tx signature is a Schnorr signature, it is a point element and a field element. for the field element, 32 bytes is OK. but for the point element, don't we need an extra byte to indicate its y as we usually do to encode a public key.

but in the code, it is just 64 bytes. why is that?

Thanks in advance.

tromp commented 2 years ago

According to https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki

Implicit Y coordinates

In order to support efficient verification and batch verification, the Y coordinate of P and of R cannot be ambiguous (every valid X coordinate has two possible Y coordinates). We have a choice between several options for symmetry breaking:

  1. Implicitly choosing the Y coordinate that is in the lower half.
  2. Implicitly choosing the Y coordinate that is even[6].
  3. Implicitly choosing the Y coordinate that is a quadratic residue (i.e. has a square root modulo p).

The second option offers the greatest compatibility with existing key generation systems, where the standard 33-byte compressed public key format consists of a byte indicating the oddness of the Y coordinate, plus the full X coordinate. To avoid gratuitous incompatibilities, we pick that option for P, and thus our X-only public keys become equivalent to a compressed public key that is the X-only key prefixed by the byte 0x02. For consistency, the same is done for R[7]. Despite halving the size of the set of valid public keys, implicit Y coordinates are not a reduction in security. Informally, if a fast algorithm existed to compute the discrete logarithm of an X-only public key, then it could also be used to compute the discrete logarithm of a full public key: apply it to the X coordinate, and then optionally negate the result. This shows that breaking an X-only public key can be at most a small constant term faster than breaking a full one.[8].

jackzhp commented 2 years ago

@tromp thanks. I really appreciate for providing me with this info.

jackzhp commented 2 years ago

according to the implementation, https://github.com/mimblewimble/secp256k1-zkp/blob/8d1f5bb152580446a3438cd705caebacc2a5d850/src/modules/aggsig/main_impl.h

It seems the option#3 is used, so assume leading byte 08, rather than 02.

Is there someone can tell me why this inconsistency?

tromp commented 2 years ago

It seems the option#3 is used, so assume leading byte 08, rather than 02.

Where is the use of leading byte 0x08 documented?

Could this be related to footnote [6]?

[6] An earlier version of this draft used the third option instead, based on a belief that this would in general trade signing efficiency for verification efficiency. When using Jacobian coordinates, a common optimization in ECC implementations, it is possible to determine if a Y coordinate is a quadratic residue by computing the Legendre symbol, without converting to affine coordinates first (which needs a modular inversion). As modular inverses and Legendre symbols have similar performance in practice, this trade-off is not worth it.

yeastplume commented 2 years ago

This seems sufficiently answered