Частный рынок: Доверительные транзакции для произвольных вычислений, реализованные с помощью ZK

1. Введение

Частный рынок, конфиденциальность и надежная продажа с помощью zk-SNARK и Ethereum:

  • 1) Закрытый ключ адреса Ethereum (пара ключей ECDSA).
  • 2) Подпись EdDSA
  • 3) Доказательство Groth16: используйте рекурсию для анонимной торговли доказательствами Groth16.

См. реализацию открытого исходного кода:

Частный рынок позиционируется как не требующий разрешения P2P-период, поддерживающий закрытый ключ спроса/предложения любого пользователя, подпись и доказательство Groth16.

Транзакции данных должны решать две основные проблемы одновременно:

  • Данные доступны только покупателю.
  • Данные имеют проверяемые свойства.

вставьте сюда описание изображения
вставьте сюда описание изображения
вставьте сюда описание изображения
вставьте сюда описание изображения
вставьте сюда описание изображения
вставьте сюда описание изображения
вставьте сюда описание изображения
вставьте сюда описание изображения
Соответствующие примеры:

  • 1) zkML: модели машинного обучения для торговли, основанные на проверенной точности.
  • 2) Протокол Yi: уменьшенные версии изображений для частной передачи NFT.
  • 3) Ночной рынок: торговый рынок Координаты Темного Леса.
  • 4) Размытие изображения:
    вставьте сюда описание изображения

2. Три краеугольных камня

Этот протокол построен на следующих трех краеугольных камнях:

  • 1) Доказательство утверждения: f (данные, свойство) = truef(данные, свойство) = trueж ( д а т а ,собственность ) _ _ _ _ _"="true , то есть доказательство утверждения используется для доказательства того , что сегмент проданных данных удовлетворяет определенному атрибуту .
    • Если вы знаете закрытый ключ, соответствующий конкретному адресу Ethereum: f ( secret Key ,address ) = truef(secretKey,address)=truef ( секретный ключ , _платье DD ) _"="true , чтобы убедить покупателя в том, что частная часть данных о партии действительно имеет какой-то атрибут, который его интересует .
  • 2) Доказательство шифрования: enc (данные, ключ) enc (данные, ключ)en c ( данные , _ _ _ _ключ ) _
    • Доказательство шифрования призвано убедить покупателя в том, что конфиденциальная часть данных зашифрована требуемым ключом. Ключ аналогичен общему значению ECDH покупателя-продавца.
  • 3) Подтверждение обязательств: h (данные) h(данные)ч ( д а т а ) . Доказательства обязательств могут выполнять разные роли, и существуют разные типы доказательств обязательств. Обычно подтверждение обязательств предназначено для доказательства того, что продается, и то, как это продается, подтверждает некоторую ранее подтвержденную стоимость. нравиться:
    • h (данные проданы) = = h (в списке данных) h(data_{продано})==h(data_{в списке})ч ( д а т атак что я буду)==ч ( д а т асписок _ _ _ _ _) , известны данные транзакции и данные, указанные при инициализации.
    • Заранее рассчитайте значение обязательства h (shared Key) h(sharedKey)h ( s ha red Key ) , при продаже убедитесь, что покупатель и продавец используют правильный ключ шифрования.

3. Случай 1: продать нечетное число

Предположим, Алиса продает Бобу нечетное число, основной процесс таков:

  • 1) Алиса знает секретное нечетное число и надеется продать 1 эфир:
    • Алиса фиксирует нечетное число и помещает соответствующий результат хеширования в контракт.
    • Алиса публикует свой открытый ключ, который каждый может использовать для вычисления общего секрета.
  • 2) Боб хочет узнать, какое нечетное число продала Алиса:
    • Боб вычисляет общий ключ обоих на основе открытого ключа, выданного Алисой.
    • Боб публикует свой открытый ключ при вычислении общего секрета.
    • Боб фиксирует свой закрытый ключ.
    • Боб является хостом 1Ether.
  • 3) Теперь Алиса может продать Бобу свое нечетное число. Алиса вычислит одно доказательство, содержащее следующую информацию:
    • Покажите, что его число не делится на 2 – доказательство утверждения.
    • Продемонстрируйте, что он правильно зашифровал нечетное число — доказательство шифрования. Зашифрованные данные будут отправлены в цепочку.
    • Это показывает, что он использует тот же общий ключ, что и Боб, и проданное нечетное число соответствует числу предыдущего коммита, то есть доказательству обязательства.

