Skip to content

RAM-LFE

RAM-LFE означает оценку лаконической функции машины случайного доступа. В Iroha это общий слой скрытой функции для программ, чья государственная политика находится в цепочке, но чья логика-оценщик, секретный или сырой вход не должен быть написан мировым государством. Он используется в потоках идентификаторов SORA Nexus, таких как личный телефон или поиск электронной почты, а также может быть выявлен в качестве помощника для выполнения программы Torii, когда профиль узла обеспечивает маршруты, направленные на приложение.

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

Наименование

Разделение названий имеет значение:

ТерминЗначение .
ram_lfeВнешняя абстракция скрытой функции: политика программы, обязательства, расписки выполнения и режим проверки расписки.
BFVСистема гомоморфного шифрования Brakerski/Fan-Vercauteren, используемая задним числом с зашифрованным входом RAM-LFE.
ram_fhe_profileBFV-специфические метаданные для запрограммированной машины исполнения шифрования. Это не второе название для RAM-LFE.

В модели данных RamLfeProgramPolicy и RamLfeExecutionReceipt представляют собой типы RAM-LFE. Параметры BFV, рамки шифрового текста и скрытый профиль программы RAM-FHE относятся к зашифрованному исполнению бэкэнда, используемому в политике.

Что в ней записано

Политика программы RAM-LFE зарегистрирована в глобальном масштабе program_id. Политика содержит:

  • аккаунт владельца, который может активировать, деактивировать или иным образом изменить политику.
  • обратный контент, рекламируемый клиентам
  • режим проверки получения, либо signed или proof
  • приверженность скрытым программам метаданные и секрет оценщика
  • общественный ключ решателя для подписанных квитанций
  • необязательные публичные метаданные зашифрованного ввода, такие как параметры BFV и ram_fhe_profile
  • флаг active, который контролирует, может ли полис выдавать новые квитанции;

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

Оригинальное название

Нынешняя поддержка RAM-LFE сосредоточена на трех идентификаторах обратного конца:

ВзаимодействиеИспользовать
hkdf-sha3-512-prf-v1Оценка с обязательством PRF.
bfv-affine-sha3-256-v1BFV поддерживается секретная аффина оценка зашифрованные идентификационные слоты.
bfv-programmed-sha3-256-v1BFV поддерживает программируемое выполнение через зашифрованные реестры и память.

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

Математика

В этом разделе описывается алгебра на уровне реализации, используемая текущим RAM-LFE кодом. Это не является доказательством безопасности; это детерминистический транскрипт и модель зашифрованной оценки, по которой политики, квитанции и клиенты должны согласиться.

Примечание

Пусть:

  • (H(m)) быть Iroha Hash::new(m): Blake2b-32 над m, с наименее значительным битом последнего байта вынуждены на 1.
  • (N(x)) быть каноническим кодированием Norito x.
  • (a \parallel b) средняя конкаценация байт-струн.
  • (\operatorname{le64}(i)) быть 8-байтной небольшой эндианской кодировкой неподписанного целого числа.
  • (s) быть решающим секретом, хранящимся за пределами мира государства.
  • (P) должны быть параметрами государственной политики.
  • (A) запросить связанные с ними данные.
  • (x) должны быть нормализованными байтами ввода или зашифрованным конвертом ввода, кодируемым Norito, в зависимости от бэкэнда.

RAM-LFE использует хэши, разделенные доменами. Ниже приведены формулы названия доменов по назначению; их текущие байтные строки:

