mirror of
https://github.com/bitcoin/bips.git
synced 2025-05-12 12:03:29 +00:00
commit
ad1d3bc2a7
@ -619,7 +619,7 @@ Algorithm ''DeterministicSign(sk, aggothernonce, pk<sub>1..u</sub>, tweak<sub>1.
|
|||||||
* Let ''keyagg_ctx<sub>0</sub> = KeyAgg(pk<sub>1..u</sub>)''; fail if that fails
|
* Let ''keyagg_ctx<sub>0</sub> = KeyAgg(pk<sub>1..u</sub>)''; fail if that fails
|
||||||
* For ''i = 1 .. v'':
|
* For ''i = 1 .. v'':
|
||||||
** Let ''keyagg_ctx<sub>i</sub> = ApplyTweak(keyagg_ctx<sub>i-1</sub>, tweak<sub>i</sub>, is_xonly_t<sub>i</sub>)''; fail if that fails
|
** Let ''keyagg_ctx<sub>i</sub> = ApplyTweak(keyagg_ctx<sub>i-1</sub>, tweak<sub>i</sub>, is_xonly_t<sub>i</sub>)''; fail if that fails
|
||||||
* Let ''aggpk = GetPubkey(keyagg_ctx<sub>v</sub>)''
|
* Let ''aggpk = GetXonlyPubkey(keyagg_ctx<sub>v</sub>)''
|
||||||
* Let ''k<sub>i</sub> = int(hash<sub>MuSig/deterministic/nonce</sub>(sk' || aggothernonce || aggpk || bytes(8, len(m)) || m || bytes(1, i - 1))) mod n'' for ''i = 1,2''
|
* Let ''k<sub>i</sub> = int(hash<sub>MuSig/deterministic/nonce</sub>(sk' || aggothernonce || aggpk || bytes(8, len(m)) || m || bytes(1, i - 1))) mod n'' for ''i = 1,2''
|
||||||
* Fail if ''k<sub>1</sub> = 0'' or ''k<sub>2</sub> = 0''
|
* Fail if ''k<sub>1</sub> = 0'' or ''k<sub>2</sub> = 0''
|
||||||
* Let ''R<sub>⁎,1</sub> = k<sub>1</sub>⋅G, R<sub>⁎,2</sub> = k<sub>2</sub>⋅G''
|
* Let ''R<sub>⁎,1</sub> = k<sub>1</sub>⋅G, R<sub>⁎,2</sub> = k<sub>2</sub>⋅G''
|
||||||
@ -782,6 +782,8 @@ An exception to this rule is <code>MAJOR</code> version zero (0.y.z) which is fo
|
|||||||
The <code>MINOR</code> version is incremented whenever the inputs or the output of an algorithm changes in a backward-compatible way or new backward-compatible functionality is added.
|
The <code>MINOR</code> version is incremented whenever the inputs or the output of an algorithm changes in a backward-compatible way or new backward-compatible functionality is added.
|
||||||
The <code>PATCH</code> version is incremented for other changes that are noteworthy (bug fixes, test vectors, important clarifications, etc.).
|
The <code>PATCH</code> version is incremented for other changes that are noteworthy (bug fixes, test vectors, important clarifications, etc.).
|
||||||
|
|
||||||
|
* '''1.0.2''' (2024-07-22):
|
||||||
|
** Fix minor bug in the specification of ''DeterministicSign'' and add small improvement to a ''PartialSigAgg'' test vector.
|
||||||
* '''1.0.1''' (2024-05-14):
|
* '''1.0.1''' (2024-05-14):
|
||||||
** Fix minor issue in ''PartialSigVerify'' vectors.
|
** Fix minor issue in ''PartialSigVerify'' vectors.
|
||||||
* '''1.0.0''' (2023-03-26):
|
* '''1.0.0''' (2023-03-26):
|
||||||
@ -825,4 +827,4 @@ The <code>PATCH</code> version is incremented for other changes that are notewor
|
|||||||
|
|
||||||
== Acknowledgements ==
|
== Acknowledgements ==
|
||||||
|
|
||||||
We thank Brandon Black, Riccardo Casatta, Lloyd Fournier, Russell O'Connor, and Pieter Wuille for their contributions to this document.
|
We thank Brandon Black, Riccardo Casatta, Sivaram Dhakshinamoorthy, Lloyd Fournier, Russell O'Connor, and Pieter Wuille for their contributions to this document.
|
||||||
|
@ -153,7 +153,8 @@ def sig_agg_vectors():
|
|||||||
"psig_indices": [7, 8],
|
"psig_indices": [7, 8],
|
||||||
"error": {
|
"error": {
|
||||||
"type": "invalid_contribution",
|
"type": "invalid_contribution",
|
||||||
"signer": 1
|
"signer": 1,
|
||||||
|
"contrib": "psig",
|
||||||
},
|
},
|
||||||
"comment": "Partial signature is invalid because it exceeds group size"
|
"comment": "Partial signature is invalid because it exceeds group size"
|
||||||
}
|
}
|
||||||
|
@ -317,7 +317,7 @@ SessionContext = NamedTuple('SessionContext', [('aggnonce', bytes),
|
|||||||
('is_xonly', List[bool]),
|
('is_xonly', List[bool]),
|
||||||
('msg', bytes)])
|
('msg', bytes)])
|
||||||
|
|
||||||
def key_agg_and_tweak(pubkeys: List[PlainPk], tweaks: List[bytes], is_xonly: List[bool]):
|
def key_agg_and_tweak(pubkeys: List[PlainPk], tweaks: List[bytes], is_xonly: List[bool]) -> KeyAggContext:
|
||||||
if len(tweaks) != len(is_xonly):
|
if len(tweaks) != len(is_xonly):
|
||||||
raise ValueError('The `tweaks` and `is_xonly` arrays must have the same length.')
|
raise ValueError('The `tweaks` and `is_xonly` arrays must have the same length.')
|
||||||
keyagg_ctx = key_agg(pubkeys)
|
keyagg_ctx = key_agg(pubkeys)
|
||||||
@ -440,8 +440,6 @@ def partial_sig_verify_internal(psig: bytes, pubnonce: bytes, pk: bytes, session
|
|||||||
Re_s_ = point_add(R_s1, point_mul(R_s2, b))
|
Re_s_ = point_add(R_s1, point_mul(R_s2, b))
|
||||||
Re_s = Re_s_ if has_even_y(R) else point_negate(Re_s_)
|
Re_s = Re_s_ if has_even_y(R) else point_negate(Re_s_)
|
||||||
P = cpoint(pk)
|
P = cpoint(pk)
|
||||||
if P is None:
|
|
||||||
return False
|
|
||||||
a = get_session_key_agg_coeff(session_ctx, P)
|
a = get_session_key_agg_coeff(session_ctx, P)
|
||||||
g = 1 if has_even_y(Q) else n - 1
|
g = 1 if has_even_y(Q) else n - 1
|
||||||
g_ = g * gacc % n
|
g_ = g * gacc % n
|
||||||
@ -523,7 +521,7 @@ def test_key_agg_vectors() -> None:
|
|||||||
|
|
||||||
assert get_xonly_pk(key_agg(pubkeys)) == expected
|
assert get_xonly_pk(key_agg(pubkeys)) == expected
|
||||||
|
|
||||||
for i, test_case in enumerate(error_test_cases):
|
for test_case in error_test_cases:
|
||||||
exception, except_fn = get_error_details(test_case)
|
exception, except_fn = get_error_details(test_case)
|
||||||
|
|
||||||
pubkeys = [X[i] for i in test_case["key_indices"]]
|
pubkeys = [X[i] for i in test_case["key_indices"]]
|
||||||
@ -572,7 +570,7 @@ def test_nonce_agg_vectors() -> None:
|
|||||||
expected = bytes.fromhex(test_case["expected"])
|
expected = bytes.fromhex(test_case["expected"])
|
||||||
assert nonce_agg(pubnonces) == expected
|
assert nonce_agg(pubnonces) == expected
|
||||||
|
|
||||||
for i, test_case in enumerate(error_test_cases):
|
for test_case in error_test_cases:
|
||||||
exception, except_fn = get_error_details(test_case)
|
exception, except_fn = get_error_details(test_case)
|
||||||
pubnonces = [pnonce[i] for i in test_case["pnonce_indices"]]
|
pubnonces = [pnonce[i] for i in test_case["pnonce_indices"]]
|
||||||
assert_raises(exception, lambda: nonce_agg(pubnonces), except_fn)
|
assert_raises(exception, lambda: nonce_agg(pubnonces), except_fn)
|
||||||
@ -598,7 +596,10 @@ def test_sign_verify_vectors() -> None:
|
|||||||
|
|
||||||
aggnonces = fromhex_all(test_data["aggnonces"])
|
aggnonces = fromhex_all(test_data["aggnonces"])
|
||||||
# The aggregate of the first three elements of pnonce is at index 0
|
# The aggregate of the first three elements of pnonce is at index 0
|
||||||
assert(aggnonces[0] == nonce_agg([pnonce[0], pnonce[1], pnonce[2]]))
|
assert (aggnonces[0] == nonce_agg([pnonce[0], pnonce[1], pnonce[2]]))
|
||||||
|
# The aggregate of the first and fourth elements of pnonce is at index 1,
|
||||||
|
# which is the infinity point encoded as a zeroed 33-byte array
|
||||||
|
assert (aggnonces[1] == nonce_agg([pnonce[0], pnonce[3]]))
|
||||||
|
|
||||||
msgs = fromhex_all(test_data["msgs"])
|
msgs = fromhex_all(test_data["msgs"])
|
||||||
|
|
||||||
@ -626,7 +627,7 @@ def test_sign_verify_vectors() -> None:
|
|||||||
assert sign(secnonce_tmp, sk, session_ctx) == expected
|
assert sign(secnonce_tmp, sk, session_ctx) == expected
|
||||||
assert partial_sig_verify(expected, pubnonces, pubkeys, [], [], msg, signer_index)
|
assert partial_sig_verify(expected, pubnonces, pubkeys, [], [], msg, signer_index)
|
||||||
|
|
||||||
for i, test_case in enumerate(sign_error_test_cases):
|
for test_case in sign_error_test_cases:
|
||||||
exception, except_fn = get_error_details(test_case)
|
exception, except_fn = get_error_details(test_case)
|
||||||
|
|
||||||
pubkeys = [X[i] for i in test_case["key_indices"]]
|
pubkeys = [X[i] for i in test_case["key_indices"]]
|
||||||
@ -646,7 +647,7 @@ def test_sign_verify_vectors() -> None:
|
|||||||
|
|
||||||
assert not partial_sig_verify(sig, pubnonces, pubkeys, [], [], msg, signer_index)
|
assert not partial_sig_verify(sig, pubnonces, pubkeys, [], [], msg, signer_index)
|
||||||
|
|
||||||
for i, test_case in enumerate(verify_error_test_cases):
|
for test_case in verify_error_test_cases:
|
||||||
exception, except_fn = get_error_details(test_case)
|
exception, except_fn = get_error_details(test_case)
|
||||||
|
|
||||||
sig = bytes.fromhex(test_case["sig"])
|
sig = bytes.fromhex(test_case["sig"])
|
||||||
@ -702,7 +703,7 @@ def test_tweak_vectors() -> None:
|
|||||||
assert sign(secnonce_tmp, sk, session_ctx) == expected
|
assert sign(secnonce_tmp, sk, session_ctx) == expected
|
||||||
assert partial_sig_verify(expected, pubnonces, pubkeys, tweaks, is_xonly, msg, signer_index)
|
assert partial_sig_verify(expected, pubnonces, pubkeys, tweaks, is_xonly, msg, signer_index)
|
||||||
|
|
||||||
for i, test_case in enumerate(error_test_cases):
|
for test_case in error_test_cases:
|
||||||
exception, except_fn = get_error_details(test_case)
|
exception, except_fn = get_error_details(test_case)
|
||||||
|
|
||||||
pubkeys = [X[i] for i in test_case["key_indices"]]
|
pubkeys = [X[i] for i in test_case["key_indices"]]
|
||||||
@ -747,7 +748,7 @@ def test_det_sign_vectors() -> None:
|
|||||||
session_ctx = SessionContext(aggnonce, pubkeys, tweaks, is_xonly, msg)
|
session_ctx = SessionContext(aggnonce, pubkeys, tweaks, is_xonly, msg)
|
||||||
assert partial_sig_verify_internal(psig, pubnonce, pubkeys[signer_index], session_ctx)
|
assert partial_sig_verify_internal(psig, pubnonce, pubkeys[signer_index], session_ctx)
|
||||||
|
|
||||||
for i, test_case in enumerate(error_test_cases):
|
for test_case in error_test_cases:
|
||||||
exception, except_fn = get_error_details(test_case)
|
exception, except_fn = get_error_details(test_case)
|
||||||
|
|
||||||
pubkeys = [X[i] for i in test_case["key_indices"]]
|
pubkeys = [X[i] for i in test_case["key_indices"]]
|
||||||
@ -796,7 +797,7 @@ def test_sig_agg_vectors() -> None:
|
|||||||
aggpk = get_xonly_pk(key_agg_and_tweak(pubkeys, tweaks, is_xonly))
|
aggpk = get_xonly_pk(key_agg_and_tweak(pubkeys, tweaks, is_xonly))
|
||||||
assert schnorr_verify(msg, aggpk, sig)
|
assert schnorr_verify(msg, aggpk, sig)
|
||||||
|
|
||||||
for i, test_case in enumerate(error_test_cases):
|
for test_case in error_test_cases:
|
||||||
exception, except_fn = get_error_details(test_case)
|
exception, except_fn = get_error_details(test_case)
|
||||||
|
|
||||||
pubnonces = [pnonce[i] for i in test_case["nonce_indices"]]
|
pubnonces = [pnonce[i] for i in test_case["nonce_indices"]]
|
||||||
|
@ -143,7 +143,8 @@
|
|||||||
],
|
],
|
||||||
"error": {
|
"error": {
|
||||||
"type": "invalid_contribution",
|
"type": "invalid_contribution",
|
||||||
"signer": 1
|
"signer": 1,
|
||||||
|
"contrib": "psig"
|
||||||
},
|
},
|
||||||
"comment": "Partial signature is invalid because it exceeds group size"
|
"comment": "Partial signature is invalid because it exceeds group size"
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user