Как только контракт подтвердит, что доказательство Алисы прошло, 1Ether, размещенный Бобом, будет передан Алисе. На данный момент Алиса получила прибыль в размере 1ETH, а Боб может использовать общий ключ для расшифровки данных в цепочке и получения соответствующего нечетного числа.

4. Случай 2: продать закрытый ключ

Интересно, что существует план по созданию рынка вокруг одного из самых ликвидных активов Ethereum. Закрытый ключ используется для доступа к учетной записи и инициации транзакции. Мы можем задаться вопросом, на что способна такая настройка.
Во-первых, возможность без всякого доверия делать ставки или запрашивать приватные ключи может стать сдерживающим механизмом для передачи акций неизвестным лицам. Если ключ ускользнет от стейкера с делегированной суммой, любой, кто им владеет, может использовать эту настройку, чтобы продать его анонимно и без доверия. Следовательно, такая установка может сигнализировать об утечке частной и ценной информации.
Это также поднимает вопросы о протоколах управления и механизмах голосования. Следует ли учитывать голоса с адресов, где предлагаются или продаются закрытые ключи? Продажа приватных ключей на рынке, вероятно, не самый простой способ манипулировать голосами. Фактически, покупка закрытого ключа никоим образом не гарантирует, что адрес, на который делает ставка покупатель, будет голосовать определенным образом. Однако протокол управления может быть уязвим для злоумышленников, продающих или покупающих набор адресов за определенное количество ETH, что делает голосование по конкретному решению потенциально недействительным. Должны ли участвующие адреса по-прежнему иметь право голоса в управленческих решениях после того, как их закрытые ключи будут опубликованы на частном рынке?
Наконец, некоторые части настройки рынка закрытых ключей могут быть актуальными в контексте абстракции учетной записи. Кошельки могут использовать схему вращающейся пары ключей для подписи своих транзакций. Возможность продавать временный доступ к кошелькам с помощью этой настройки может быть особенно интересна для таких случаев, как кредитование счетов.
Наша конструкция никоим образом не является окончательной. Вместо этого он указывает в направлении, которое может сделать неликвидный актив кошелька Ethereum ликвидным.

Пара ключей secp256k1 является краеугольным камнем Ethereum и Bitcoin, и существует две ситуации для продажи закрытых ключей Ethereum:

  • 1) спросить
  • 2) ставка

4.1 Размещение запроса на адрес Ethereum

Процесс размещения запроса на адрес Ethereum:

  • 1) Продавец сообщает свой адрес, выражая готовность продать соответствующий закрытый ключ и указывая цену.
  • 2) Покупатель размещает в контракте соответствующую сумму ETH и отправляет свой открытый ключ. Покупатель рассчитает:
    • Используйте открытый ключ продавца для расчета значения ECDH общего ключа.
    • Передайте общий секрет.
  • 3) Для получения прибыли доказательство, представленное продавцом сети, должно соответствовать:
    • Корректность утверждения: то есть адрес получен из предоставленного закрытого ключа.
    • Корректность шифрования: Закрытый ключ был правильно зашифрован.
    • Корректность обязательств:即:
      • Ключ шифрования соответствует зафиксированному общему ключу, предоставленному Бобом.
      • Производный адрес соответствует адресу предыдущего коммита.

Поскольку зашифрованные данные включены в подтверждающие данные, покупатель теперь может получить доступ к зашифрованному закрытому ключу в цепочке.
вставьте сюда описание изображения
Соответствующая схема :

/*
     This circuit is used within the ask setup. It does not require to check
     the validity of an ECDH shared key, since it is not used. The shared key
     has been committed onchain, we make the hash of this shared key public 
     and check against this commmitment when posting the proof.
*/

template SellETHAddressNoECDH(n, k) {

     signal input sharedKey[2]; // private
     signal input sharedKeyHash; // public

     signal input poseidonNonce; // public
     signal input encryptedPrivECDSAKey[7]; // public
     
     signal input privECDSAKey[4]; // private

     signal output address;

     var i;

     /* 
          1. Hash the shared key 
          Ensure that it corresponds to the committed one. 
     */

     component poseidonSharedKey = Poseidon(2);
     poseidonSharedKey.inputs[0] <== sharedKey[0];
     poseidonSharedKey.inputs[1] <== sharedKey[1];

     poseidonSharedKey.out === sharedKeyHash;

     /*
          2. Check that the private key derives to the sold address and that its encryption is correct
     */
     component sellETHAddress = CheckAndEncryptETHAddress(n, k);

     sellETHAddress.sharedKey[0] <== sharedKey[0];
     sellETHAddress.sharedKey[1] <== sharedKey[1];
     sellETHAddress.poseidonNonce <== poseidonNonce;


     for (i = 0; i < 7; i++) {
          sellETHAddress.encryptedPrivECDSAKey[i] <== encryptedPrivECDSAKey[i];
     }

     for (i = 0; i < 4; i++) {
          sellETHAddress.privECDSAKey[i] <== privECDSAKey[i];
     }

     address <== sellETHAddress.address;
}