Символ .Доменная строка
(D_{\mathrm{policy}})iroha.ram_lfe.policy.hkdf_sha3_512_prf.v1
(D_{\mathrm{secret}})iroha.ram_lfe.policy_secret.hkdf_sha3_512_prf.v1
(D_{\mathrm{salt}})iroha.ram_lfe.hkdf_salt.hkdf_sha3_512_prf.v1
(D_{\mathrm{hkdf_opaque}})iroha.ram_lfe.opaque_info.hkdf_sha3_512_prf.v1
(D_{\mathrm{hkdf_receipt}})iroha.ram_lfe.receipt_info.hkdf_sha3_512_prf.v1
(D_{\mathrm{opaque}})iroha.ram_lfe.opaque_hash.hkdf_sha3_512_prf.v1
(D_{\mathrm{receipt}})iroha.ram_lfe.receipt_hash.hkdf_sha3_512_prf.v1
(D_{\mathrm{affine_circuit}})iroha.ram_lfe.bfv_affine.circuit.v1
(D_{\mathrm{affine_opaque}})iroha.ram_lfe.bfv_affine.opaque_hash.v1
(D_{\mathrm{affine_receipt}})iroha.ram_lfe.bfv_affine.receipt_hash.v1
(D_{\mathrm{program_memory}})iroha.ram_lfe.bfv_program.memory.v1
(D_{\mathrm{program_opaque}})iroha.ram_lfe.bfv_program.opaque_hash.v1
(D_{\mathrm{program_receipt}})iroha.ram_lfe.bfv_program.receipt_hash.v1
(D_{\mathrm{program_digest}})iroha.ram_lfe.bfv_program.digest.v1
(D_{\mathrm{output}})iroha.ram_lfe.output_hash.v1
(D_{\mathrm{id_opaque}})iroha.ram_lfe.identifier.opaque_hash.v1
(D_{\mathrm{id_receipt}})iroha.ram_lfe.identifier.receipt_hash.v1
(D_{\mathrm{bfv_keygen}})iroha.crypto.fhe.bfv.keygen.v1
(D_{\mathrm{bfv_encrypt}})iroha.crypto.fhe.bfv.encrypt.v1
(D_{\mathrm{id_keygen}})iroha.crypto.fhe.bfv.identifier.keygen.v1
(D_{\mathrm{id_slot}})iroha.crypto.fhe.bfv.identifier.slot.v1

Политическая приверженность

Политическое обязательство связывает общественные параметры и скрытые секреты решений с бэк-эндами. Во-первых, секрет делается отдельно:

Cs=H(Dsecrets) C_s = H(D_{\mathrm{secret}} \parallel s)

Затем полная транскрипта политики кодируется:

Tpolicy=N(backend,P,Cs) T_{\mathrm{policy}} = N(\mathrm{backend}, P, C_s)

и опубликованный хэш-политический код:

policy_hash=H(DpolicyTpolicy) \mathrm{policy\_hash} = H(D_{\mathrm{policy}} \parallel T_{\mathrm{policy}})

В цепочке PolicyCommitment:

(backend,policy_hash,P) (\mathrm{backend}, \mathrm{policy\_hash}, P)

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

HKDF-SHA3-512 Взаимодействие

Для hkdf-sha3-512-prf-v1 выход является самой нормализованной входной системой, но непрозрачный идентификатор и хэш квитанции являются секретно связанными PRF выходами.

Перепись просьбы:

Treq=N(policy_hash,P,A,x) T_{\mathrm{req}} = N(\mathrm{policy\_hash}, P, A, x)

Соль HKDF и ключ псевдорандума:

salt=Dsaltpolicy_hash \mathrm{salt} = D_{\mathrm{salt}} \parallel \mathrm{policy\_hash}

PRK=HKDF-ExtractSHA3-512(salt,s) \mathrm{PRK} = \operatorname{HKDF\text{-}Extract}_{\mathrm{SHA3\text{-}512}} (\mathrm{salt}, s)

Непрозрачный материал расширяется и рассеивается:

mo=HKDF-ExpandSHA3-512(PRK,Dhkdf_opaqueTreq,32) m_o = \operatorname{HKDF\text{-}Expand}_{\mathrm{SHA3\text{-}512}} (\mathrm{PRK}, D_{\mathrm{hkdf\_opaque}} \parallel T_{\mathrm{req}}, 32)

opaque_id=H(Dopaquemo) \mathrm{opaque\_id} = H(D_{\mathrm{opaque}} \parallel m_o)

Материал получения дополнительно связывает непрозрачный идентификационный номер:

mr=HKDF-ExpandSHA3-512(PRK,Dhkdf_receiptTreqopaque_id,32) m_r = \operatorname{HKDF\text{-}Expand}_{\mathrm{SHA3\text{-}512}} (\mathrm{PRK}, D_{\mathrm{hkdf\_receipt}} \parallel T_{\mathrm{req}} \parallel \mathrm{opaque\_id}, 32)

