Как работают кроссчейн мосты | 2
Сегодня мы продолжим разбираться с работой кроссчейн мостов, а поможет нам в этом данная статья ТЫК
Начнем!
В продолжение первой части, в этой статье мы сосредоточимся на проверке подписей опекунов в Wormhole как на Solana, так и на Ethereum
Как проверяются подписи опекунов (для предотвращения поддельных VAA)?
На Solana, Wormhole использует функцию verify_signatures для проверки всех подписей в VAA. Каждый VAA может содержать несколько подписей (не менее 2/3 из 19 проверенных подписей для достижения кворума). Из-за ограничения вычислений он разбивает проверку подписей на несколько этапов (т.е. вызывает verify_signatures несколько раз), при этом каждый вызов проверяет подмножество (например, шесть или семь) подписей опекунов
Входные данные в VerifySignatures определены ниже:
Важны два аккаунта PDA: guardian_set и signature_set. Аккаунт guardian_set должен быть инициализирован (AccountState::Initialized), и в нём хранится набор проверенных опекунов (включая их ключи (keys)):
В signature_set хранится проверенный статус (true или false) каждой подписи опекуна (signatures: Vec<bool>), хэш сообщения и guardian_set_index:
Аккаунт signature_set создается и инициализируется при первом вызове verify_signatures:
В последующих вызовах тот же signature_set проверяется с помощью соответствующего хэша сообщения и guardian_set_index, чтобы убедиться, что его нельзя подделать (строки 188 и 192 выше)
После проверки подписи соответствующий индекс signer_index в signature_set.signatures будет установлен true:
Как проверяется каждая подпись опекуна?
Wormhole (на Solana) использует предварительно компилированную программу Secp256k1 SigVerify, и каждый вызов verify_signatures дополняется инструкцией к программе SigVerify, которая проверяет входную последовательность подписей:
Wormhole использует sysvar_instructions для загрузки инструкции current_instruction, соответствующей verify_signatures, и проверяет, что его предыдущая инструкция должна быть инструкцией верификации secp (т.е. вызовом SigVerify):
Логи инструкций программы наглядно иллюстрируют поток:
Как подписи проверяются на Ethereum?
В отличие от Solana, Wormhole на Ethereum проверяет все подписи в одной транзакции, вызывая функцию verifyVM (vm - массив байтов VAA):
Она проверяет кворум, читая длину подписей:
Вызывает verifySignatures (аналогично Solana, принимая на вход hash сообщения и guardianSet):
VerifySignatures проверяет входные подписи по одной, используя ecrecover(строка 93):
API ecrecover(message, v, r, s) вычисляет ключ, который произвел подпись (v, r, s) на message. Проверка if проходит, если возвращаемый ключ совпадает с публичным ключом соответствующего опекуна (guardianSet.keys[sig.guardianIndex]).
Что если (злонамеренный) опекун подаст несколько повторяющихся подписей в VAA?
Wormhole предотвращает эту атаку, гарантируя, что индексы подписей в VAA должны быть возрастающими (на Ethereum):
На Solana Wormhole поддерживает пару (sig_index,signer_index) для каждой подписи и сопоставляет ключ проверенной подписи с соответствующим открытым ключом опекуна (строка 209):
Даже если злоумышленник сможет контролировать опекуна и поместить 19 повторяющихся подписей в VAA, только у одного опекуна signer_index будет true в signature_set.signature, поэтому атака будет неудачной
Wormhole также проверяет валидность guardian_set и целостность signature_set:
Проверка кворума выполняется в инструкции PostVAA:
В следующей статье мы продолжим обсуждение безопасности кроссчейн минта/сжигания токенов в Wormhole
Надеюсь статья была интересной и понятной!