component main{ public [ sharedKeyHash, poseidonNonce, encryptedPrivECDSAKey ] } = SellETHAddressNoECDH(64, 4);

4.2 Размещение ставки на адрес Ethereum

Процесс предложения отличается от процесса запроса. Ставка является первым выражением покупателя намерения купить адрес, поэтому покупатель раскрывает свой открытый ключ раньше продавца. С точки зрения продавца, у него есть доказательство, отличное от процесса запроса.

Процесс размещения ставки на адрес Ethereum:

  • 1) Покупатель делает ставку на адрес Ethereum и размещает соответствующее количество ETH в рыночном контракте.
  • 2) Доказательства, представленные продавцом сети, должны включать:
    • Корректность утверждения: то есть адрес получен из предоставленного закрытого ключа.
    • Корректность шифрования: Закрытый ключ был правильно зашифрован.
    • Корректность обязательств:即:
      • Продавец использует подтвержденный открытый ключ покупателя.
      • Производный адрес соответствует текущему адресу заявки.
    • Корректность обмена ключами: сообщенный открытый ключ продавца соответствует открытому ключу, используемому для расчета общего ключа шифрования.

вставьте сюда описание изображения
Процесс торгов состоит из меньшего количества шагов. Но продавцу необходимо добавить подтверждение корректности обмена ключами. В противном случае продавец может сообщить открытый ключ, отличный от того, который он получил, используя закрытый ключ, используемый для вычисления общего ключа шифрования.

Соответствующая схема :

/*
     This circuit is used within the bid setup. We check here that 
     the ECDH value has been correctly computed. We make the public key of the seller
     public so that the buyer - bidder - can compute the shared key value after the
     sale has been made. 
*/

template SellETHAddressECDH(n, k) {
     
     signal input sellerPubJubJub[2]; // public
     signal input sellerPrivJubJub; // private

     signal input buyerPubJubJub[2]; // public

     signal input sharedKey[2]; // private

     signal input poseidonNonce; // public
     signal input encryptedPrivECDSAKey[7]; // public
     
     signal input privECDSAKey[4]; // private

     signal output address;

     /*
          1. Check that the shared key is correctly computed
     */
     component sharedKeyCheck = SharedJubJubKeyCheck();
     
     sharedKeyCheck.pubA[0] <== sellerPubJubJub[0];
     sharedKeyCheck.pubA[1] <== sellerPubJubJub[1];
     sharedKeyCheck.privA <== sellerPrivJubJub;
     
     sharedKeyCheck.pubB[0] <== buyerPubJubJub[0];
     sharedKeyCheck.pubB[1] <== buyerPubJubJub[1];
     
     sharedKeyCheck.sharedKey[0] <== sharedKey[0];
     sharedKeyCheck.sharedKey[1] <== sharedKey[1];

     /*
          2. Check the sold address is correct
     */
     component sellETHAddress = CheckAndEncryptETHAddress(n, k);

     sellETHAddress.sharedKey[0] <== sharedKey[0];
     sellETHAddress.sharedKey[1] <== sharedKey[1];
     sellETHAddress.poseidonNonce <== poseidonNonce;

     var i;

     for (i = 0; i < 7; i++) {
          sellETHAddress.encryptedPrivECDSAKey[i] <== encryptedPrivECDSAKey[i];
     }

     for (i = 0; i < 4; i++) {
          sellETHAddress.privECDSAKey[i] <== privECDSAKey[i];
     }

     address <== sellETHAddress.address;
}

component main{ public [ sellerPubJubJub, buyerPubJubJub, poseidonNonce, encryptedPrivECDSAKey ] } = SellETHAddressECDH(64, 4);

5. Случай 3: Продажа подписей EdDSA

