|
264 | 264 | VCRevokeResponse,
|
265 | 265 | VCSpend,
|
266 | 266 | VCSpendResponse,
|
| 267 | + VerifySignature, |
| 268 | + VerifySignatureResponse, |
267 | 269 | WalletInfoResponse,
|
268 | 270 | )
|
269 | 271 | from chia.wallet.wallet_spend_bundle import WalletSpendBundle
|
@@ -1965,63 +1967,59 @@ async def send_notification(
|
1965 | 1967 |
|
1966 | 1968 | return {"tx": None, "transactions": None} # tx_endpoint wrapper will take care of this
|
1967 | 1969 |
|
1968 |
| - async def verify_signature(self, request: dict[str, Any]) -> EndpointResult: |
| 1970 | + @marshal |
| 1971 | + async def verify_signature(self, request: VerifySignature) -> VerifySignatureResponse: |
1969 | 1972 | """
|
1970 | 1973 | Given a public key, message and signature, verify if it is valid.
|
1971 | 1974 | :param request:
|
1972 | 1975 | :return:
|
1973 | 1976 | """
|
1974 |
| - input_message: str = request["message"] |
1975 |
| - signing_mode_str: Optional[str] = request.get("signing_mode") |
1976 | 1977 | # Default to BLS_MESSAGE_AUGMENTATION_HEX_INPUT as this RPC was originally designed to verify
|
1977 | 1978 | # signatures made by `chia keys sign`, which uses BLS_MESSAGE_AUGMENTATION_HEX_INPUT
|
1978 |
| - if signing_mode_str is None: |
| 1979 | + if request.signing_mode is None: |
1979 | 1980 | signing_mode = SigningMode.BLS_MESSAGE_AUGMENTATION_HEX_INPUT
|
1980 | 1981 | else:
|
1981 | 1982 | try:
|
1982 |
| - signing_mode = SigningMode(signing_mode_str) |
| 1983 | + signing_mode = SigningMode(request.signing_mode) |
1983 | 1984 | except ValueError:
|
1984 |
| - raise ValueError(f"Invalid signing mode: {signing_mode_str!r}") |
| 1985 | + raise ValueError(f"Invalid signing mode: {request.signing_mode!r}") |
1985 | 1986 |
|
1986 | 1987 | if signing_mode in {SigningMode.CHIP_0002, SigningMode.CHIP_0002_P2_DELEGATED_CONDITIONS}:
|
1987 | 1988 | # CHIP-0002 message signatures are made over the tree hash of:
|
1988 | 1989 | # ("Chia Signed Message", message)
|
1989 |
| - message_to_verify: bytes = Program.to((CHIP_0002_SIGN_MESSAGE_PREFIX, input_message)).get_tree_hash() |
| 1990 | + message_to_verify: bytes = Program.to((CHIP_0002_SIGN_MESSAGE_PREFIX, request.message)).get_tree_hash() |
1990 | 1991 | elif signing_mode == SigningMode.BLS_MESSAGE_AUGMENTATION_HEX_INPUT:
|
1991 | 1992 | # Message is expected to be a hex string
|
1992 |
| - message_to_verify = hexstr_to_bytes(input_message) |
| 1993 | + message_to_verify = hexstr_to_bytes(request.message) |
1993 | 1994 | elif signing_mode == SigningMode.BLS_MESSAGE_AUGMENTATION_UTF8_INPUT:
|
1994 | 1995 | # Message is expected to be a UTF-8 string
|
1995 |
| - message_to_verify = bytes(input_message, "utf-8") |
| 1996 | + message_to_verify = bytes(request.message, "utf-8") |
1996 | 1997 | else:
|
1997 |
| - raise ValueError(f"Unsupported signing mode: {signing_mode_str!r}") |
| 1998 | + raise ValueError(f"Unsupported signing mode: {request.signing_mode!r}") |
1998 | 1999 |
|
1999 | 2000 | # Verify using the BLS message augmentation scheme
|
2000 | 2001 | is_valid = AugSchemeMPL.verify(
|
2001 |
| - G1Element.from_bytes(hexstr_to_bytes(request["pubkey"])), |
| 2002 | + request.pubkey, |
2002 | 2003 | message_to_verify,
|
2003 |
| - G2Element.from_bytes(hexstr_to_bytes(request["signature"])), |
| 2004 | + request.signature, |
2004 | 2005 | )
|
2005 |
| - address = request.get("address") |
2006 |
| - if address is not None: |
| 2006 | + if request.address is not None: |
2007 | 2007 | # For signatures made by the sign_message_by_address/sign_message_by_id
|
2008 | 2008 | # endpoints, the "address" field should contain the p2_address of the NFT/DID
|
2009 | 2009 | # that was used to sign the message.
|
2010 |
| - puzzle_hash: bytes32 = decode_puzzle_hash(address) |
| 2010 | + puzzle_hash: bytes32 = decode_puzzle_hash(request.address) |
2011 | 2011 | expected_puzzle_hash: Optional[bytes32] = None
|
2012 | 2012 | if signing_mode == SigningMode.CHIP_0002_P2_DELEGATED_CONDITIONS:
|
2013 |
| - puzzle = p2_delegated_conditions.puzzle_for_pk(Program.to(hexstr_to_bytes(request["pubkey"]))) |
| 2013 | + puzzle = p2_delegated_conditions.puzzle_for_pk(Program.to(request.pubkey)) |
2014 | 2014 | expected_puzzle_hash = bytes32(puzzle.get_tree_hash())
|
2015 | 2015 | else:
|
2016 |
| - expected_puzzle_hash = puzzle_hash_for_synthetic_public_key( |
2017 |
| - G1Element.from_bytes(hexstr_to_bytes(request["pubkey"])) |
2018 |
| - ) |
| 2016 | + expected_puzzle_hash = puzzle_hash_for_synthetic_public_key(request.pubkey) |
2019 | 2017 | if puzzle_hash != expected_puzzle_hash:
|
2020 |
| - return {"isValid": False, "error": "Public key doesn't match the address"} |
| 2018 | + return VerifySignatureResponse(isValid=False, error="Public key doesn't match the address") |
2021 | 2019 | if is_valid:
|
2022 |
| - return {"isValid": is_valid} |
| 2020 | + return VerifySignatureResponse(isValid=is_valid) |
2023 | 2021 | else:
|
2024 |
| - return {"isValid": False, "error": "Signature is invalid."} |
| 2022 | + return VerifySignatureResponse(isValid=False, error="Signature is invalid.") |
2025 | 2023 |
|
2026 | 2024 | async def sign_message_by_address(self, request: dict[str, Any]) -> EndpointResult:
|
2027 | 2025 | """
|
|
0 commit comments