receipt_hash=H(Dreceiptmropaque_id) \mathrm{receipt\_hash} = H(D_{\mathrm{receipt}} \parallel m_r \parallel \mathrm{opaque\_id})

В обратном конце возвращается:

(output,opaque_id,receipt_hash)=(x,opaque_id,receipt_hash) (\mathrm{output}, \mathrm{opaque\_id}, \mathrm{receipt\_hash}) = (x, \mathrm{opaque\_id}, \mathrm{receipt\_hash})

BFV Пример

BFV - это схема гомоморфного шифрования на основе решетки. "Гомоморфная" означает, что программа может добавлять и умножать зашифрованные значения и, после расшифровки, получать тот же результат, как если бы она выполняла добавления и умножения на чистых текстовых значениях.

Для RAM-LFE, BFV используется в качестве механизма шифрования ввода:

  1. Портфель нормализует частное значение, такое как номер телефона или адрес электронной почты.
  2. Кошелек превращает байты в небольшие целые слоты.
  3. Каждый слот зашифрован с помощью общественного ключа решителя BFV.
  4. Время запуска решителя оценивает скрытую программу с помощью этих шифровых текстов
  5. Время запуска расшифровывает только скрытый выход программы и подписывает или доказывает квитанцию.

BFV это точная цельная арифметика, а не приблизительная арифметика. Вот почему он лучше подходит для идентификаторов байтов и небольших модульных Вычисления, а не вывод модели плавающей точкой. Iroha В настоящее время BFV использование, каждый зашифрованный слот имеет один скалярный модуль значения (t), Обычно это байт или поле длины байта. (q). Разрыв между (q) и (t) дает место для расшифровки шума, вызываемого шифрованием и гомоморфическими операциями.

Шифровый текст BFV имеет два полиномиальных компонента:

c=(c0,c1) c=(c_0,c_1)

Секретный ключ - это еще один полиномиал (s_k).

v=c0+c1sk v = c_0 + c_1s_k

Если шифровая запись была сформирована правильно и шум все еще достаточно маленький, (v) находится близко к масштабированному простому тексту. Округление восстанавливает коэффициент простого текста modulo (t).

Простая работаОперация шифрования текста
(m+n)Добавьте компоненты шифрового текста.
(m+\alpha)Добавьте в (c_0) масштабированную постоянную простых текстов.
(\alpha m)Размеры обоих компонентов шифрового текста на (\alpha).
(mn)Умножьте шифротекстовые полиномы, перерасширьте, а затем релинействуйте.

Умножение - это дорогая операция. Продукт двух двухкомпонентных шифровых текстов естественным образом создает трехкомпонентный шифровый текст, который расшифровывается с помощью (1), (s_k) и (s_k^2). Relinearization использует опубликованный ключ оценки, чтобы перевернуть термин (s_k^2) обратно в нормальный двухкомпонентный шифровый текст.

BFV является также "уровневой": каждая зашифрованная операция потребляет определенный бюджет на шум. Эта реализация не запускает шифровые тексты для обновления этого бюджета. RAM-LFE публикует небольшой ram_fhe_profile и принимает только ограниченную скрытую форму программы. что поддерживает оценку в пределах поддерживаемой глубины набора параметров. Текущий запрограммированный профиль позволяет фиксировать количество реестров, фиксировать число путей памяти, и как минимум одно умножение шифротекста-шифротексту на программируемый шаг.

В этом RAM-LFE дизайне, BFV скрывает вход клиента от данных публичной книги и от наблюдателей, которые видят только полезную нагрузку транзакции или маршрута. Это не означает, что цепочка выполняет произвольные зашифрованные программы сама по себе. Регулятор Torii Runtime все еще владеет секретным материалом BFV, оценивает конфигурированную скрытую программу, расшифровывает разрешенный выход и удостоверяет результат.

В случае использования идентификатора выбирается простое представление целенаправленно.

text
[length, byte_0, byte_1, ..., byte_n, 0, 0, ...]

Каждый элемент шифруется как свой собственный BFV скалярный шифровый текст. Эта форма делает нормализацию и проверку конверта ясными, позволяет кошелькам создавать зашифрованные запросы из публичных параметров, а разрешает решителю канонизировать эквивалентные зашифренные входы в стабильную транскрипту квитанции.

