[:html
 [:head
  [:title "decrypt-zcash - Matthew Fors"]
  [:link
   {:rel "shortcut icon",
    :type "image/x-icon",
    :href "photos/favicon.ico"}]
  [:link {:rel "stylesheet", :href "styles/normalize.css"}]
  [:link {:rel "stylesheet", :href "styles/skeleton.css"}]
  [:link {:rel "stylesheet", :href "styles/style.css"}]]
 [:body
  [:div
   {:class "container"}
   [:div
    {:class "row nav", :style "padding: 20px 0 30px 0"}
    [:h5
     {:class "two columns nav-item",
      :style "width: 100/12%;",
      :onClick "location.href='about.html'"}
     "About"]
    [:h5
     {:class "two columns nav-item",
      :style "width: 100/12%;",
      :onClick "location.href='blog.html'"}
     "Blog"]
    [:h5
     {:class "two columns nav-item",
      :style "width: 100/12%;",
      :onClick "location.href='contact.html'"}
     "Contact"]
    [:h5
     {:class "six columns right-text bold nav-item",
      :onClick "location.href='index.html'"}
     "(enforser)"]]]
  (([:div
     {:class "container"}
     [:div {:class "row"} [:h3 "Zcash: Decrypt Sapling Outputs"]]
     [:div
      {:class "row"}
      [:p
       "A Zcash transaction may consist of both transparent and shielded outputs. Shielded outputs describe funds which are moving to a private z-address. If you are using a wallet which manages your z-address for you, it likely handles your addresses \"Incoming Viewing Key\" to decrypt the shielded output which defines the payment being made. This key can be used to decrypt any payment made to that z-address, so it is likely not something which is recommended to be disclosed - as that would reveal all past and future payments to the address."]
      [:p
       "There are other viewing keys in Zcash which are more restrictive in terms of what information they disclose. This post is concerned with the \"Outgoing Cipher Key\" (OCK). The OCK is a 32-byte key which has the ability to decrypt a single output of a transaction. This is valuable because it allows specific payments to be disclosed to third parties, without revealing any information outside of the single output."]
      [:p
       "The following form accepts a raw transaction and an OCK. To decrypt, each shielded output of the transaction is applied against the given OCK until one is successfully decrypted."]
      [:p
       "To protect your privacy all decryption processing on this page is done entirely in your browser. This avoids your OCK from needing to be shared over the web, to be decrypted on some unknown server. This is done by using WebAssembly to take advantage of the Outgoing Cipher Key decryption already defined in the "
       [:a
        {:href
         "https://github.com/zcash/librustzcash/tree/master/zcash_primitives"}
        "zcash_primitives"]
       " rust crate. The WebAssembly/Rust interop can be found "
       [:a
        {:href
         "https://github.com/enforser/enforser/tree/master/decrypt-zcash"}
        "here"]
       "."]]
     [:div
      {:class "row"}
      [:p "Raw Transaction"]
      [:textarea {:id "rawTx", :cols "60"}]
      [:p "Outgoing Cipher Key (Remove '0x' prefix)"]
      [:textarea {:id "ock", :cols "40"}]
      [:br]
      [:input {:id "decryptForm", :type "submit", :value "Decrypt!"}]]
     [:br]
     [:p {:hidden true, :id "message"}]
     [:table
      {:id "results", :hidden true}
      [:tr [:td "Value"] [:td {:id "zec"}]]
      [:tr [:td "Address"] [:td {:id "address"}]]
      [:tr [:td "Memo"] [:td {:id "memo"}]]]
     [:script
      {:type "module"}
      "\n      import init, { parseock } from './decrypt-zcash-assets/decrypt_zcash.js';\n      async function decryptOutput() {\n        await init();\n        document.getElementById('results').hidden = true;\n        document.getElementById('message').innerHTML = 'Decrypting! Hold tight.';\n        document.getElementById('message').hidden = false;\n        try {\n            console.log(document.getElementById('rawTx').value)\n            console.log(document.getElementById('ock').value)\n            const parsed = parseock(\n              document.getElementById('rawTx').value,\n              document.getElementById('ock').value\n            );\n            const [zatoshis, address, memo] = parsed.split('|', 3);\n            const zec = parseInt(zatoshis, 10) / 100000000 + ' ZEC';\n            const decrypted = {\n              zatoshis,\n              zec,\n              address,\n              memo: memo || ''\n            };\n            console.log(decrypted.memo);\n            document.getElementById('memo').innerHTML = decrypted.memo.length < 1 ? 'no memo provided' : decrypted.memo;\n            document.getElementById('zec').innerHTML = decrypted.zec;\n            document.getElementById('address').innerHTML = decrypted.address;\n            document.getElementById('message').hidden = true;\n            document.getElementById('results').hidden = false;\n        } catch (error) {\n          console.error(error);\n          document.getElementById('message').innerHTML = 'Failed to parse transaction';\n          document.getElementById('message').hidden = false;\n        }\n        return false;\n      }\n\n      document.getElementById('decryptForm').addEventListener('click', decryptOutput);\n    "]]))
  [:div
   {:class "container"}
   [:a
    {:class "twelve columns",
     :style "text-align: right",
     :href "/decrypt-zcash-as-code.html"}
    "Hiccup"]]]]
Back