В нашем приложении покупатель подписи должен подписать хеш своего открытого ключа. С некоторыми реестрами открытых ключей эта настройка может стать привлекательным способом создания собственной платформы подписки для Web3. Подпись, приобретенная на рынке, представляет собой PCD (Proof-Carrying Data) , что указывает на то, что покупатель знает «подпись, подписанную открытым ключом конкретной службы». Таким образом, подписанный покупатель может получить интересующую услугу без доверия.

Покупатели также могут собирать эти подписи в кошельке, выбирая, какие из них мы хотим полностью или частично раскрыть поставщику услуг. Например, был отправлен запрос на добавление jubjub -signature-pcd в репозиторий Zupass , позволяющий хранить такие подписи в паспортах Zuzalu.

Давайте посмотрим на конкретный пример. Журнал Bitcoin Magazine рекомендует эту настройку для подписки на его контент. Алиса платит 0,01 ETH за доступ к газете на год. Служба газет получает открытый ключ Алисы из контента, опубликованного в цепочке, хэширует его, подписывает и публикует зашифрованную подпись в цепочке. Алиса может расшифровать подпись, которую теперь можно добавить в кошелек PCD. После входа в систему Алисе будет предложено доказать:

  • (1) Она знает подпись, подписанную парой ключей газеты, сообщением которой является хэш ее открытого ключа,
  • (2) Она знает закрытый ключ этого открытого ключа. Открытый ключ останется скрытым, и Алисе нужно только предоставить доказательства. Поэтому она войдет в систему конфиденциально и без всякого доверия прочитает статью в журнале Bitcoin Magazine.

В нашей настройке мы просим покупателей публиковать хешированные предварительные изображения, которые продавцы должны подписать. Хотя при этом создаются дополнительные данные о вызове, продавец знает, какое сообщение нужно подписать.

Процесс запроса подписи EdDSA мало чем отличается от процесса запроса пары ключей ECDSA. Покупатель подписи может запросить открытый ключ, предоставленный продавцом, для подписи любого публичного сообщения. Конкретный процесс:

  • 1) Продавец фиксирует свою пару открытых ключей, утверждая, что, пока указана конкретная цена, сообщение можно подписать.
  • 2) Покупатель размещает соответствующую сумму ETH в рыночном контракте, отправляет свой открытый ключ и размещает заказ на запрос подписи. Покупатель будет рассчитан оффчейн:
    • Используйте открытый ключ продавца для расчета значения ECDH (т. е. «общий ключ»).
    • Зафиксируйте общий ключ
    • Подписываемое сообщение содержит хэш открытого ключа покупателя.
  • 3) Доказательства, представленные продавцом сети, должны включать:
    • Корректность утверждения: Подпись предназначена для подписания определенного хэша.
    • корректность шифрования: расшифровка подписи верна
    • Корректность обязательства:
      • Ключ шифрования соответствует зафиксированному общему ключу.
      • Подписанное сообщение соответствует зафиксированному хешу в цепочке покупателя.

В этом случае продавцам может быть неудобно подписывать произвольные данные. В качестве исправления покупатель также разместил предварительное изображение подписываемого хэша. Теперь продавец должен проверить, соответствует ли подписываемый хэш переданному прообразу, и принять соответствующее решение.

Соответствующую схему см.:

/*
     A seller has placed an ask order for a signature over a public message
     A buyer has escrowed some value for it, along with a public preimage
     The seller makes a proof that:
          1. The signature has been encrypted with the committed shared key
          2. The signature signs a hash whose preimage is the publicly committed one
          3. The signature is correct
          4. The encryption is correct
*/