Модель кольца BFV

В BFV задней части используется негациклический полиномиальный кольцо:

Rq=Zq[X]/(Xn+1) R_q = \mathbb{Z}_q[X] / (X^n + 1)

и простого текстового кольца:

Rt=Zt[X]/(Xn+1) R_t = \mathbb{Z}_t[X] / (X^n + 1)

где:

  • (n) - polynomial_degree, мощность двух
  • (q) - ciphertext_modulus
  • (t) - plaintext_modulus
  • (q > t) и (t \mid q)
  • (\Delta = q/t)
  • (B = 2^{\mathrm{decomposition_base_log}})

Векторы коэффициентов простых текстов кодируются путем масштабирования каждого коэффициента:

EncPlain(m)i=Δmimodq \operatorname{EncPlain}(m)_i = \Delta m_i \bmod q

Разшифровка централизует каждый коэффициент:

v=c0+c1skRq v = c_0 + c_1 s_k \in R_q

затем закручивает его обратно в (R_t):

Dec(c)i=tcenterq(vi)qmodt \operatorname{Dec}(c)_i = \left\lfloor \frac{t \cdot \operatorname{center}_q(v_i)}{q} \right\rceil \bmod t

Здесь (s_k) представляет собой полиномию тайного ключа BFV, а не внешний RAM-LFE секрет решающего решения (s).

Ключевое поколение BFV

Для ввода шифрованного идентификатора ключевой материал BFV является детерминируемым по секретным и связанным с ним данным для решений:

σid=H(Did_keygenAs) \sigma_{\mathrm{id}} = H(D_{\mathrm{id\_keygen}} \parallel A \parallel s)

BFV RNG сеется следующим образом:

ChaCha20Rng(H(Dbfv_keygenσid)) \operatorname{ChaCha20Rng}(H(D_{\mathrm{bfv\_keygen}} \parallel \sigma_{\mathrm{id}}))

Ключевые образцы генератора:

  • (s_k \in {-1,0,1}^n), представленный в модуле (q)
  • (a \leftarrow R_q) единообразно
  • (e \in {-1,0,1}^n)

Общественный ключ:

pk=(b,a),b=aske(modq) \mathrm{pk}=(b,a),\qquad b = -a s_k - e \pmod q

Для переопределения, пусть (s_k^2) быть продуктом кольца в (R_q). Для каждой базы...(B) цифры (j), образец (a_j) единообразно и (e_j) из небольшого распространения, а затем опубликовать:

rlkj=(bj,aj),bj=ajskej+Bjsk2(modq) \mathrm{rlk}_j=(b_j,a_j),\qquad b_j = -a_j s_k - e_j + B^j s_k^2 \pmod q

