Когда задача создаётся на Newton, перед тем как Gateway начнёт работу, должны дать согласие две стороны: пользователь и приложение, действующее от его имени. В документации это описывается как цепочка — подпись приложения, как предполагается, должна иметь определённый смысл: «мы увидели согласие пользователя, проверили его и только после этого добавили своё». Я хотел выяснить, обеспечивает ли реальная конструкция второй подписи соблюдение этого порядка, или же она просто утверждает, что он был соблюдён.
Вот что описано. Обе подписи проверяются по одному и тому же лежащему в основе сообщению — дайджесту, построенному из policy client и intent hash, при этом ссылки на данные включаются (складываются) внутрь. Пользователь подписывает его. Подписывает его и приложение. Gateway принимает задачу, как только обе подписи успешно проходят проверку по соответствующим открытым ключам. И заявленная цель подписи приложения — удостоверить, что оно получило и проверило согласие пользователя прежде, чем добавить своё собственное одобрение.

Это важное утверждение, если оно верно, потому что именно оно не позволяет злонамеренному или небрежному приложению санкционировать доступ к данным от имени пользователя, не получив при этом его реального согласия. Приложение говорит не просто «я одобряю этот intent». Оно говорит «я подтвердил, что реальный человек одобрил этот intent, и вот моя подпись как доказательство того, что я проверил».
Но посмотрите, что именно приложение на самом деле подписывает. Это тот же дайджест, который подписывает пользователь, — не дайджест, который включает подпись пользователя в качестве одного из входов. Если бы подписывающее сообщение приложения строилось путём хеширования реальных байт подписи пользователя, то получить корректную подпись приложения было бы криптографически невозможно без предварительного наличия реальной подписи пользователя — тогда подписи были бы связаны по построению, и утверждение «проверено до одобрения» обеспечивалось бы самой математикой, а не только тем, что оператор приложения ведёт себя честно. Но описано не это.
Приложение подписывает комбинацию intent и ссылки на данные напрямую, независимо от того, подписал ли пользователь или не подписал.
Это означает, насколько я могу судить по документации, что приложение может само вычислить тот же дайджест — оно уже знает policy-клиент, и именно оно в первую очередь конструирует intent и ссылки на данные — и произвести корректную со-подпись, даже не получив подпись пользователя. Проверка Gateway: «обе подписи независимо действительны для этого сообщения», а не «зависит ли подпись приложения от подписи пользователя». Два независимо сгенерированных одобрения одного и того же утверждения для верификатора выглядят идентично одному одобрению, которое было действительно обусловлено другим.

Я хочу быть осторожным в том, что это означает и чего не означает. Это не означает, что согласие пользователя может быть сфабриковано — собственная подпись пользователя всё равно должна существовать и самостоятельно подтверждаться, и ничто здесь не позволяет злоумышленнику подделать её. Смысл уже и конкретнее: гарантия упорядочивания — утверждение о том, что подпись приложения конкретно представляет собой «я сначала проверил подпись пользователя» — не выглядит чем-то, что криптография обязана обеспечивать. Это ближе к операционному ожиданию, предъявляемому к честному поведению приложения, а не к свойству, которое математически гарантирует схема двойной подписи.
Приложение, которое сначала подписало, или подписало, так и не получив подпись пользователя, и просто «повезло» тому, что пользователь отдельно подписал тот же дайджест через какой-то другой канал, сформирует задачу, которая on-chain выглядит идентично той, где последовательность действительно произошла так, как было задумано.
То, имеет ли значение эта разница, целиком зависит от того, что могло бы сделать с ней скомпрометированное или небрежное приложение. Если практическая модель риска такова, что «кто-то вообще может подделать задачу без реального согласия пользователя», то это не открывает ничего нового — обе реальные подписи всё равно должны существовать. Но если часть того, что эта схема призвана обнаружить, — это приложение, которое «резиновым штампом» подтверждает намерения, не проверяя, кто стоит за ними, — это реальный, отличный от откровенной подделки режим отказа — то конструкция дайджеста, как она описана, похоже, не закрывает эту дверь.

Итак, точный вопрос таков: существует ли что-то за пределами именно этого подписываемого сообщения — отдельный on-chain журнал событий, требование аудита вне сети, проверка упорядочивания на стороне Gateway в момент прихода каждой подписи — что действительно принуждает к последовательности «проверено до одобрения», которую описывает документация?
Или же это просто такая политика последовательности, которой доверенное приложение должно следовать, опираясь на криптографическую схему, которая сама по себе не может отличить приложение, которое проверило, от приложения, которое не проверило?