template SellSigPublicMessageEdDSA() {

     signal input pubKeyJubJubSeller[2]; // public
     signal input messagePreImage[2]; // public

     signal input message; // public h( messagePreImage )

     signal input sharedKey[2]; // private
     signal input sharedKeyHash; // public
     signal input signaturePoseidonNonce; // public
     
     signal input eddsaSigR8[2]; // private
     signal input eddsaSigS; // private
     signal input poseidonEncryptedSig[4]; // public 

     var i;

     /* 
          1. Hash the shared key 
          Ensures that it corresponds to the committed one
     */

     component poseidonSharedKey = Poseidon(2);
     poseidonSharedKey.inputs[0] <== sharedKey[0];
     poseidonSharedKey.inputs[1] <== sharedKey[1];

     poseidonSharedKey.out === sharedKeyHash;

     /*
          2. Hash message preimage
          Check that h( messagePreImage ) === message
     */

     component poseidonPubJubJubBuyer = Poseidon(2);
     poseidonPubJubJubBuyer.inputs[0] <== messagePreImage[0];
     poseidonPubJubJubBuyer.inputs[1] <== messagePreImage[1];

     poseidonPubJubJubBuyer.out === message;

     /* 
          3. Check correctness of the signature
          Ensures that no other message than h( payload ) has been signed
     */

     component sigVerifier = EdDSAPoseidonVerifier_patched();
 
     sigVerifier.Ax <== pubKeyJubJubSeller[0];
     sigVerifier.Ay <== pubKeyJubJubSeller[1];
     sigVerifier.S <== eddsaSigS;
     sigVerifier.R8x <== eddsaSigR8[0];
     sigVerifier.R8y <== eddsaSigR8[1];
     sigVerifier.M <== message;
 
     sigVerifier.valid === 1;

     /*
          4. Check correctness of the encryption
          Ensures that encryption has been carried out with correct shared key
     */

     component pSig = PoseidonEncryptCheck(3);

     pSig.nonce <== signaturePoseidonNonce;
     for (i = 0; i < 4; i++) {
          pSig.ciphertext[i] <== poseidonEncryptedSig[i];
     }
     pSig.message[0] <== eddsaSigR8[0];
     pSig.message[1] <== eddsaSigR8[1];
     pSig.message[2] <== eddsaSigS;
     pSig.key[0] <== sharedKey[0];
     pSig.key[1] <== sharedKey[1];

     pSig.out === 1;

}

6. Случай 4: продать доказательство Groth16

Когда мы начали этот проект, мы сначала задавались вопросом, как предоставить пользователям проверенных сервисов полный доступ, который у них есть.

Недавно Personae Labs выпустила heyanoun — инструмент, разработанный специально для владельцев имен, позволяющих анонимно придумывать идеи и обсуждать реквизиты DAO в Интернете. Это весьма эффективно для групп существительных. Несмотря на то, что приложение является общедоступным, его проверяемый характер гарантирует, что в нем могут участвовать только носители существительных, тем самым действуя как механизм фильтрации и улучшая качество обсуждений.
Тем не менее, было бы не слишком надуманно предположить, что носители, не являющиеся существительными, также могут иметь интересные моменты. Что, если владелец, не являющийся существительным, захочет анонимно поддержать команду реквизита? Или, что, если у реквизита есть сломанный активатор, о котором могут сообщить только те, кто не является существительным (которые могут пожелать остаться анонимными)? А как насчет самих носителей существительных? Разве не интересно, что они используют свой доступ, чтобы позволить анонимным людям выражать свое мнение на их платформе? Это может повысить ценность NFT, которыми они владеют.
Вот что могут сделать доказательства роста продаж16. Например, недавно я нашел запрос на доступ к группе heyanon. Когда мой заказ был выполнен анонимным участником группы, я разместил сообщение в соответствующей группе heyanon, даже не указав свой адрес в группе! так круто. Адрес, на котором был оформлен мой заказ, счел мою информацию интересной и возможность что-то сделать с доступом, который он больше не использовал. Со своей стороны, мне выпала честь опубликовать дерзкое сообщение и внести свой вклад в группу, частью которой я всегда хотел быть.
Это очень интересное достижение. Мы считаем, что это может открыть еще одно пространство для разработки проверенных приложений.
Во-первых, поскольку рекурсия допускает выборочное раскрытие входных данных, производители децентрализованных приложений могут разрабатывать различные политики доступа в зависимости от раскрытия общедоступного сигнала. Это приведет к тому, что разные доказательства потенциально будут иметь разные значения в зависимости от типа доступа, который они предоставляют.
Например, на heyanoun покупатели доказательства «анонимного доступа» могут публиковать сообщения, используя общий «псевдоним». Но также можно приобрести чуть более дорогие «фейковые» доказательства, которые позволяют публиковать сообщения под «вымышленным именем», заработавшим со временем репутацию, имеющую большее влияние и влияние в сообществе.
Это также интересно для владельцев NFT, которые смогут получить доступ к таким приложениям. Теперь они могут без всякого доверия извлекать выгоду из своих NFT, в отличие от спекулятивной динамики, окружающей их активы. Рынок вокруг его полезности может сформировать динамичную экосистему внутри сообщества NFT. В сочетании с PCD Wallet можно представить совершенно новый набор приложений и пользовательский интерфейс.
В контексте сетевых игр продажу доказательств вместо их ввода можно рассматривать как способ разработки «чит-кодов». В темном лесу устроен ночной рынок для продажи координат планет. Но если доказательство будет продано, покупатель доказательства может убедить других игроков, что он исследует определенную область, распространяя вокруг ложную информацию. Он также может убедить других игроков или службы обмена nft, что он выиграл раунд или попал в топ-5 таблицы лидеров.
Мы хотели бы услышать ваши мысли о том, как использовать эту настройку. Один из способов добиться этого — разработать библиотеку рекурсивных схем, которая работает для каждого dapp, на который ссылались (или не ссылались) ранее.