Публичные BFV метаданные политики содержат (((n,q,t,B)), публичный ключ и max_input_bytes. Секретный ключ BFV и ключ релинеаризации остаются в режиме выполнения решения.

BFV Шифрование и операции

Для шифрования простых текстовых полиномий (m) реализация производит семена другого ChaCha20 RNG из:

H(Dbfv_encryptseed) H(D_{\mathrm{bfv\_encrypt}} \parallel \mathrm{seed})

Он обрабатывает образцы (u,e_1,e_2 \in {-1,0,1}^n) и исчисляет:

c0=bu+e1+EncPlain(m)(modq) c_0 = b u + e_1 + \operatorname{EncPlain}(m) \pmod q

c1=au+e2(modq) c_1 = a u + e_2 \pmod q

Шифровый текст является (c=(c_0,c_1)).

Гомоморфное добавление имеет значение по компонентам:

c+d=(c0+d0, c1+d1)(modq) c+d=(c_0+d_0,\ c_1+d_1)\pmod q

Добавление простого текстового скалера (\alpha) к коэффициенту нулевых изменений только (c_0):

c+α=(c0+Δα, c1)(modq) c+\alpha = (c_0 + \Delta\alpha,\ c_1)\pmod q

Умножение простым текстовым шкалой (\alpha) измеряет оба компонента:

αc=(αc0, αc1)(modq) \alpha c = (\alpha c_0,\ \alpha c_1)\pmod q

Для двух шифротекстов (c=(c_0,c_1)) и (d=(d_0,d_1)), умножение шифрного текста сначала вычисляет шифрный текст размером в три размера и измеряет каждый коэффициент обратно на (t/q):

c~0=t(c0d0)qmodq \tilde c_0 = \left\lfloor \frac{t(c_0 d_0)}{q} \right\rceil \bmod q

c~1=t(c0d1+c1d0)qmodq \tilde c_1 = \left\lfloor \frac{t(c_0 d_1 + c_1 d_0)}{q} \right\rceil \bmod q

c~2=t(c1d1)qmodq \tilde c_2 = \left\lfloor \frac{t(c_1 d_1)}{q} \right\rceil \bmod q

Все вышеперечисленные продукты являются негациклическими кольцевыми продуктами в (R_q). Затем (\tilde c_2) разлагается на полиномы основной-(B):

c~2=jBjuj \tilde c_2 = \sum_j B^j u_j

и перелинейные:

c0=c~0+jujbj(modq) c'_0 = \tilde c_0 + \sum_j u_j b_j \pmod q

c1=c~1+jujaj(modq) c'_1 = \tilde c_1 + \sum_j u_j a_j \pmod q

Результат снова является двухкомпонентным BFV шифровым текстом.

Идентификатор Шифровая текстовая конверт

Идентификаторный вход байт-провода:

x=(x0,,x1) x=(x_0,\ldots,x_{\ell-1})

Кодируется в скалярные слоты:

m0= m_0 = \ell

mi+1=xi,0i< m_{i+1}=x_i,\qquad 0 \le i < \ell

и все оставшиеся слоты составляют нуль до max_input_bytes + 1. Каждый скалярный слот зашифрован как коэффициент-нулевый простотекстовый полиномий ([m_i]). Семя шифрования на слот:

σi=H(Did_slotseedle64(i)) \sigma_i = H(D_{\mathrm{id\_slot}} \parallel \mathrm{seed} \parallel \operatorname{le64}(i))

Зашифрованный идентификационный конверт:

(BFV.Encpk([m0];σ0),,BFV.Encpk([mM];σM)) (\operatorname{BFV.Enc}_{\mathrm{pk}}([m_0];\sigma_0),\ldots, \operatorname{BFV.Enc}_{\mathrm{pk}}([m_M];\sigma_M))

где (M=\mathrm{max_input_bytes}).

BFV Совершенный обратный конец

Для bfv-affine-sha3-256-v1 время выполнения сначала получает ключевой материал BFV из (s) и (A). Полученные общественные параметры должны точно соответствовать публичным параметрам, обязательным для цепочки.

Семена аффиновой схемы:

σaffine=H(Daffine_circuitspolicy_hashA) \sigma_{\mathrm{affine}} = H(D_{\mathrm{affine\_circuit}} \parallel s \parallel \mathrm{policy\_hash} \parallel A)

Из этого семена образцы времени выполнения, modulo (t), 32-рядовой аффиновый схема:

yj=bj+iwj,imi(modt),0j<32 y_j = b_j + \sum_i w_{j,i} m_i \pmod t, \qquad 0 \le j < 32

где (m_i) являются расшифрованными идентификационными слотами. Гомоморфически он рассчитывает одно и то же значение по шифровым текстам:

Cj=bj+iwj,iCi C_j = b_j + \sum_i w_{j,i} C_i

Регулятор расшифровывает каждый (C_j), требует, чтобы все последовательные коэффициенты простого текста были нулевыми, преобразует значения коэффициента-нулевых в байты и образует:

O=(y0,,y31) O=(y_0,\ldots,y_{31})

А потом:

opaque_id=H(Daffine_opaquepolicy_hashO) \mathrm{opaque\_id} = H(D_{\mathrm{affine\_opaque}} \parallel \mathrm{policy\_hash} \parallel O)

receipt_hash=H(Daffine_receiptpolicy_hashOopaque_id) \mathrm{receipt\_hash} = H(D_{\mathrm{affine\_receipt}} \parallel \mathrm{policy\_hash} \parallel O \parallel \mathrm{opaque\_id})

BFV Программированный обратный контент

Для bfv-programmed-sha3-256-v1 общедоступные параметры включают в себя параметры шифрования идентификатора BFV плюс дигес скрытой программы:

program_digest=H(Dprogram_digestN(program)) \mathrm{program\_digest} = H(D_{\mathrm{program\_digest}} \parallel N(\mathrm{program}))

Текущий профиль RAM-FHE составляет:

ПолеЗначение
profile_version1
register_count4
memory_lane_count32
ciphertext_mul_per_step1
encrypted_input_moderesolver_canonicalized_envelope_v1
min_ciphertext_modulus(2^{52})

Ввод простого текста, представленный в Torii, зашифрован в том же конверте BFV до исполнения . Детерминистическое семя для этого серверного шифрования:

H("iroha.ram_lfe.execute.plaintext_bfv.v1"N(program_id)x) H( \texttt{"iroha.ram\_lfe.execute.plaintext\_bfv.v1"} \parallel N(\mathrm{program\_id}) \parallel x )

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

Первоначальные зашифрованные полосы памяти получены из:

σmem=H(Dprogram_memoryspolicy_hashAle64(0)) \sigma_{\mathrm{mem}} = H(D_{\mathrm{program\_memory}} \parallel s \parallel \mathrm{policy\_hash} \parallel A \parallel \operatorname{le64}(0))

Для каждой из 32 полос образцы времени выполнения (r_j \in [0,t)) и хранит шифровый текст BFV, шифрующий (r_j). Затем скрытая программа выполняется по зашифрованным реестрам и зашифренной памяти:

ИнструкцияАлгебра
LoadInput(dst, i)(R_{\mathrm{dst}} \leftarrow C_i)
LoadState(dst, j)(R_{\mathrm{dst}} \leftarrow S_j)
StoreState(j, src)(S_j \leftarrow R_{\mathrm{src}})
LoadConst(dst, a)(R_{\mathrm{dst}} \leftrow \operatorname{Enc}(a))
Add(dst, a, b)(R_{\mathrm{dst}} \leftarrow R_a + R_b)
AddPlain(dst, src, a)(R_{\mathrm{dst}} \leftarrow R_{\mathrm{src}} + a)
SubPlain(dst, src, a)(R_{\mathrm{dst}} \leftarrow R_{\mathrm{src}} - a)
MulPlain(dst, src, a)(R_{\mathrm{dst}} \leftarrow aR_{\mathrm{src}})
Mul(dst, a, b)(R_{\mathrm{dst}} \leftarrow R_aR_b), затем перепространиться
SelectEqZero(dst, cond, z, nz)Дешифровывать (R_{\mathrm{cond}}); выбрать (R_z), когда он является нулевым, иначе (R_{nz}).
Output(src)Добавить (R_{\mathrm{src}}) к списку регистра выхода.

После того, как лента инструкций закончится, решитель расшифрует каждый регистратор выхода, преобразует коэффициент нуля в байт и конкацетирует эти байты:

O=bytes(Dec(Ro0)0,,Dec(Rok)0) O = \operatorname{bytes}(\operatorname{Dec}(R_{o_0})_0,\ldots, \operatorname{Dec}(R_{o_k})_0)

Общие программируемые хэши заднего конца:

opaque_hash=H(Dprogram_opaquepolicy_hashO) \mathrm{opaque\_hash} = H(D_{\mathrm{program\_opaque}} \parallel \mathrm{policy\_hash} \parallel O)

receipt_hashprogram=H(Dprogram_receiptpolicy_hashOopaque_hash) \mathrm{receipt\_hash}_{\mathrm{program}} = H(D_{\mathrm{program\_receipt}} \parallel \mathrm{policy\_hash} \parallel O \parallel \mathrm{opaque\_hash})

По умолчанию запрограммированная лента-идентификатор имеет 64 входные слоты. Для каждого слота (i) она загружает входный слот, загружая полосу памяти (i \bmod 32), добавляя их и давая результат:

R0Ci,R1Simod32,R2R0+R1,Output(R2) R_0 \leftarrow C_i,\qquad R_1 \leftarrow S_{i\bmod 32},\qquad R_2 \leftarrow R_0 + R_1,\qquad \operatorname{Output}(R_2)

Выходные хэши и квитанции

Общий квитанция исполнения RAM-LFE не подписывает сырьевой выход.

output_hash=H(DoutputO) \mathrm{output\_hash} = H(D_{\mathrm{output}} \parallel O)

Для квитанций исполнения Torii RAM-LFE, связанными данными являются байты идентификатора канонической программы:

A=N(program_id) A = N(\mathrm{program\_id})

associated_data_hash=H(A) \mathrm{associated\_data\_hash}=H(A)

Подписанная квитанция - это:

R=(program_id,program_digest,backend,verification_mode,output_hash,associated_data_hash,executed_at_ms,expires_at_ms) R = (\mathrm{program\_id}, \mathrm{program\_digest}, \mathrm{backend}, \mathrm{verification\_mode}, \mathrm{output\_hash}, \mathrm{associated\_data\_hash}, \mathrm{executed\_at\_ms}, \mathrm{expires\_at\_ms})

Для режима signed:

attestation=Signresolver(N(R)) \mathrm{attestation} = \operatorname{Sign}_{\mathrm{resolver}}(N(R))

Проверка проверяет подпись с помощью resolver_public_key и отклоняет получение, если только все эти равенства не содержат:

R.program_id=policy.program_id R.\mathrm{program\_id} = \mathrm{policy.program\_id}

R.backend=policy.backend R.\mathrm{backend} = \mathrm{policy.backend}

R.verification_mode=policy.verification_mode R.\mathrm{verification\_mode} = \mathrm{policy.verification\_mode}

R.program_digest=policy.public_parameters.hidden_program_digest R.\mathrm{program\_digest} = \mathrm{policy.public\_parameters.hidden\_program\_digest}

R.associated_data_hash=H(N(policy.program_id)) R.\mathrm{associated\_data\_hash} = H(N(\mathrm{policy.program\_id}))

В случае подачи заявителем output_hex, проверяющий орган также проверяет:

H(Doutputbytes(output_hex))=R.output_hash H(D_{\mathrm{output}} \parallel \operatorname{bytes}(\mathrm{output\_hex})) = R.\mathrm{output\_hash}

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

hR=H(N(R))=(h0,,h31) h_R = H(N(R)) = (h_0,\ldots,h_{31})

Ожидаемые публичные экземпляры являются четырьмя колоннами с одним элементом. Колонна (j) содержит байты (h_{8j}\ldots h_{8j+7}), за которыми следуют 24 нулевые байты:

instancej=h8jh8j+7024,0j<4 \mathrm{instance}_j = h_{8j}\parallel\cdots\parallel h_{8j+7}\parallel 0^{24}, \qquad 0 \le j < 4

Проекция идентификатора

Разрешение идентификатора не использует общий бэкэнд opaque_hash в качестве непрозрачного идентификатора учетной записи для пользователя. Он проецирует выходный хэш RAM-LFE через специальные домены идентификатора:

opaque_idid=H(Did_opaqueN(program_id)output_hash) \mathrm{opaque\_id}_{\mathrm{id}} = H(D_{\mathrm{id\_opaque}} \parallel N(\mathrm{program\_id}) \parallel \mathrm{output\_hash})

receipt_hashid=H(Did_receiptN(program_id)output_hashopaque_idid) \mathrm{receipt\_hash}_{\mathrm{id}} = H(D_{\mathrm{id\_receipt}} \parallel N(\mathrm{program\_id}) \parallel \mathrm{output\_hash} \parallel \mathrm{opaque\_id}_{\mathrm{id}})

IdentifierResolutionReceipt подписывает полезную нагрузку более высокого уровня:

I=(policy_id,R,opaque_idid,receipt_hashid,uaid,account_id) I = (\mathrm{policy\_id}, R, \mathrm{opaque\_id}_{\mathrm{id}}, \mathrm{receipt\_hash}_{\mathrm{id}}, \mathrm{uaid}, \mathrm{account\_id})

Для подписанных идентификационных квитанций:

attestation=Signresolver(N(I)) \mathrm{attestation} = \operatorname{Sign}_{\mathrm{resolver}}(N(I))

ClaimIdentifier принимает квитанцию только тогда, когда подпись или доказательство являются действительными, встроенная полезная нагрузка выполнения RAM-LFE соответствует указанной политике программы, а заявляемые обязательные документы - uaid и account_id.

Поток исполнения

Общее исполнение RAM-LFE выполняется следующей формой:

  1. Управление или регистрация оператора RamLfeProgramPolicy.
  2. Владелец активирует полис.
  3. Клиент читает метаданные о государственной политике от Torii.
  4. Клиент представляет решителю точно одну форму ввода: простый текст input_hex или зашифрованный вводный конверт BFV.
  5. Время запуска оценивает скрытую программу и возвращает output_hex, output_hash, opaque_hash, receipt_hash и RamLfeExecutionReceipt.
  6. Клиент или бэкэнд проверяют квитанцию в соответствии с опубликованной политикой, опционально проверяя, что возвращенный output_hex хэшируется с квитанцией output_hash.
  7. Инструкция более высокого уровня, такая как ClaimIdentifier, может встраивать заверенный квитанция вместо встраивания сырого входа.

Политика идентификации

Политика идентификатора - это конкретное использование RAM-LFE. Они добавляют бизнес-наименовое пространство и правило нормализации к общей программе политики:

text
RegisterRamLfeProgramPolicy(
  program_id = "phone_team",
  owner = "<POLICY_OWNER>",
  backend = "bfv-programmed-sha3-256-v1",
  verification_mode = "signed",
  commitment = "<HIDDEN_PROGRAM_POLICY_COMMITMENT>",
  resolver_public_key = "<RESOLVER_PUBLIC_KEY>"
)
ActivateRamLfeProgramPolicy(program_id = "phone_team")

RegisterIdentifierPolicy(
  id = "phone#team",
  owner = "<POLICY_OWNER>",
  normalization = "PhoneE164",
  program_id = "phone_team",
  note = "Private phone registration for team dataspace"
)
ActivateIdentifierPolicy(policy_id = "phone#team")

В идентификационном слое используется квитанция RAM-LFE, чтобы связать:

  • policy_id
  • непрозрачный идентификатор, полученный по скрытой функции
  • детерминированный receipt_hash
  • счета UAID
  • канонический account_id
  • общая эксплуатационная нагрузка RAM-LFE

Для набора пользователей, используйте псевдонимы аккаунтов отдельно от частных идентификаторов. Прозвища - это публичные имена; номера телефонов, адреса электронной почты и аналогичные значения должны проходить через идентификационные политики и квитанции.

Torii Маршруты

При включении семейства маршрутов, ориентированных на приложение, Torii раскрывает RAM-LFE и идентификационные помощники:

МаршрутЦель .
GET /v1/ram-lfe/program-policiesПеречислить активные и неактивные политики программы RAM-LFE и метаданные общественного исполнения.
POST /v1/ram-lfe/programs/{program_id}/executeВыполнить одну программу из input_hex или encrypted_input и вернуть выходные хэши плюс безгосударственный квитанция.
POST /v1/ram-lfe/receipts/verifyПроверьте RamLfeExecutionReceipt по сравнению с опубликованной политикой и, возможно, сравните output_hex с output_hash.
GET /v1/identifier-policiesПеречислить политики идентификатора, режимы нормализации, ключи решителя и метаданные зашифрованного ввода.
POST /v1/accounts/{account_id}/identifiers/claim-receiptВыпускать квитанцию, которую пользователь может вставить в ClaimIdentifier.
POST /v1/identifiers/resolveРешение нормализованного идентификационного ввода на связанный счет, когда существует активная претензия.
GET /v1/identifiers/receipts/{receipt_hash}Поищите постоянный идентификационный запрос с помощью хэша квитанции для инструментов аудита и поддержки.

Всегда проверяйте документ /openapi или /openapi.json целевого узла, прежде чем строить против этих маршрутов. Доступность зависит от создания узла и профиля сети.

Время запуска узлов

Время выполнения Torii в процессе RAM-LFE настроено под torii.ram_lfe.programs[*], на клавиатуре program_id. Каждая конфигурированная программа должна соответствовать обязательствам по политике в цепочке и должна предоставлять материалы о времени выполнения, необходимые для оценки и подтверждения полученных документов. Identifier routes reuse this same runtime; they do not require a separate identifier-resolver configuration surface.

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

Операционные рельсы

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