Skip to content

Commit 3b1fb96

Browse files
committed
Clarify that R=infinity is invalid in BIP340
Also rename is_infinity to is_infinite is reference implementation, to match the wording in BIP340.
1 parent d853148 commit 3b1fb96

File tree

3 files changed

+9
-4
lines changed

3 files changed

+9
-4
lines changed

bip-0340.mediawiki

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ The following conventions are used, with constants as defined for [https://www.s
110110
** The function ''bytes(x)'', where ''x'' is an integer, returns the 32-byte encoding of ''x'', most significant byte first.
111111
** The function ''bytes(P)'', where ''P'' is a point, returns ''bytes(x(P))''.
112112
** The function ''int(x)'', where ''x'' is a 32-byte array, returns the 256-bit unsigned integer whose most significant byte first encoding is ''x''.
113-
** The function ''has_even_y(P)'', where ''P'' is a point, returns ''y(P) mod 2 = 0''.
113+
** The function ''has_even_y(P)'', where ''P'' is a point for which ''not is_infinite(P)'', returns ''y(P) mod 2 = 0''.
114114
** The function ''lift_x(x)'', where ''x'' is an integer in range ''0..p-1'', returns the point ''P'' for which ''x(P) = x''<ref>
115115
Given a candidate X coordinate ''x'' in the range ''0..p-1'', there exist either exactly two or exactly zero valid Y coordinates. If no valid Y coordinate exists, then ''x'' is not a valid X coordinate either, i.e., no point ''P'' exists for which ''x(P) = x''. The valid Y coordinates for a given candidate ''x'' are the square roots of ''c = x<sup>3</sup> + 7 mod p'' and they can be computed as ''y = &plusmn;c<sup>(p+1)/4</sup> mod p'' (see [https://en.wikipedia.org/wiki/Quadratic_residue#Prime_or_prime_power_modulus Quadratic residue]) if they exist, which can be checked by squaring and comparing with ''c''.</ref> and ''has_even_y(P)'', or fails if no such point exists. The function ''lift_x(x)'' is equivalent to the following pseudocode:
116116
*** Let ''c = x<sup>3</sup> + 7 mod p''.
@@ -184,7 +184,9 @@ The algorithm ''Verify(pk, m, sig)'' is defined as:
184184
* Let ''s = int(sig[32:64])''; fail if ''s &ge; n''.
185185
* Let ''e = int(hash<sub>BIP0340/challenge</sub>(bytes(r) || bytes(P) || m)) mod n''.
186186
* Let ''R = s⋅G - e⋅P''.
187-
* Fail if ''not has_even_y(R)'' or ''x(R) &ne; r''.
187+
* Fail if ''is_infinite(R)''.
188+
* Fail if ''not has_even_y(R)''.
189+
* Fail if ''x(R) &ne; r''.
188190
* Return success iff no failure occurred before reaching this point.
189191
190192
For every valid secret key ''sk'' and message ''m'', ''Verify(PubKey(sk),m,Sign(sk,m))'' will succeed.

bip-0340/reference.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,15 @@ def tagged_hash(tag: str, msg: bytes) -> bytes:
2626
tag_hash = hashlib.sha256(tag.encode()).digest()
2727
return hashlib.sha256(tag_hash + tag_hash + msg).digest()
2828

29-
def is_infinity(P: Optional[Point]) -> bool:
29+
def is_infinite(P: Optional[Point]) -> bool:
3030
return P is None
3131

3232
def x(P: Point) -> int:
33+
assert not is_infinite(P)
3334
return P[0]
3435

3536
def y(P: Point) -> int:
37+
assert not is_infinite(P)
3638
return P[1]
3739

3840
def point_add(P1: Optional[Point], P2: Optional[Point]) -> Optional[Point]:
@@ -83,6 +85,7 @@ def hash_sha256(b: bytes) -> bytes:
8385
return hashlib.sha256(b).digest()
8486

8587
def has_even_y(P: Point) -> bool:
88+
assert not is_infinite(P)
8689
return y(P) % 2 == 0
8790

8891
def pubkey_gen(seckey: bytes) -> bytes:

bip-0340/test-vectors.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ def is_square(x):
66

77
def has_square_y(P):
88
"""Determine if P has a square Y coordinate. Used in an earlier draft of BIP340."""
9-
assert not is_infinity(P)
9+
assert not is_infinite(P)
1010
return is_square(P[1])
1111

1212
def vector0():

0 commit comments

Comments
 (0)