Здесь мы подробно рассказываем, как надежно продать доказательство Groth16. Используя рекурсию, мы можем продавать доказательства роста16 в частном порядке, которые покупатели затем могут использовать для доступа к соответствующей службе подтверждения.

6.1 Размещение запроса на подтверждение роста16

В качестве примера возьмем то же доказательство роста16 в приложении heyanoun .

Чтобы получить доступ к этим услугам, пользователю необходимо предоставить доказательство того, что он знает действительную подпись ss .s над сообщениемммm , исходящий из открытого ключаpki pk_iпк _яхранится в дереве TTт с корнемrrr и оставляетpk 0 , ⋯ , pki , ⋯ , pkn pk_0,\cdots,pk_i,\cdots,pk_nпк _0,,пк _я,,пк _н

Сначала мы предполагали, что пользователи heyanon смогут напрямую продавать пути и подписи Меркла заинтересованным покупателям. Проблема в том, что это нарушит анонимность продавца. И путь Меркла, и подпись показывают покупателю, какой открытый ключ в дереве Меркла продал ему доступ.
Вместо этого мы воспользуемся рекурсией. Это позволяет нам добиться избирательной конфиденциальности, раскрывая только те входные данные, которые нам нужны — сообщения и корни групп. Продавец должен создать доказательство того, что он знает действительную подпись s (частное) в сообщении m (публичное) и доказательство пути Меркла p (частное), который разрешается в корень r (публичное).
Продажа доказательства сама по себе не нарушает анонимность продавца, но предоставляет такой же уровень доступа покупателю. Конкретный процесс:

  • 1) продавец в группу root rrr фиксирует, заявляя, что он может получить доступ к группе, и проверяет хеш ключаvvv — связан с ключом проверки в службе проверки подлинности.
  • 2) Вне блокчейна покупатель использует открытый ключ продавца для расчета общего ключа, затем размещает соответствующее количество ETH на рынке, отправляет открытый ключ и передает сообщение, которое он хочет отправить группе, для размещения заказа. доказательство. [Обратите внимание, что на этом этапе, если покупатель использует вычисленный общий ключ для сохранения конфиденциальности сообщения, и покупатель, и продавец получат анонимность для сообщения о транзакции.
  • 3) Доказательства, представленные продавцом сети, должны включать:
    • Корректность утверждения: проданное доказательство Groth16 правильное — это рекурсивная часть.
    • правильность шифрования: доказательство правильно зашифровано
    • Корректность обязательства:
      • Хэши ключа шифрования и ключа проверки верны.
      • Корень группы и хеш сообщения проданного доказательства соответствуют начальному зафиксированному значению.

вставьте сюда описание изображения
Соответствующую схему см.:

/*
     This circuit:
          1. verifies a proof
          2. encrypts the proof's content
          3. hashes the verification key
          4. hashes the shared key
*/

template verifyAndEncryptSigMerkleProof(publicInputCount, l, nPoseidonHash, nHashInputs) {
     /*
          In our setup, we werify a proof of a proof of:
               1. a valid signature over a message m 
               2. a merkle path resolving to root r
     */
     var k = 6;
     var m;
     var i;
     var j;
     var encryptedProofLength = l + 1;

     // verification key
     signal input negalfa1xbeta2[6][2][k]; // private
     signal input gamma2[2][2][k]; // private
     signal input delta2[2][2][k]; // private
     signal input IC[publicInputCount+1][2][k]; // private
     signal input vkHash; // public

     // proof
     signal input negpa[2][k]; // private
     signal input pb[2][2][k]; // private
     signal input pc[2][k]; // private
     signal input pubInput[publicInputCount]; // public

     // encryption
     signal input encryptedProof[encryptedProofLength]; // public
     signal input poseidonNonce; // public
     signal input sharedKey[2]; // private
     signal input sharedKeyHash; // public

     component verify = verifyProof(publicInputCount);
     component encrypt = EncryptGroth16Proof(l);
     component hash = HashGroth16Vkey(nPoseidonHash, nHashInputs);
     component poseidonSharedKey = Poseidon(2);

     var startIdxHashGamma2 = (k * 2 * k); // offset 
     var startIdxHashDelta2 = startIdxHashGamma2 + (k * 4);
     var startIdxHashIC = startIdxHashDelta2 + (k * 4);

     for (i = 0; i < 2; i ++) {
          for (j = 0; j < k; j++) {

               for (m = 0; m < k; m++) {
                    verify.negalfa1xbeta2[m][i][j] <== negalfa1xbeta2[m][i][j];

                    var idx = (m * k * 2) + (k * i) + (j);
                    hash.inputs[idx] <== negalfa1xbeta2[m][i][j];

               }

               verify.negpa[i][j] <== negpa[i][j];
               encrypt.negpa[i][j] <== negpa[i][j];

               verify.pc[i][j] <== pc[i][j];
               encrypt.pc[i][j] <== pc[i][j];

               for (m = 0; m < 2; m++) {

                    verify.gamma2[m][i][j] <== gamma2[m][i][j];

                    var idxGamma2 = startIdxHashGamma2 + (m * k * 2) + (k * i) + (j);
                    hash.inputs[idxGamma2] <== gamma2[m][i][j];

                    verify.delta2[m][i][j] <== delta2[m][i][j];

                    var idxDelta2 = startIdxHashDelta2 + (m * k * 2) + (k * i) + (j);
                    hash.inputs[idxDelta2] <== delta2[m][i][j];

                    verify.pb[m][i][j] <== pb[m][i][j];
                    encrypt.pb[m][i][j] <== pb[m][i][j];
               }

          }
     }

     for (i = 0; i < publicInputCount; i++) {
          verify.pubInput[i] <== pubInput[i];
          for (j = 0; j < k; j++) {
               for (m = 0; m < 2; m++) {
                    verify.IC[i][m][j] <== IC[i][m][j];

                    var idxIC = startIdxHashIC + (i * k * 2) + (k * m) + (j);
                    hash.inputs[idxIC] <== IC[i][m][j];
               }
          }
     }

     var lastStartHashIdx = startIdxHashIC + (publicInputCount * k * 2);
     for (j = 0; j < k; j++) {
          // last IC input
          for (m = 0; m < 2; m++) {
               verify.IC[publicInputCount][m][j] <== IC[publicInputCount][m][j];

               var lastIdxIC = lastStartHashIdx + (k * m) + (j);
               hash.inputs[lastIdxIC] <== IC[publicInputCount][m][j];

          }
     }

     for (i = 0; i < encryptedProofLength; i++) {
          encrypt.encryptedProof[i] <== encryptedProof[i];
     }

     encrypt.poseidonNonce <== poseidonNonce;
     encrypt.sharedKey[0] <== sharedKey[0];
     encrypt.sharedKey[1] <== sharedKey[1];

     poseidonSharedKey.inputs[0] <== sharedKey[0];
     poseidonSharedKey.inputs[1] <== sharedKey[1];
     
     poseidonSharedKey.out === sharedKeyHash; // check shared key commitment

     hash.out === vkHash; // check vkey commitment

     verify.out === 1; // check proof
}

component main { public [ vkHash, pubInput, encryptedProof, poseidonNonce, sharedKeyHash ] } = verifyAndEncryptSigMerkleProof(5, 48, 12, 16);

7. Случай 5: Транзакция продажи Ethereum

Также существует настройка, при которой продажа осуществляется на Ethereum. Это может сделать интересной скрытую торговлю. Конкретный процесс:

  • 1) Алиса выдает запрос, указывая на свое намерение выполнить транзакцию. Транзакция предоставит определенное количество ETH, размещенное на рынке.
  • 2) Боб хочет, чтобы Алиса отправила определенное количество ETH на адрес, где он хранит закрытый ключ. Боб размещает на рынке определенное количество ETH для Алисы. Боб рассчитает:
    • Вычислить общий ключ, используя открытый ключ Алисы.
    • Зафиксируйте общий ключ
    • Ему нужны зашифрованные данные транзакции, выполненные Алисой, включая адрес и сумму перевода.
    • Зафиксируйте данные транзакции, которые могут включать h (адрес, сумма) h(адрес, сумма)ч ( дресс , _ _я не ) _ _ _
  • 3) Алиса расшифровывает данные транзакции. Алиса отправляет соответствующую сумму на определенный адрес. Предоставив доказательство, содержащее следующую информацию, Алиса может получить соответствующий хостинг, предоставленный Бобом:
    • корректность утверждения: используя путь Меркла, соответствующий корню дерева транзакций, Алиса показывает квитанцию ​​транзакции, существующую в дереве квитанций транзакций, которая удовлетворяет параметрам транзакции, первоначально запрошенным Бобом.
    • корректность шифрования: Алиса использует общий ключ для шифрования квитанции о транзакции.
    • Корректность обязательства:
      • Хэш параметров выполненной транзакции равен значению обязательства, отправленному Бобом ранее.
      • Зашифрованные квитанции о транзакциях используют правильный общий ключ.

Обратите внимание, что Боб может депонировать другое количество ETH, чем он просил Алису. Если он депонирует больше ETH, он каким-то образом «даст чаевые» Алисе за выполненную транзакцию. Он также дополнительно отделит сумму, депонированную в смарт-контракте, от суммы, транзакционной Алисы.

Этой настройки можно достичь, сохраняя последовательные корни дерева квитанций транзакций в рыночном контракте.

Однако из-за временных и технических ограничений мы не приводим здесь реализацию. Помимо других трудностей, мы не смогли найти способ легко получить доказательства, содержащие путь Меркла квитанции транзакции, в дереве квитанций транзакций — используя API, такой как eth_getProof, на geth. Нам пришлось реализовать как этот API, так и эффективный способ генерации доказательств, содержащих квитанции о транзакциях — аналогично тому, что Axiom сделала с деревом состояний Ethereum.

Мы были удивлены тем, что в желтой книге Ethereum прямо упоминается, что может быть интересно генерировать доказательства с нулевым разглашением, связанные с квитанциями о транзакциях. Фактически, эту настройку можно легко обобщить, от доказательства выполнения простых транзакций до более сложных взаимодействий с контрактами, т. е. скрытых взаимодействий.

8. Улучшения

Наши сборки рискуют, что персонаж отправит на рынок запрос предложения, который, как он знает, он не сможет выполнить. Чтобы предотвратить это, можно использовать три механизма: инициирование запросов путем предоставления доказательств того, что покупатели знают данные для расчета за недвижимость, отмена правила, согласно которому запрашивающие могут отменить запросы только в том случае, если они предоставят доказательства, и, в конечном итоге, установление протокола репутации на рынке. .
Мы также подробно описываем последовательность покупатель-продавец, которая включает до трех отдельных этапов: запрос, заказ и заполнение. Однако не следует ограничиваться этим конкретным потоком. Можно добавить шаг, который позволит покупателям и продавцам общаться конфиденциально и/или обещать предоставить некоторые дополнительные данные.

Помимо этого, наша сегодняшняя установка предназначена только для депонирования эфира. Однако в качестве условного депонирования можно разрешить использовать различные активы, такие как NFT или ERC-20. Также может быть организовано групповое условное депонирование, при котором покупатели объединяют ETH вместе. Например, команда сетевых игровых DAO может объединить свои ETH для покупки дорогого чит-кода, тем самым получив несправедливое решающее стратегическое преимущество.
Мы также не обсуждали вопрос о признании недействительными. Однако приложениям с проверкой подлинности, которые позволяют использовать такие схемы, возможно, потребуется найти способы избежать «двойного использования» доказательств в их протоколах.

Технические моменты, требующие улучшения:
Продавцам, демонстрирующим рост16, придется нести значительные затраты, связанные с данными о вызовах. Мы не работаем над доказательствами сжатия, которые могли бы помочь нам снизить такие затраты. Это также указывает на то, что эта настройка, при которой зашифрованные данные публикуются в цепочке, потребует краткости, если ее примет средний повседневный пользователь Ethereum.

Нам нужны были мощные серверы для генерации zkeys и доказательств4. В общем, выполнение рекурсивных доказательств Groth16 на современных повседневных машинах непомерно дорого. Мы рады видеть, что команда работает над возможностью рекурсивного создания доказательств на мобильных устройствах с использованием схемы доказательств Nova.

Рекомендации

[1] Видео PSE, август 2023 г. Частные рынки на Ethereum — 0xPARC Pierre
[2] Частный рынок
[3] Июнь 2022 г. Прикладной ZK, видео Devconnect AMS'22 ZK Data Marketplace, Прикладной ZK — день 1

Guess you like

Origin blog.csdn.net/mutourend/article/details/132577718